昨日は、等分された円周上の点を、とにかく全部線で結ぶ関数を作成してみた。
infoment.hatenablog.com
今日から複数回に分けて、等間隔(素数)で点を結ぶ「糸かけ曼荼羅」を作成することに挑戦する。
線を引くためには、始点と終点の座標が必要だ。そこで、この座標を手っ取り早く取得するために、昨日作成した関数の一部でクラスモジュールを作成してみた。
なお数学で馴染みの表記となるよう、今回は座標をジャグ配列で持たせている。<<座標(i)=(x座標,y座標)>>
クラスモジュール(Mandara)
Enum 座標軸名 x座標 y座標 End Enum Public 分割数 As Long Public 旋回中心 As Variant Public 旋回半径 As Double Private Sub Class_Initialize() 分割数 = 30 旋回中心 = Array(500, 500) 旋回半径 = 200 End Sub Public Sub Reset() ' 元々書いてある線を削除。 On Error Resume Next ActiveSheet.Shapes.SelectAll Selection.Delete End Sub Public Property Get 各座標取得() As Variant Dim arr() As Variant ReDim arr(1 To 分割数 + 1) Dim x As Double Dim y As Double Dim i As Long Dim θ As Double θ = 2 * WorksheetFunction.Pi / 分割数 For i = 1 To 分割数 x = 旋回中心(x座標) + 旋回半径 * Sin(i * θ) y = 旋回中心(y座標) - 旋回半径 * (1 - Cos(i * θ)) arr(i) = Array(x, y) Next arr(分割数 + 1) = arr(1) 各座標取得 = arr End Property
続いて、等間隔ごとにポイントをスキップしながら線を引いてみよう。
簡単のため、5等分した点を3つずつ数えて線を引いた場合について考える。
始点が1点目の場合 ⇒ 終点は1+3=4点目
始点が4点目の場合 ⇒ 終点は4+3=1周+2点目
このことからn+1点目は、nを5で割った余りで求まりそうに思える。
しかし実際は、割り切れるとき余りが0になって上手く行かない。
こんな時は、nからまず1引いておき、余りに1を足すと良い。
これを踏まえて、先程のクラスモジュールに ↓ を追加した。
Sub PrimeMandara(prime_number As Long, _ Optional wait_flag As Boolean = False) Dim 始点 As Long: 始点 = 1 Dim 終点 As Long: 終点 = 1 Dim 各座標 As Variant 各座標 = 各座標取得 Do 始点 = 終点 終点 = ((始点 + prime_number - 1) Mod 分割数) + 1 ActiveSheet.Shapes.AddConnector msoConnectorStraight, _ 各座標(始点)(x座標), 各座標(始点)(y座標), _ 各座標(終点)(x座標), 各座標(終点)(y座標) If wait_flag Then Application.Wait [Now() + "00:00:00.1"] End If If 終点 = 1 Then Exit Do Loop End Sub
これで先程の5分割を3つずつ結ぶと、お星さまが出来上がった。
傾いている(或いは、ひっくり返っている?)のは、ご愛敬。
それでは早速、テストしてみよう。
Sub test() With New Mandara .Reset .分割数 = 64 .PrimeMandara 31 .PrimeMandara 29 .PrimeMandara 23 .PrimeMandara 19 .PrimeMandara 17 .PrimeMandara 13 .PrimeMandara 11 .PrimeMandara 7 .PrimeMandara 3 End With End Sub
結果は ↓ こちら。
一応、描画は上手く行ったようだ。
だが、課題がまだいくつもある(線の色をどうするか、など)。
ということで、次回に続きます。
参考まで。