スピログラフ(spirograph)、一般的に言えば内トロコイド(hypotrochoid)は、内サイクロイドをちょっと変えただけのものです。
ちなみに、spiro-は「らせん」とかの意味だそうです。
trochoidの語源に関しては、力学で出てくる「滑車」が「trochlea」で、その辺が関係しているようです。
1.1. 内トロコイドの式
図1のように、スピログラフは内サイクロイドとほとんど同じです。
r1、r2、θ、φは同じ。
ただ違うのは、点Pが動円の円周上ではなく、動円の中心Cからr3のところにあるということです。
つまり、第2回の式(12)のr2がr3に変わるだけです。
そうすると、第2回の式(10)は次のようになります。
と表せます。
第2回の式(11)との微妙な違いを見てください。
r3=r2にすれば、内サイクロイドになります。
1.2. スピログラフを描く
式(2)を元に、第2回のリスト7をベースにして、スピログラフを描きます。
! ! スピログラフを描く ! Copyright(c) カイン Cain 2006 ! DECLARE EXTERNAL PICTURE circle ! ! 定数設定 ! 半径 LET r1 = 7 ! 定円半径 LET r2 = 3 ! 動円半径 LET r3 = 2 ! 動円内描画点の半径 LET prompt$="半径r1,r2,r3を入力(デフォルト値 " & & & STR$(r1) & "," &STR$(r2) & "," & STR$(r3) & ")" WHEN EXCEPTION IN INPUT PROMPT prompt$ : r1,r2,r3 USE END WHEN LET ar1 = ABS( r1 ) LET ar2 = ABS( r2 ) LET ar3 = ABS( r3 ) ! 周回数 … LET rounds = ABS( rounds ) ! LET win_size = ar1 !定円 IF r1 * r2 < 0 THEN ! r1,r2のどちらか一方が負の場合は外トロコイド LET win_size = win_size + ar2 * 2 ELSEIF ar2 > ar1 THEN ! 内トロコイドだが、動円の方が大きい場合 LET win_size = win_size + ( ar2 - ar1 ) * 2 END IF IF ar3 > ar2 THEN ! 動円の外の軌跡を描く場合 LET win_size = win_size + ( ar3 - ar2 ) END IF SET WINDOW -(win_size+1), win_size+1, -(win_size+1), win_size+1 DRAW grid ! ! 定円描画 DRAW circle( 0, 0, r1 ) ! ! スピログラフ描画 ! 関数定義 DEF xp(t) = ( r1 - r2 ) * COS( t ) + r3 * COS( ( r1 - r2 ) / r2 * t ) DEF yp(t) = ( r1 - r2 ) * SIN( t ) - r3 * SIN( ( r1 - r2 ) / r2 * t ) ! LET div = 100 ! 360°を分割する数 LET round_time = 1 ! t=0~2π を描くのにウェイトをかける秒数 …
リスト1では、主に第2回のリスト7からの変更箇所を示しています。
リスト1を実行すると、次のような図形が描けます。
IF
~ELSEIF
~ELSE
~END IF
文-
複数の条件で条件付けをする時は、
ELSEIF
を使います。IF 条件1 THEN 条件1が真の時に実行されるプログラム ELSEIF 条件2 THEN 条件1が偽で条件2が真の時に実行されるプログラム ELSE 条件1も条件2も偽の時に実行されるプログラム END IF
という形になります。
更にELSEIF
を連ねて条件を増やすこともできます。 - 絶対値
ar1
、ar2
、ar3
-
これまでは
r1
、r2
、r3
の絶対値をそのままr1
、r2
、r3
に取っていましたが、リスト1では、別の変数ar1
、ar2
、ar3
にとっています。
これは、r1
、r2
、r3
が負の値の場合でも、その値をそのまま使って図形を描くためです。
具体的な話は次項で書きます。 - ウィンドウサイズ
-
リスト1では、ウィンドウサイズを次のように計算しています。
LET win_size = ar1 !定円
まず、初めに定円の大きさを基準とします。IF r1 * r2 < 0 THEN ! r1,r2のどちらか一方が負の場合は外トロコイド LET win_size = win_size + ar2 * 2
この「負の場合」については、次項で。ELSEIF ar2 > ar1 THEN ! 内トロコイドだが、動円の方が大きい場合 LET win_size = win_size + ( ar2 - ar1 ) * 2 END IF
この「動円の方が大きい場合」は、前回の内サイクロイドでやりました。IF ar3 > ar2 THEN ! 動円の外の軌跡を描く場合 LET win_size = win_size + ( ar3 - ar2 ) END IF
|r3|>|r2|の場合は、点Pが動円をはみ出すので、その分を追加しています。
例えば、r1,r2,r3
を3,1,2
としてスピログラフを描くと、次のようになります。
やっとスピログラフを描くところまで辿り着きました。
1.3. 外トロコイドも描ける
リスト1で外トロコイド(epitrochoid)を描くこともできます。
1.3.1. 試しに描く
ここまでは、r1、r2が正の場合のみ考えてきました。
では、r1、r2の片方を負の値にしてみたら、どうなるでしょうか。
リスト1を、 r1,r2,r3
を 3,-1,1
と入力して実行してみましょう。
どこかで見た感じ。r1,r2
を 3,1
とした外サイクロイドと同じ形です。
このように、r1とr2の正負を異なるようにすると、外トロコイドが描けます。
一石二鳥、面白い性質ですね。
リスト1の
IF r1 * r2 < 0 THEN ! r1,r2のどちらか一方が負の場合は外トロコイド LET win_size = win_size + ar2 * 2
の部分は、この場合を考慮して、動円の直径を加えています。
条件の r1 * r2 < 0
は、掛け合わせて正になるか負になるかで、 r1
と r2
の符号が同じか異なるかを判定しています。
1.4. 経過を省略して描く
描かれた結果だけを素早く見ることができるように、描画経過のアニメーションを省いたプログラムも作っておきます。
… LET div = 100 ! 360°を分割する数 ! SET LINE COLOR 4 ! ! 描画 FOR t = 0 TO 2 * PI * rounds STEP 2 * PI / div PLOT LINES : xp(t), yp(t) ; NEXT t END …
これで例えば、 r1,r2,r3
を 31,16,11
、 rounds
を 16
と入力して実行すると、次のような図形が描かれます。
アニメーションしていたら時間のかかるこのようなスピログラフも、一瞬で描けます。