HTMLでレイトレーシング (1回目)

2021/6/9(水)

HTMLでレイトレーシング (1回目)


by ULproject for HTML(JavaScript, canvas)


レイトレーシングで球を表示するという

簡単なプログラムをHTML(Java script, canvas)で作ります


このシリーズは、式などに関する説明を省略して

いますので

詳しくは

N88-BASICでレイトレーシング (1回目)

を見てください









図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)は

以下のリンクからダウンロードできます

VL-BASIC(N88-BASIC互換?)ホームページ

Readme.txtを読んで遊んで下さい


このブログの人気の投稿

NEWS

N88-BASICでゲーム (1回目)