コンテンツ・メディアコンテンツ メディアプログラミング実習Ⅰ
コンピュータグラフィックス編②ベジ 曲線とフラクタルベジェ曲線とフラクタル
橋本 直
1
今日大事なのは…今日大事なのは…難しい数式が出てきたら◦ 落ち着いて式のつくりを読み取ろう数式の意味を完全に理解 き なく も◦ 数式の意味を完全に理解できていなくても、プログラムで実装することはできる
難しいアルゴリズムが出てきたら難しいアルゴリズムが出てきたら◦ コンピュータになりきってどういう処理が⾏◦ コンピュータになりきってどういう処理が⾏われるか1⾏ずつ丁寧に考えよう
2
1 ベジェ曲線1. ベジェ曲線
3
滑らかな曲線を描くアルゴリズム滑らかな曲線を描くアルゴリズム
いろいろな曲線◦ ベジェ曲線◦ ベジェ曲線◦ ファーガソン曲線
Bスプライン曲線◦ Bスプライン曲線◦ 有理ベジェ曲線◦ NURBS曲線
CADソフトやドローソフトには大抵なんらかの曲線アルゴリズムが入っているの曲線アルゴリズムが入っている。◦ Illustrator, Photoshop, PowerPoint, ペイント, …
4
例: Inkscapeの曲線機能例: Inkscapeの曲線機能
IllustratorやInkscapeに搭載されている曲線機能を実際に使ってみよう実際に使ってみよう。
5
ベジェ曲線とはベジェ曲線とは
「制御点」と呼ばれる複数の点に基づいて定義される多項式曲線される多項式曲線。
ラン ⾃動⾞メ カフランスの⾃動⾞メーカー、ルノー社のエンジニアだったピエール・ベジェが考案。
(1962)(1962)
CADの開発を⾏っていた Pierre Bézier(1910-1999)
CADの開発を⾏っていた。
6Image from http://luc.devroye.org/fonts-36362.html
ベジェ曲線はこんな線ベジェ曲線はこんな線
P1 P2
P3P0
点 P P P P を制御点と呼ぶ点 P0, P1, P2, P3 を制御点と呼ぶ。n次のベジェ曲線には n+1 個の制御点がある。次 ジ 曲線には 個 制御点がある。◦ 3次のベジェ曲線 ⇒ 4個の制御点◦ 2次のベジェ曲線 ⇒ 3個の制御点
7
◦ 2次のベジェ曲線 ⇒ 3個の制御点
アニメーションで⾒るベジェ曲線アニメーションで⾒るベジェ曲線
2次ベジェ曲線 3次ベジェ曲線次 ジェ曲線 3次 ジェ曲線
8Image from http://en.wikipedia.org/wiki/B%C3%A9zier_curve
ベジェ曲線の形状ベジェ曲線の形状制御点の位置を変えることによ 曲げ方を制御点の位置を変えることによって曲げ方を変えることができる。
9
ベジェ曲線の性質① 端点一致性ベジェ曲線の性質① 端点一致性
P1 P2 P0 P2
P0 P3P P3P1 P3
曲線の両端は制御点P0、Pnに一致する。また P P と P P が曲線の接ベクトルとなるまた、P0 P1 と Pn-1 Pn が曲線の接ベクトルとなる。
10
ベジェ曲線の性質② 凸包性ベジェ曲線の性質② 凸包性PP1
P2
P P0
P2
PP30 P3
P0 P1
ベジェ曲線は制御点によって定義される凸包の中に完全に内包される中に完全に内包される。
凸包(とつほう)凸包(とつほう)◦ 与えられた点群を含む最小の凸形状のこと。◦ ピン群に輪ゴムをかけたときにできる図形。
11
ベジェ曲線の数式表現ベジェ曲線の数式表現制御点 があ き 次制御点 P0, P1, P2, P3 があるとき、3次のベジェ曲線は次式で表わされる。
10,)()()()()( 333
322
311
300 ≤≤+++= ttBPtBPtBPtBPtP
ここで は3次のバーンスタイン基底関数)(3 tB
,)()()()()( 33221100
ここで は3次のバ ンスタイン基底関数)(tBi
)(3B )(3B33 )1()( ttB の関数は 制御点の)(30 tB
)(3B )(3B
)(33 tB
231
0
)1(3)(
)1()(
tttB
ttB
−=
−= この関数は、制御点の位置情報をどのようにブレンドするかの配合
)(31 tB )(3
2 tB23
2
1
)1(3)(
)()(
tttB −=比を表わす。
12
333 )( ttB =
実装のために数式を読む①実装のために数式を読む①まずは式の形を把握する
)()()()()( 3333
どうや たらプ グ ムに落とし込めそうかよく考え
)()()()()( 333
322
311
300 tBPtBPtBPtBPtP +++=
◦ どうやったらプログラムに落とし込めそうかよく考える◦ 例えば微積分や総和、ノルム、最大値などの計算は入っている?
「t って何だ?」媒介変数表示(パラメ タ表示)◦ 媒介変数表示(パラメータ表示)◦ この式に t=0, t=0.1, t=0.2, … t=1.0 と代入し
ていくと 曲線を構成する点群になるていくと、曲線を構成する点群になる。◦ すなわち、for文で t=0〜1.0 の範囲で値を入れて
ば13
いけばよい!
実装のために数式を読む②実装のために数式を読む②デ変数の形(データ構造)を把握する
◦ スカラー? ベクトル? ⾏列?スカラ ? クトル? ⾏列?◦ プログラムで表現しやすい形に式を変形しよう。
)()()()()( 333
322
311
300 tBPtBPtBPtBPtP +++=
Pは2次元の点を示す座標値なので、変形)( とおいて変形
3333
),( yxP =
)()()()()( 333
322
311
300 tBxtBxtBxtBxtx +++=
)()()()()( 3333 tBytBytBytByty +++=14
)()()()()( 33221100 tBytBytBytByty +++=
実装をイメージしよう(1)実装をイメ ジしよう(1)
for (float t=0; t<1.0; t+=0.01) {33 )1()( ttB
231
330
)1(3)(
)1()(
tttB
ttB
−=
−= ① 媒介変数による式表現は、for文によって表現することができる。
232
1
)1(3)(
)1(3)(
tttB
tttB
−=33
3 )( ttB =
)()()()()( 3333 BPBPBPBPPpoint( );
)()()()()( 333
322
311
300 tBPtBPtBPtBPtP +++=)(tP
})(
15
実装をイメージしよう(2)実装をイメ ジしよう(2)
for (float t=0; t<1.0; t+=0.01) {33 )1()( ttB −=
231
0
)1(3)(
)1()(
tttB
ttB
−=
=
3
232 )1(3)( tttB −= ② P(t)はすべて2次元の座標値を示す
ベクトルなので、xとyを使って表現する
)()()()()( 3333 tBxtBxtBxtBxtx +++=
333 )( ttB = る。
)()()()()( 33221100 tBxtBxtBxtBxtx +++=)()()()()( 3
333
223
113
00 tBytBytBytByty +++=point( , );
}
)()()()()( 33221100 yyyyy)(tx )(ty
16
}
実装をイメージしよう(3)実装をイメ ジしよう(3)
for (float t=0; t<1.0; t+=0.01) {33 )1( tB −=
231
0
)1(3
)1(
ttB
tB
−=
=
③ よりプログラムに近い、平易な形で表
3
232 )1(3 ttB −=
現するとこうなる。これらの数式を代入によってさらにまとめてしまってもよい。
3333 BxBxBxBxx +++=
333 tB =
33221100 BxBxBxBxx +++=3
333
223
113
00 ByByByByy +++=point( , );
}
33221100 yyyyyx y
17
}
課題① bezierCurve1課題① bezierCurve1
前述の数式を用いて、3次ベジェ曲線を描くプログラムを作成せよプログラムを作成せよ。
制御点の例◦ P0 : (75, 260)◦ P1 : (170, 120)◦ P2 : (350 90)P2 : (350, 90)◦ P3 : (500, 200)
18
課題② bezierCurve2課題② bezierCurve2各制御点をマウスカ ソルでひ ぱ て移動で各制御点をマウスカーソルでひっぱって移動できるように改良し、制御点の配置とベジェ曲線の関係(前述の性質)について確認せよ。
点の近くでマウスボタンを押して、そのままドラッグすると点が移動。
19
点の近くで ウスボタンを押して、そのままドラッグすると点が移動。好きな場所でマウスボタンを離すと、そこで点が留まる。
ヒントヒント
点をマウスで移動させるには?「点の近くにカ ソルがあって マウスボタ◦ 「点の近くにカーソルがあって、マウスボタンが押されている」状態を判定しよう。
◦ その状態のときに、カーソルに点がついていくよ すれば良くようにすれば良い。
ウ ボタ 押 状態は と◦ マウスボタン押下状態は mousePressed という論理型変数(true/false)で判定できる。
20
2 フラクタル2. フラクタル
21
フラクタルとはフラクタルとはフラクタル(Fractal)
⾃己相似性を持つ図形のこと◦ ⾃己相似性を持つ図形のこと
自己相似性縮尺を変え も全体と部分の形状が相似◦ 縮尺を変えても全体と部分の形状が相似の関係にあること。◦ 「⾃分の中に⾃分がいて、さらにその中にも⾃分が…」という構造にも⾃分が 」という構造
22
有名なフラクタル図形有名なフラクタル図形
マンデルブロ集合 シェルピンスキー角形の三角形
コ ホ曲線コッホ曲線
23Image from http://ja.wikipedia.org/wiki/マンデルブロ集合
自然界に潜むフラクタル自然界に潜むフラクタル海岸線(リアス式海岸)海岸線(リアス式海岸)毛細血管毛細血管植物の葉や茎
ロマネスコシダ植物
24(カリフラワーの一種)
Image from http://ja.wikipedia.org/wiki/シダ植物, http://ja.wikipedia.org/wiki/ロマネスコ
フラクタルの応⽤例フラクタルの応⽤例F t l C dFractal Codes◦ ⾃己相似性を持つ2次元コード⾃己相似性を持 次元 ド◦ 近くから⾒ても遠くから⾒ても認識できる!◦ 一部分が⼿などで隠れていても認識できる!◦ 部分が⼿などで隠れていても認識できる!
25綾塚 祐二, “Fractal Codes: ⾃己相似的に配置される二次元コード”, WISS2006, pp.101-106
フラクタルを描くプログラムフラクタルを描くプログラムまずは以下のプログラムをよく読んで なぜそういうまずは以下のプログラムをよく読んで、なぜそういう結果になるか考えてみよう
void setup() {size(400, 400);
}}
void draw() {background(200);background(200);translate( width/2, height/2 );drawCircle(400);
}}
void drawCircle(float d) { if ( d < 10 ) {
return;}ellipse( 0, 0, d, d ); プログラムの中で不思議なことを
やっている箇所がないだろうか?
26
drawCircle(d/2);}
やっている箇所がないだろうか?
再帰的アルゴリズム再帰的アルゴリズム関数 中 ⾃分⾃身を呼び出す構造を関数の中で⾃分⾃身を呼び出す構造を持つアルゴリズム持つアルゴリズム
void drawCircle(…) {
…… drawCircle()の中で
drawCircle()が実行され、drawCircle(…);
}
drawCircle()が実行され、またその中でdrawCircle()が実行され…と延々繰り返される} される
27
再帰的アルゴリズムでの注意点再帰的アルゴリズムでの注意点プ再帰において重要なのはループの終了処理!
◦ 終了条件がととのったときに return で脱出させる。終了条件がととのったときに return で脱出させる。◦ これがきちんと仕掛けられてないと無限ループに陥
ってしまう。ってしまう。
void drawCircle(float d) {void drawCircle(float d) {
if ( d < 10 ) {これが再帰ループの終了処理。円の直径が10未満になったら、
return;}
円の直径が10未満になったら、そのタイミングでreturnで関数から脱出させている。
ellipse( 0, 0, d, d );drawCircle(d/2);
}
28
}
再帰的アルゴリズムでフラクタルを再帰的アルゴリズムでフラクタルを描くときのポイント描くときのポイント
①まずは繰り返しの基本要素を⾒つけて①まずは繰り返しの基本要素を⾒つけて、その基本要素だけを描く関数を作るそ 基本要素だけを描く関数を作る
②その関数に再帰構造を組み込む②その関数に再帰構造を組み込む
③終了条件を設定する③終了条件を設定する
29
例題:フラクタルな⽊例題:フラクタルな⽊下図の木を再帰的アルゴリズムで描いてみよう
30
1 基本要素を⾒つける1. 基本要素を⾒つけるまずは繰り返しになっている最小単位を⾒つけるつける
これが最小単位
31
2 基本要素を描く方法を考える2. 基本要素を描く方法を考えるスタート地点の座標値から各線の端点の座標値を計算する方法でも良いが、ここでは前回習ったtranslate()やrotate()を使って描画する方法で考えよう
①原点から上方向に⻑さLの線を描く
使って描画する方法で考えよう。
①原点から上方向に⻑さLの線を描く。
②原点から上方向にLだけ平⾏移動する
+40°-40°
②原点から上方向にLだけ平⾏移動する。
③その位置で +40度回転した後、③④
③その位置で +40度回転した後、そこを起点に⻑さL/2の線を描く。 ②
④その位置で -40度回転した後、そこを起点に⻑さL/2の線を描く ①
32
そこを起点に⻑さL/2の線を描く。 ①
3 基本要素だけを描く関数を作る3. 基本要素だけを描く関数を作るここでは再帰構造のことは意識せずに「基本要素だけを描く関数」ここでは再帰構造のことは意識せずに「基本要素だけを描く関数」を作る。要素の大きさを引数で指定できるようにするのが重要。
void drawTree(float length) {
line( 0 0 0 -length );line( 0, 0, 0, -length );translate(0, -length);
pushMatrix();pushMatrix();rotate(radians(40));line( 0, 0, 0, -length/2 );
popMatrix();popMatrix();
pushMatrix();rotate(radians(-40));( ( ));line( 0, 0, 0, -length/2 );
popMatrix(); }
33当然だが、この関数単体での動作を確認するためにsetup()とdraw()も書こう。
4 再帰構造にする4. 再帰構造にする先ほど作 た関数内で⾏われている描画処理のうち 再帰的先ほど作った関数内で⾏われている描画処理のうち、再帰的な分割処理が発⽣する部分を再帰呼び出しに置き換える。
void drawTree(float length) { void drawTree(float length) {
line( 0, 0, 0, -length );translate(0, -length);
line( 0, 0, 0, -length );translate(0, -length);
pushMatrix();rotate(radians(40));line( 0, 0, 0, -length/2 );
pushMatrix();rotate(radians(40));drawTree( length/2 );line( 0, 0, 0, length/2 );
popMatrix();
pushMatrix();
drawTree( length/2 );popMatrix();
pushMatrix();p ();rotate(radians(-40));line( 0, 0, 0, -length/2 );
popMatrix();
p ();rotate(radians(-40));drawTree( length/2 );
popMatrix();
34
} }
5 再帰の終了条件を設定する5. 再帰の終了条件を設定するこのままでは再帰処理が無限に⾏われてしまうので、それを防ぐために「要素の大きさ
void drawTree(float length) {
を防ぐために「要素の大きさが一定値以下になったら再帰を脱出する」という仕組みを
if ( length < 1 ) {return;
}を脱出する」という仕組みを加える。 line( 0, 0, 0, -length );
translate(0, -length);
ここでは「枝の⻑さが1未満になったら終了」としている。
pushMatrix();rotate(radians(40));d T ( l th/2 )drawTree( length/2 );
popMatrix();
pushMatrix();pushMatrix();rotate(radians(-40));drawTree( length/2 );
popMatrix();
35
popMatrix(); }
6 完成したプログラム6. 完成したプログラムvoid setup() {
size(400, 400);strokeWeight(2);
void drawTree(float length) {if ( length < 1 ) {
return;strokeWeight(2);}
void draw() {
return;}
line( 0 0 0 -length );void draw() {translate( width/2, height );drawTree(200);
}
line( 0, 0, 0, length );translate(0, -length);
pushMatrix();} pushMatrix();rotate(radians(40));drawTree( length/2 );
popMatrix();p p ();
pushMatrix();rotate(radians(-40));drawTree( length/2 );
popMatrix(); }
36
課題③ KochCurve課題③ KochCurveホ曲線を描くプ グ を作成 よコッホ曲線を描くプログラムを作成せよ。
37※こういうルールで描かれているが、アニメーションさせる必要はない。
ヒントヒント
④⑥⑤ ⑦
①
④⑩
⑦
①
② ③⑧
③
⑨L/3 ⑨
L38