図形を描く数式の使い方

12月 4th, 2011

Processing Advent Calendar 2011 (4日目)

曲線の数式を使って図形を描いてみよう


Wikipediaには美しい曲線が数式とともに多数掲載されています。 このような数式をProcessingで使って、様々な図形を描いてみましょう。

数式のうち、xとyについての式が書かれている場合、多くはそれをそのままProcessingに移植することができます。
xとyについての式というのは、例えば、
 x = ○○
 y = ○○
のように書かれているものです。(媒介変数表示、などと言ったりします)

円の数式をProcessingで使ってみよう

このような数式の代表的なものとして、円の式が挙げられます。
円についてのxとyの数式はパラメトリック方程式(Wikipedia)の欄にありました。
これはやや自明な例だが、半径 a の円をパラメトリックに表すと次のようになる。
 x = a cos(t)
 y = a sin(t)
と書かれています。これをProcessingで使うことにします。

この数式をProcessingで使うためには、それぞれの文字がどういう意味なのかを調べます。
まず、「a」。これは文章中に「半径 a の円を」と書いてあるので、半径の長さを表していることが分かります。
次の「cos」や「sin」はそれぞれ三角関数のコサインとサインです。(今回は三角関数の意味は分からなくても大丈夫です。)
最後の「t」ですが、これはWikipediaでのさきほどの数式のちょっと上に
これを自由な媒介変数 t を使って次のようにも表せる。
と書いてあるので、媒介変数だということが分かります。何やら難しい単語に聞こえますが、とりあえず今回は、プログラム内で増加していく変数と考えておけばよいでしょう。
この媒介変数が変化していくことで、図形が生み出されることになります。

さて、これをProcessingのコードにします。
先ほどの数式に四則演算記号などを入れて、Processingで使える形にします。そして、計算したxとyの位置に円を描いていきます。媒介変数であるtを増やしていくことを忘れないようにしてください。

float t = 0; //  媒介変数
final float a = 80; //  円の半径
 
void setup(){
  size(200, 200);
  smooth();
  fill(0);
}
 
void draw(){
  //  xとyを計算すsる
  float x = a * cos(t);
  float y = a * sin(t);
 
  //  得られたxとyの位置に円を描く
  ellipse(x, y, 1, 1);
 
  //  媒介変数を増やす
  t += 0.01;
}

例えば、「a」を 80にして実行してみると、次のような結果が得られます。

Prodessingの原点は左上なので、左上に円が描かれてしまいました。
この円を画面の中央にずらすらため、xとyのそれぞれに、画面の幅の半分の値を足します。

float halfWidth;
float halfHeight;
float t = 0; //  媒介変数
final float a = 80; //  円の半径
 
void setup(){
  size(200, 200);
  halfWidth = width / 2;
  halfHeight = height / 2;
  smooth();
  fill(0);
}
 
void draw(){
  //  xとyを計算する
  float x = a * cos(t);
  float y = a * sin(t);
 
  //  図形を画面の中央に移動する
  x += halfWidth;
  y += halfHeight;
 
  //  得られたxとyの位置に円を描く
  ellipse(x, y, 1, 1);
 
  //  媒介変数を増やす
  t += 0.01;
}

これで、数式を使って無事に中央に円を書くことができました。

他の数式を使ってみよう

wikipediaの曲線の項目には多数の曲線とその数式が載っているので、使ってみることにします。
曲線カテゴリー(Wikipedia)

リサジュー曲線

リサジュー曲線は円の数式を少し変形したようなものになります。リサジュー図形(Wikipedia)

数式を見てみると

 x = A cos(at)
 y = B sin(bt + δ)
となっています。
A,B,a,b,δそれぞれに説明はありませんが、いろいろな値を入れて試してみると、AとBはそれぞれ横、縦の大きさ(倍率)、aとbそしてδでは入れる数値によっていろいろな図形のパターンが表れることが分かります。

float halfWidth;
float halfHeight;
float t = 0; //  媒介変数
final float A = 80; //  横の大きさ
final float B = 60; //  縦の大きさ
final float a = 1.5;  //  値によって図形が曲線が変化する
final float b = 2;  //  値によって図形が曲線が変化する
final float d = 0;  //  値によって図形が曲線が変化する
 
void setup(){
  size(200, 200);
  halfWidth = width / 2;
  halfHeight = height / 2;
  smooth();
  fill(0);
}
 
void draw(){
  //  xとyを計算する
  float x = A * cos(a * t);
  float y = B * sin(b * t + d);
 
  //  図形を画面の中央に移動する
  x += halfWidth;
  y += halfHeight;
 
  //  得られたxとyの位置に円を描く
  ellipse(x, y, 1, 1);
 
  //  媒介変数を増やす
  t += 0.01;
}


これは、A = 80, B = 60, a = 1.5, b = 2, δ = 0の場合です。


また、こちらは、A = 80, B = 80, a = 1.1, b = 1.2, δ = 0の場合です。

内サイクロイド

回転させた円を軌道に利用するサイクロイドの1つである内サイクロイド(Wikipedia)です。

数式は少し複雑に見えますが、決めなければいけないものはrcとrmの2種類のみです。

 x = (rc - rm)cosθ + rm cos((rc - rm) / rm θ)
 y = (rc - rm)sinθ - rm sin((rc - rm) / rm θ)
rcとrmの値によって図形のパターンに変化が現れます。

float halfWidth;
float halfHeight;
float t= 0;
float A = 80; //  横の大きさ
float B = 80; //  縦の大きさ
final float rc = 1; //  値を決める
final float rm = 0.3; //  値を決める
 
void setup(){
  size(200, 200);
  halfWidth = width / 2;
  halfHeight = height / 2;
  smooth();
  fill(0);
}
 
void draw(){
  float x = A * ((rc - rm) * cos(t) + rm * cos((rc - rm) / rm * t));
  float y = B * ((rc - rm) * sin(t) - rm * sin((rc - rm) / rm * t));
 
  //  図形を画面の中央に移動する
  x += halfWidth;
  y += halfHeight;
 
  //  得られたxとyの位置に円を描く
  ellipse(x, y, 1, 1);
 
  //  媒介変数を増やす
  t += 0.01;
}

AやBは図形の大きさです。Wikipediaの数式には書いてありませんが、ここで数字をかけておかないと、画面に小さく表示されてしまい、見えなくなってしまうので注意が必要です。


こちらは、A = 80, B = 80, rc = 1, rm = 0.3にした場合です。


また、こちらは、A = 60, B = 60, rc = 0.85, rm = 1.1にした場合です。

まとめ

今回は曲線の数式をProcessingで使う方法を紹介しました。
パラメータをいろいろいじってみたり、数式を拡張してみたりすると思いがけない図形が描かれることがあります。
是非、オリジナルの数式を使って素敵な図形を描いてみてください。
キャラクターやオブジェクトの移動、弾幕、模様作りなどに特に効果を発揮できると思います。

なお、今回はWikipediaの数式に極力従う変数・定数名をつけたため、名前に大文字・小文字が入り混じっております。定数名にはfinalをつけてあります。
本来は定数はすべて大文字が望ましいです。

Tags: ,
Posted in Processing Advent Calendar2011 | No Comments »

Comments

Leave a Reply

 Comment Form