お世話になっております。前回の三次元タートルグラフィックスからの続きです。
HTML
+JavaScript
+Three.js
で臓器を描くのに挑戦しています。
レポジトリ:https://github.com/katahiromz/3D
Turtle3D.js ソース: https://github.com/katahiromz/3D/blob/master/Turtle3D.js
HTMLソース: https://github.com/katahiromz/3D/blob/master/7.html
この肺臓の黄色い気管支の外側に沿って血管を通したいと考えております。白い部分は肺胞です。動脈は赤色で、静脈は青色とします。最終的には3Dプリンタで利用したいと考えているので、血管は血液循環が可能なように、ちゃんと接続されていなければいけません。
よろしくお願い致します。
追記。三次元タートルグラフィックスの実装にTurtle3D.js
ファイルを使用しております。タートルグラフィックスというのは、位置と向きの情報を持ったカメ(turtle)を操作して描画するというものです。
まずは、https://github.com/katahiromz/3Dを丸ごとダウンロードして、Turtle3D.js
をご覧下さい。turtle.look_x
はX軸方向を向く関数です。turtle.look_y
はY軸方向を向く関数です。turtle.look_z
はZ軸方向を向く関数です。turtle.walk
関数で進行方向に長さdistanceだけ前進し、引数enable_pen
がtrue
なら進んだ分だけ線を描画します。turtle.turn
, turtle.spin
, turtle.pitch
はカメの向きを調整する関数です。
簡単な例を提示します。
js
1 function draw() { 2 turtle.reset(); 3 turtle.look_x(); 4 turtle.walk(20); 5 turtle.turn(30); 6 turtle.walk(20); 7 }
js
1 function draw() { 2 turtle.reset(); 3 turtle.look_y(); 4 turtle.walk(20); 5 turtle.turn(30); 6 turtle.walk(20); 7 }
次のように書くと:
js
1 // 二次元の木構造を描画する。 2 function tree(size, depth, angle) { 3 if (depth == 0) 4 return; 5 var pg = turtle.get_pg(); 6 turtle.walk(size); 7 turtle.turn(angle); 8 tree(size * 0.75, depth - 1, angle); 9 turtle.turn(-2.0 * angle); 10 tree(size * 0.75, depth - 1, angle); 11 turtle.set_pg(pg); 12 } 13 14 // 全体の描画処理。 15 function draw() { 16 turtle.reset(); 17 turtle.look_y(); 18 turtle.line_color = 0xFF0000; 19 tree(7, 8, 30); 20 }
このようにタートルグラフィックスと描画アルゴリズムを使用すれば、再帰的に複雑な図形が描画できます。線の太さturtle.line_width
を指定すれば
js
1 function draw() { 2 turtle.reset(); 3 turtle.look_y(); 4 turtle.line_width = 0.25; 5 turtle.line_color = 0xFF0000; 6 tree(7, 8, 30); 7 }
平面的ならば、血管を通すのは比較的簡単です。Zを少しずらして描けば実現できます:
js
1 // 二次元の木構造を描画する。 2 function tree(size, depth, angle) { 3 if (depth == 0) { 4 turtle.add_sphere(0.5, turtle.get_pos(), 0xFFFF00); 5 return; 6 } 7 var pg = turtle.get_pg(); 8 turtle.walk(size); 9 turtle.turn(angle); 10 tree(size * 0.75, depth - 1, angle); 11 turtle.turn(-2.0 * angle); 12 tree(size * 0.75, depth - 1, angle); 13 turtle.turn(angle); 14 turtle.walk(-size); 15 } 16 17 // 全体の描画処理。 18 function draw() { 19 turtle.reset(); 20 turtle.look_y(); 21 turtle.line_width = 0.4; 22 turtle.line_color = 0xFFFFFF; 23 tree(7, 8, 30); 24 turtle.look_y(); 25 turtle.line_width = 0.1; 26 turtle.line_color = 0xFF0000; 27 turtle.position.z += 0.3; 28 tree(7, 8, 30); 29 turtle.look_y(); 30 turtle.line_width = 0.1; 31 turtle.line_color = 0x0000FF; 32 turtle.position.z -= 0.3 * 2; 33 tree(7, 8, 30); 34 }
問題は、三次元であって、気管支が2方向に分かれたり、3方向に分かれたりして血管の位置を定めるのが難しいことです。三次元でどうやって血管を通す再帰的なアルゴリズムを実現すればいいのかわかりません。問題の関数は次のtree3
関数とlung
関数です。これにどうやって血管を追加すればいいでしょうか。
js
1 // 三脚のように三方向に分かれる木構造を描画する。 2 function tree3(size, depth, angle) { 3 if (depth == 0) { 4 turtle.add_sphere(0.5, turtle.get_pos(), 0xFFFFFF); 5 return; 6 } 7 var pg = turtle.get_pg(); 8 turtle.line_width = size / 5; 9 turtle.walk(size); 10 turtle.pitch(angle); 11 tree3(size * 0.75, depth - 1, angle); 12 turtle.pitch(-angle); 13 turtle.spin(120); 14 turtle.pitch(angle); 15 tree3(size * 0.75, depth - 1, angle); 16 turtle.pitch(-angle); 17 turtle.spin(-240); 18 turtle.pitch(angle); 19 tree3(size * 0.75, depth - 1, angle); 20 turtle.set_pg(pg); 21 } 22 23 // 肺臓を描画する関数。 24 function lung(size, depth, angle) { 25 var pg = turtle.get_pg(); 26 turtle.line_width = size / 5; 27 turtle.spin(90); 28 turtle.walk(size); 29 turtle.pitch(angle * 1.2); 30 tree3(size * 0.75, depth - 1, angle); 31 turtle.pitch(-angle * 1.2); 32 turtle.spin(180); 33 turtle.pitch(angle * 1.2); 34 tree3(size * 0.75, depth - 1, angle); 35 turtle.set_pg(pg); 36 }
単一のDHTMLで実行可能で、許容範囲内のコストであれば、どのようなアルゴリズムでも構いません。
追記2. 接続方法の例を次のリンクに示します。
https://twitter.com/katahiromz/status/1287192744268451841?s=19
追記3. もう少しです。
https://twitter.com/katahiromz/status/1287289038190256130
https://github.com/katahiromz/3D/blob/master/8.html
回答1件
あなたの回答
tips
プレビュー