[WP]no.019 HTMLで3D描画@GLを使わずに

HTML/Javascriptでも、WebGLを用いるよう初期化すれば、とても美しいかつ高速な三次元描画が可能です。

そんな事知ったことか。


ここでは「getContext("2d")」で2Dキャンバスを取得し、行列演算によって透視変換を行い、描画します。ゴリ押し。

あんまり美しくない、簡素で、言うほど高速でない三次元描画が可能です。


透視変換について、こちらのサイトを参照。ほぼそのまま使ってます。

■3次元図形表示技術■2次元への投影方法
http://www.geocities.co.jp/SiliconValley-Bay/4543/Rubic/Mathematics/Mathematics-5.html


視点方向の回転ができないので、それをしたい場合は行列に手を必要があるなど。



ボタンポチポチやると平面が移動します。かなり手抜き。
<html>

<head>
<title>数学でごり押す三次元描画</title>

<script type="text/javascript">
<!--
var d3_scale=0.001;
var d3_camera={
pos:{x:0.0,y:0.0,z:0.0},
s1:0.0,
c1:0.0,
s2:0.0,
c2:0.0
}
var pv1,pv2,pv3,pv4;
var ct;

window.onload = function(){
var ce = document.getElementById("maincanvas");
ct = ce.getContext("2d");

setcamera({x:0,y:10,z:50},{x:0,y:5,z:0});
pv1={x:-10,y:-10,z:0};
pv2={x:-10,y:10,z:0};
pv3={x:10,y:10,z:0};
pv4={x:10,y:-10,z:0};
draw();
}
function move(x,y,z){
pv1.x+=x;
pv1.y+=y;
pv1.z+=z;
pv2.x+=x;
pv2.y+=y;
pv2.z+=z;
pv3.x+=x;
pv3.y+=y;
pv3.z+=z;
pv4.x+=x;
pv4.y+=y;
pv4.z+=z;
}

function draw(){
var pex,pey,pez,pz,p1,p2,p3,p4;

ct.fillStyle = "#FFFFFF";
ct.fillRect(0,0,360,360);

ct.strokeStyle="#000000";

p1=convert3d(pv1);
p2=convert3d(pv2);
p3=convert3d(pv3);
p4=convert3d(pv4);

ct.beginPath();
ct.moveTo(p1.x,p1.y);
ct.lineTo(p2.x,p2.y);
ct.lineTo(p3.x,p3.y);
ct.lineTo(p4.x,p4.y);
ct.lineTo(p1.x,p1.y);
ct.closePath();
ct.stroke();
console.log(d3_camera);
console.log(p1);
console.log(p2);
console.log(p3);
console.log(p4);
}


function setcamera(cp,ct){
var a,b;
a = Math.sqrt((cp.x-ct.x)*(cp.x-ct.x)+(cp.y-ct.y)*(cp.y-ct.y));
b = Math.sqrt(a*a+(cp.z-ct.z)*(cp.z-ct.z));
d3_camera.s1 = (cp.y-ct.y)/a;
d3_camera.c1 = (cp.x-ct.x)/a;
d3_camera.s2 = (cp.z-ct.z)/b;
d3_camera.c2 = a/b;
d3_camera.pos = cp;
}
function convert3d(v){
var x,y,z,_x,_y,_z;
x=(v.x-d3_camera.pos.x);
y=(v.y-d3_camera.pos.y);
z=(v.z-d3_camera.pos.z);
_x=-d3_camera.s1*x +d3_camera.c1*y;
_y=-d3_camera.s2*d3_camera.c1*x -d3_camera.s2*d3_camera.s1*y +d3_camera.c2*z;
_z=-d3_camera.c2*d3_camera.c1*x -d3_camera.c2*d3_camera.s1*y -d3_camera.s2*z;
return {x:_x/_z*180+180, y:_y/_z*180+180};
}
// -->
</script>

</head>
<body>
<canvas id="maincanvas" width="360" height="360" style="border-style:solid;border-width:1px"></canvas>
<input type="button" value="-x" onclick="move(-10,0,0);draw();">
<input type="button" value="+x" onclick="move(10,0,0);draw();">
<input type="button" value="-y" onclick="move(0,-10,0);draw();">
<input type="button" value="+y" onclick="move(0,10,0);draw();">
<input type="button" value="-z" onclick="move(0,0,-10);draw();">
<input type="button" value="+z" onclick="move(0,0,10);draw();">

</body>

</html>


setcamera(カメラ位置,カメラ視点)でカメラを定め、convert3d({x,y,z})で三次元のヴェクターを二次元に投影します。


スポンサーサイト

テーマ : プログラミング
ジャンル : コンピュータ

tag : HTML5

コメントの投稿

非公開コメント

プロフィール

舞葉(ぶよう)

Author:舞葉(ぶよう)
github.io
はてなブログ(競プロ)

古い記事のソースコードは色分けしていないので、高機能テキストエディタに貼り付けたほうが見やすいかも。

検索フォーム
このブログについて
自分がつまづいた話題、なんとなく書きたいと思ったこと、ググったけど殆ど資料なかったぞオイ な話等をアップする予定。通りすがりでも、参考になっていただければと。プログラムの例外入力、メモリリークは責任負いません。投稿された記事は修正・削除する場合があります。
カテゴリ
タグ

HSP3アルゴリズムとデータ構造c++RubyJavaUnity画像解析C機械学習C#LinuxcodeIQKinectMinecraftTonyuSystemraspberrypiPythonHTML5音声制御Simulinkruby俺ルール通信制御Javascriptシミュレーション

counter-shinobi
固定記事
最新記事
最新コメント
月別アーカイブ
ブロとも申請フォーム

この人とブロともになる

アクセスランキング
[ジャンルランキング]
コンピュータ
1253位
アクセスランキングを見る>>

[サブジャンルランキング]
プログラミング
219位
アクセスランキングを見る>>