HTMLでレイトレーシング (1回目)
2021/6/9(水)
HTMLでレイトレーシング (1回目)
by ULproject for HTML(JavaScript, canvas)
レイトレーシングで球を表示するという
簡単なプログラムをHTML(Java script, canvas)で作ります
このシリーズは、式などに関する説明を省略して
いますので
詳しくは
を見てください
図1 視線方向の単位ベクトルE(上記矢印)
とその出発点V(視点位置ベクトル)
視線と球の1番近い交点の色をスクリーン上に
描いて行きます
ここから、数値(スカラー)を小文字、ベクトル
(x,y,z成分を持つ矢印)を大文字で書きます
原点が中心で半径rの球は、
|P| = r
(|P - C| = rは視線を移動すれば良いので不必要です)
視点VからE方向に向けた視線は、
P = V + Etです
|P| = r にP = V + Etを代入して、
|V + Et| = rの両辺を2乗して||を外し、
整理すると(E・E = |E|2 = 12 = 1より)
t2 + 2(V・E)t + (V・V - r2) = 0で
tの2次方程式になり、解の公式で
視点から球との交点までの距離
t = -V・E±√{ (V・E)2 - V・V + r2 }です
判別式D = (V・E)2 - V・V + r2 で3パターン判別
D < 0 → 交差しない (tは虚数)
D = 0 → 1点で接する(tは1個)
D > 0 → 2点で貫く (tは遠近2個)
これをJava scriptで書いていきます
ベクトルの成分は、
P=(x, y, z)、V=(Vx ,Vy ,Vz)、V=(V0, V1, V2)
などと表しますが、配列を使うことにします
var V = [x, y, z]
または
var V = new Array(3)
で、定義します
(x, y, zは座標を表す数値、Array(3)の3は
配列の要素数なのでx,y,zの3要素を指定します)
定義するとV[0],V[1],V[2]という変数が使え
それぞれx,y,z成分とします
VとEの内積は同じxyz成分同士の積の和なので
b = V・Eは、
b = V[0]*E[0] + V[1]*E[1] + V[2]*E[2]
となります
四則演算は + - * / です
√(n) は、Math.sqrt(n)
rの2乗は、r**2 または r*r と書きます
t = -V・E±√( (V・E) - V・V + r2)は、
b = V・E、d = V・V - r2 と置くとt = -b±√(b2 - d)
をプログラムで書きます
HTMLの説明
<!--
ここにコメントを描く
-->
<!DOctxYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>ここにタイトルを書く</title>
</head>
<body>
<p id="ここにこのページの識別名を書く"></p>
<script>
ここにJava scriptを書く
</script>
</body>
</html>
です
Java scriptの説明
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
canvas.width = '640';
canvas.height = '400';
document.body.appendChild(canvas);
で、画面描画のためのcanvasの使用準備をします
ここでは640×400ドットの画面を使用します
上記でctxという名でcanvasを使用するように
定義していますのでctx.~でcanvasを使用します
Java scriptでは//以降か/*と*/の間がコメント
になります
(Java scriptはC++に良く似ていると思います)
// 描画関数
画面クリア、色指定など基本命令を関数定義しています
canvasの色は文字列で'#rgb'か'#rrggbb'
(rgb各0~fの16進数)で指定します
前者はrgb各16段階、後者はrgb各256段階です
例
黒は、'#000'か'#000000'
赤は、'#f00'か'#ff0000'
白は、'#fff'か'#ffffff'
function命令でdistance_sphere(V, E, r)
という関数を定義しています
(変数の型は無く値によって自動変化する様です)
function distance_sphere(V, E, r)
{
var b, d, t;
b = V[0]*E[0] + V[1]*E[1] + V[2]*E[2]; // b = V・E
d = V[0]*V[0] + V[1]*V[1] + V[2]*V[2] - r*r; // d = V・V - rr
d = b*b - d; // d判別式
if (d < 0) return -1.0; // 交点なし
d = Math.sqrt(d);
t = -b - d; // 視線と球の近い方の交点距離
if (t < 0) t = -b + d; // 視線と球の遠い方の交点距離
return t;
}
視点V、視線E、半径rを指定して呼び出すと
distance_sphere(V, E, r)が距離になります
(return の後に指定した値が関数の値になります)
式の書式などはBASICと似ているので説明は省きます
function trace()
{
var V = [0, 0, 100];
var E = [0, 0, -1];
var r = 10;
var t;
t = distance_sphere(V, E, r);
color('#fff');
ctx.font = "16px 'MS ゴシック'";
ctx.fillText(t, 0, 16*2);
}
距離をtに代入して、canvasで表示しています
function idle()
{
cls('#000');
color('#fff');
ctx.font = "16px 'MS ゴシック'";
ctx.fillText("HTMLでレイトレーシング(1回目) ULproject", 0, 16);
trace();
}
画面クリアとタイトルを表示して
上記trace()関数を呼び出しています
idle();
上記idle()関数を呼び出しています
以上でjava script終了です
ray001.htmlはMicrosoft Edgeに重ねると
動き、メモ帳でコードを見ることが出来ます
blg~.zip(ray001.html)は
以下のリンクからダウンロードできます
Readme.txtを読んで遊んで下さい