2009-10-18 27 views
16

HTML 5.0キャンバスに3Dボールや球を描きたい。私は3D球を描く方法についてアルゴリズムを理解したい。誰が私とこのことを共有できますか?3D球を描く方法は?

+1

を見つけてください「3d球」の意味ですか?あなたは陰影の意味ですか?ワイヤーフレーム? –

+11

3d以外の球体はありますか? – Rook

+0

Idigas:明らかに4Dが存在しますが、その可視投影は基本的に3Dと同じですが、そのサイズは変化し続けます。 – Esko

答えて

0

球のイメージは常にあなたの画面上に円形の形をしているので、重要なのは陰影だけです。これは光源を置く場所によって決まります。アルゴリズムについては

ray tracingが最も簡単ですが、またそうあなたはおそらく(特に、その環境で利用可能なグラフィックスアクセラレーションの欠如を与え<CANVAS>に非常に複雑な何かをするためにそれを使用したくない遠く—することにより、最も遅いです)、単一の球体をしたいと思っていれば十分速いかもしれません。

+0

光源が変わらないとすれば、彼はそれを事前レンダリングしてビットマップをblitすることもできます; ^) – Toad

7

球をモデル化する必要があります。球をモデル化して回転させると、球ではなくレンダリングされるように色が変化する必要があります。

それ以外の場合は、その周囲の参照点ではない球は、すべてが単色であれば円のように見えます。

まず、あなたが持っている主要なプリミティブであるように、長方形の円を描こうとします。

これを行う方法を理解したり、Pathメソッドを使用して三角形などの新しいプリミティブを作成して円を作成すると、3Dに移動する準備が整います。

3Dはちょうどおもしろいのですが、おそらく数式で生成されたモデルを取り出し、それを平坦化して表示する部分を決定し、表示します。

しかし、光の光源からどのくらい離れているかに基づいて、また光源に対するその部分の角度に基づいて、三角形の色を変えたいと思うでしょう。

ここで、このピクセルをピクセル単位でレイトレーシングする場合、最適化を開始できます。より大きなブロックと光源の点光源があり、オブジェクトが回転していて動き回っていない場合、各三角形の色がどのように変化するかを再計算できます。回転をシミュレートするために色を変更するだけです。

このアルゴリズムは、どのような単純化をしたいのかによって異なります。したがって、これまでに行ったことを示して、経験を得るようになります。

ここではその例を示します。以下では3D球部分をコピーしましたが、article全体を見てください。

function Sphere3D(radius) { 
this.point = new Array(); 
this.color = "rgb(100,0,255)" 
this.radius = (typeof(radius) == "undefined") ? 20.0 : radius; 
this.radius = (typeof(radius) != "number") ? 20.0 : radius; 
this.numberOfVertexes = 0; 

// Loop from 0 to 360 degrees with a pitch of 10 degrees ... 
    for(alpha = 0; alpha <= 6.28; alpha += 0.17) { 
    p = this.point[this.numberOfVertexes] = new Point3D(); 

    p.x = Math.cos(alpha) * this.radius; 
    p.y = 0; 
    p.z = Math.sin(alpha) * this.radius; 

    this.numberOfVertexes++; 
} 

// Loop from 0 to 90 degrees with a pitch of 10 degrees ... 
// (direction = 1) 

// Loop from 0 to 90 degrees with a pitch of 10 degrees ... 
// (direction = -1) 

for(var direction = 1; direction >= -1; direction -= 2) { 
    for(var beta = 0.17; beta < 1.445; beta += 0.17) { 

    var radius = Math.cos(beta) * this.radius; 
    var fixedY = Math.sin(beta) * this.radius * direction; 

    for(var alpha = 0; alpha < 6.28; alpha += 0.17) { 
     p = this.point[this.numberOfVertexes] = new Point3D(); 

     p.x = Math.cos(alpha) * radius; 
     p.y = fixedY; 
     p.z = Math.sin(alpha) * radius; 

     this.numberOfVertexes++; 
    } 
    } 
} 
} 
+0

これらの例は素晴らしいです。彼らはChromeで見ることを推奨していますが、旗の波とiPhone(デフォルトのレンダラー)はSafariでうまく機能しました。 –

+0

私はChromeが速いかもしれないと思っていますが、今はSafari 4、Firefox 3.5、Chrome、Opera 10がこれらをうまく表示できるはずです。 –

+0

デッドリンク(ドメイン全体)。 – brichins

6

更新:このコードはかなり古いと限られています。ライブラリは現在、3Dの球体を行うためにあります。http://techslides.com/d3-globe-with-canvas-webgl-and-three-js/


10年以上前、私は(球の表面は、シーンにあった場所を動作するように、実際に数学を行うことによって、テクスチャ球体をレンダリングするためにJavaアプレットを書きました三角形を使用しない)。

私はキャンバスのためにJavaScriptでそれを書き換えていると私はdemo rendering the earth as a sphereを持っている:

alt text http://sam.haslers.info/render-sphere/JavaScript+Canvas.png

私は私のマシン上の周りに22 FPSを取得します。レンダリングに基づいていたJavaバージョンとほぼ同じ速さですが、少し速くはありません。

私はJavaコードを書いて以来、長い時間がかかりました。それはかなり鈍かったので、実際の動作を覚えていません。JavaScriptを移植しました。しかし、これはコードのバージョンが遅いからです。より速いバージョンが、私がピクセルを操作するのに使ったJavaメソッドの最適化や、計算の高速化から、どのピクセルをレンダリングするのかテクスチャ私はまた、私よりもはるかに高速だった類似のアプレットを持っていた人にも対応していましたが、Javaライブラリに依存していたため、JavaScriptで可能だったスピードの改善があるかどうかわかりません。 (私は彼らのコードを見たことがないので、どのように行ったのかわかりません)

だから、は速度を改善することが可能です。しかし、これは概念の証明としてはうまく機能します。

あなたはスピードを比較するに興味があるなら、Javaのバージョンはここにある:

これらの私は次の私のウェブサイトの更新まで、死者のリンクがある

私はJavaScriptバージョンに任意の速度の向上を得ることができるかどうかを確認するために私の速いバージョンいくつかの時間を変換するに行く必要があります。

+0

JavaScript + CanvasデモはFirefoxでのみ動作します。 Chromeはこの質問と同じエラーを表示します:http://stackoverflow.com/questions/982000/firefox-throwing-a-exception-with-html-canvas-putimagedata –

+0

高速版を見る時間がありませんでしたがいくつかの簡単な改良があり、最大40fpsになります。 –

+0

下の3つのリンクが死んでいます。 – bjb568

4

コアwebglプログラミングから多くのコードを抽象化したthree.jsライブラリで試すことができます。 HTMLにthree.jsライブラリをthree.js libから含めてください。

uがWebGLのは、クロム

のために働く、Safariブラウザのためのキャンバスのレンダラを使用することができますあなたは何JS FIDDLE FOR SPHERE

のvarカメラ、シーン、材料、メッシュ、形状、レンダラ

function drawSphere() { 
    init(); 
    animate(); 

} 

function init() { 
    // camera 

    scene = new THREE.Scene() 
    camera = new THREE.PerspectiveCamera(50, window.innerWidth/innerHeight, 1, 1000); 
    camera.position.z = 300; 
    scene.add(camera); 

    // sphere object 
    var radius = 50, 
     segments = 10, 
     rings = 10; 
    geometry = new THREE.SphereGeometry(radius, segments, rings); 
    material = new THREE.MeshNormalMaterial({ 
     color: 0x002288 
    }); 
    mesh = new THREE.Mesh(geometry, material); 

    //scene 
    ; 
    scene.add(mesh); 


    // renderer 
    renderer = new THREE.WebGLRenderer(); 
    renderer.setSize(window.innerWidth, window.innerHeight); 
    document.body.appendChild(renderer.domElement); 

} 


function animate() { 
    requestAnimationFrame(animate); 
    render(); 

} 

function render() { 

    mesh.rotation.x += .01; 
    mesh.rotation.y += .02; 
    renderer.render(scene, camera); 


} 

// fn callin 
drawSphere(); 
+0

最後にJSFIDDLEデモ。 :-)ありがとう! –

+0

私はちょうどそれが必要です、ありがとう! – JNYJ