turtleモジュール や matplotlibライブラリ を使用して、ハート型の図形を描きました。 使用したプログラミング言語はPythonです。
目次
直線と弧を組み合わせて描いたハート(turtleモジュール使用)
図形的特徴
曲線の部分は円です。ほかの線は直線です。 作図して、角度や長さを計算しました。 そして、作図したデータをもとに、turtleモジュールを使い、お絵かきしました。
最適な角度を調整した結果、「扇形の中心角θ」 は 210°、「直線と水平軸の角度α」 は 45°になりました。シンプルにθ=180°としても良かったかもしれません。
ハートを描くプログラム(turtleモジュール使用)のソースコード
これが ハート型の図形を描くプログラムのソースコード です。
# tutleモジュールをインポートします。タートルグラフィックスのことです。 import turtle # mathライブラリから、関数cos(),sin() と 円周率piをインポートします from math import cos,sin, pi # 円周率は定数なので、なんとなく大文字PIで表記しました。別に小文字のままpiで問題ないと思います PI=pi # ハートを描く関数です。 def draw_my_heart(ttl, x, y, radius, alpha=45, theta=210, degrees=0): ttl.setheading(degrees) # カーソルの向きを設定する。右0度,上90度,左180度,下270度。 ttl.penup() # ペンを上げる(ペンを上げると、移動中に線が引かれない) ttl.goto(x, y) # カーソルが(x,y) の座標に移動する ttl.pendown() # ペンを下ろす(ペンを下ろすと、移動中に線が引かれる) # 長ったらしい数式を書くので、変数を短めにしました r = radius # 扇形の半径 a = alpha # 水平方向と直線の角度 t = theta # 扇形の中心角 # 直線の長さです。作図して求めました straight = r*(-cos((a+90)*PI/180)-cos((t+a-90)*PI/180)) / cos(a*PI/180) ttl.left(a) # 左にa度カーソルの向きを変えます ttl.forward(straight) # カーソルが向いてる方向にstraightの長さ進みます。右の直線部分。 ttl.circle(r,t) # 半径rでt度の扇形を描きます。右側の扇形。 ttl.left(720-2*a-2*t) # 真ん中で左に(720-2*a-2*t)度カーソルの向きを変えます。作図して求めた角度。 ttl.circle(r,t) # 半径rでt度の扇形を描きます。左側の扇形。 ttl.forward(straight) #カーソルが向いてる方向にstraightの長さ進みます。左の直線部分。 width=700 # 画面の横幅 height=700 # 画面の高さ x = 0 # ハートの一番下の点のx座標 y = -150 # ハートの一番下の点のy座標 r = 100 # ハートの扇形の半径 scr = turtle.Screen() # 画面を作ります。Screenクラスのインスタンスを作っています。 scr.title('draw a heart') # 画面の上にこのタイトルが表示されます scr.setup (width, height, 0, 0) # 画面のサイズです ttl = turtle.Turtle() # Turtle オブジェクト(絵を描くカーソル)を作ります ttl.speed(3) # 絵を描くスピードを設定します ttl.shape('turtle') # カーソルは'turtle'(亀)にしました ttl.screen.screensize(width+100, height+100) # この範囲まで画面をスクロールできます。タートルが画面外に行った時、追いかけられるように大きめに設定 ttl.pencolor('red') # ペンの色を赤に設定 ttl.fillcolor('red') # 塗りつぶしに使う色を赤に設定 ttl.pensize(1) # ペンの太さを1に設定 ttl.begin_fill() # ここから塗りつぶし開始 draw_my_heart(ttl, x, y, r) # ハートを描く。デフォルト値を決めてる引数alpha=45, theta=210, degrees=0は省略されています、 ttl.end_fill() # ここまで塗りつぶす ttl.hideturtle() # カーソルを見えないようにする scr.exitonclick() # 画面をクリックしたら終了する
ハート曲線を利用して描いたハート
x,y座標をパラメータtで表す
ハート曲線(heart curve) と呼ばれる曲線はたくさん存在します。 今回、パラメータt (0~2π)によってx,y座標を表し、ハート曲線のグラフを描いてみました。
ちなみに上の図は 説明用に描いたハート曲線(turtleモジュールを使用)です。 ハートの中心より少し上からスタート(t=0)。 時計回りに一周して一番最初の場所に戻ってきます(t=2π) 。
ハート曲線を描くプログラム(matplotlib使用)のソースコード
まず、2つのライブラリmatplotlib, numpy をインストールしておく必要があります。 コマンドプロンプトを起動して下のコマンドを入力すれば、2つのライブラリはインストールされます。
pip install matplotlib numpy
これがmatplotlibとnumpyを使ってハート曲線を描くプログラムのソースコードです。 「図のインスタンスfig」 や 「座標軸のインスタンスax」 を作って、オブジェクト指向的にグラフを描きました。
# matplotlib.pyplotモジュール をインポートし、pltと略して使います。plt.show()のように使用できます import matplotlib.pyplot as plt # numpyライブラリ をインポートして、npと略して使います。np.arange()のように使用できます。 import numpy as np # グラフ上の点を作成します。それらの点が線でつながれると、ハート曲線のようなグラフができます # t: 0から2πまで0.01間隔で並んだ数字の配列(ndarray)。パラメータt。 # right_t: ハート曲線の右端の点に来る時のtの値=π/2 # right_y: ハート曲線の右端の点に来る時のy座標の値 # x: グラフ上の点のx座標の配列(ndarray) をパラメータtを用いて表します # y: グラフ上の点のy座標の配列(ndarray) をパラメータtを用いて表します。 t = np.arange(0, 2*np.pi, 0.01) # np.pi は円周率 right_t = np.pi/2 right_y = 13*np.cos(right_t)-5*np.cos(2*right_t)-2*np.cos(3*right_t)-np.cos(4*right_t) x = 16 * np.sin(t) ** 3 y = 13 * np.cos(t) - 5 * np.cos(2*t) - 2 * np.cos(3*t) - np.cos(4*t) # ここから図を作ります fig = plt.figure() # Figure(図)のインスタンスfig。何も描かれてない図。 ax = fig.add_subplot(1,1,1) # 座標軸(axes)のインスタンスax を作ります。グラフを描く前に座標軸を決めます。 ax.set_xlim(-17, 17) # x軸を表示する範囲を -17から17 とします ax.set_ylim(-20, 13) # y軸を表示する範囲を -20から13 とします ax.plot(x, y, color='pink') # 点(x,y)を順番にピンクの線でつなぎます ax.fill_between(x, y, y2=right_y, color='red') # 点(x,y) で囲まれた領域を赤く塗りつぶす ax.set_aspect(1) # x,yの目盛りの比を1にします # グラフを表示 plt.show()
matplotlib.pyplot を使用し、オブジェクト指向的にグラフを描きました
下の2つのモジュール(ライブラリ)を使ってハート曲線を描きました。
- matplotlib.pyplotモジュール(グラフを描くのに利用)
- numpyライブラリ(グラフの線を通す点の集まりを作るのに利用)
これがハート曲線(内部は赤く塗りつぶされている)を描いた手順です。
- グラフの線を通す点を作成する(np.arrange()を使用)
- 図のインスタンスfig を作成(fig = plt.figure())
- 座標軸(axes)クラスのインスタンスax を作成(ax = fig.add_subplot(1,1,1))
- グラフ上の点(x,y)を順につないでハート曲線を描く(ax.plot(x, y, color="pink") )
- ハート曲線の内部を赤く塗りつぶす(ax.fill_between(x, y, color="red"))
境界線と内部の色が同じでいいなら、赤く塗りつぶす作業だけすれば良いです。 点が多い方が綺麗に仕上がります。グラフの精度は点の多さに依存します。
縦横の目盛りの比が自動で調整されることがあるので、 ax.set_aspect(1) のようにして、縦:横 = 1:1 にしておいたほうがいいです。
set_aspect()は Axesクラス (座標軸のクラス)のインスタンスax が持っているメソッド(関数みたいな物) です。plot(), fill_between() もAxesクラスのメソッドです。 詳細は matplotlibのAxesクラスのドキュメントに記載されています。
最初、座標軸クラスのインスタンス が グラフを描けることに驚きましたが、 axes は axis(軸)の複数形 なので、 「ある平面の座標軸(x,y軸)」のクラスみたいな感じに思っておけば良いかもしれません。 1つ1つの軸ではなくて。
fill_between() のドキュメント によると、2番目の曲線y2 が デフォルトで y2=0 と設定されてるようです。 そのせいで、y=0 の線が塗りつぶされていました。
そこで、ハート曲線のx座標が最大となる時のy座標を求めて、それをy2としました。 すると、綺麗に赤い線が消えました。
ハートを100個描いてみました(matplotlib使用)
add_subplot() を利用して、図を10x10分割して、100個のハートを描いてみました。
ハートを100個描くプログラムのソースコード
100個のハートを描くプログラムのソースコードはこちらです。
# matplotlib.pyplotモジュール をインポートし、pltと略して使います。plt.show()のように使用できます import matplotlib.pyplot as plt # numpyライブラリ をインポートして、npと略して使います。np.arange()のように使用できます。 import numpy as np # グラフ上の点を作成します。それらの点が線でつながれると、ハート曲線のようなグラフができます # t: 0から2πまで0.01間隔で並んだ数字の配列(ndarray)。パラメータt。 # right_t: ハート曲線の右端の点に来る時のtの値=π/2 # right_y: ハート曲線の右端の点に来る時のy座標の値 # x: グラフ上の点のx座標の配列(ndarray) をパラメータtを用いて表します # y: グラフ上の点のy座標の配列(ndarray) をパラメータtを用いて表します。 t = np.arange(0, 2*np.pi, 0.01) # np.pi は円周率 right_t = np.pi/2 right_y = 13*np.cos(right_t)-5*np.cos(2*right_t)-2*np.cos(3*right_t)-np.cos(4*right_t) x = 16 * np.sin(t) ** 3 y = 13 * np.cos(t) - 5 * np.cos(2*t) - 2 * np.cos(3*t) - np.cos(4*t) # 図を10x10分割してハート曲線のグラフを100個描きます fig = plt.figure() # Figure(図)のインスタンスを作ります。今これは何も描かれていない図。 ax = [] # 座標軸のリスト。空のリストに初期化。 n=10 for i in range(n*n): # i=0,1,2...,n*n-1(=99)に対して以下の操作を繰り返す ax.append(fig.add_subplot(n, n,i+1)) # 図をnxnに分割して、左上から数えてi+1番目の座標軸をaxに追加 ax[i].set_xlim(-17, 17) # 表示するx軸の範囲を-17から17に設定 ax[i].set_ylim(-20, 13) # 表示するy軸の範囲を-23から10に設定 ax[i].set_aspect(1) # x軸とy軸の目盛りの比を1に設定 ax[i].set_axis_off() # 座標の軸、目盛り、枠などを表示しないようにする ax[i].fill_between(x, y, y2=right_y, color='red') # 点(x,y)で囲まれた領域を赤く塗りつぶします plt.show() # グラフを表示
回転させたハートを描く
turtleモジュールを使って、回転させたハートを描くとしたら、最初に向いてる角度を調整します。 下の絵はturtleモジュールによって描かれました。
matplotlib.pyplotモジュールを使って、回転させたハートを描くのに、 いわゆる回転行列(rotation matrix)を使いました。下の絵はmatplotlib.pyplotを使って描かれました。
下の絵は360°/5=72°ずつ回転させたハート曲線です。
真ん中ある五角形ぽい図形が思ったより綺麗でびっくりしました。
0 件のコメント:
コメントを投稿
投稿されたコメントは承認後に公開されます。