2016-02-29 13 views
7

私はここにdivをつけた回転球を持っています:https://jsfiddle.net/ao5wdm04/ 私はxとyの値を計算し、translate3dの変換を使ってdivを配置しますそれはかなりうまくいく。キューブ面の回転ベクトルカメラとの関係

私の質問はどのようにrotateXの値を取得することができ、rotateYrotateZまたはrotate3dはそうdivの「接線」球体の表面を変換しています。私はキューブメッシュが球の中心に向いていることを知っているので、カメラに関連して外向きの法線ベクトルの回転ベクトルに必要な値が含まれていると仮定します。しかし、私はこれらをどのように入手するかについてはあまりよく分かりません。

更新オイラーは、私はほとんどここに示す所望の効果を達成しています角度使用することにより

https://jsfiddle.net/ao5wdm04/1/はなく、回転が十分ではありません。

+0

[このフィドル](http://jsfiddle.net/qa6erofL/)は 'WebGLRenderer'と' CSS3DRenderer'をミックスする方法を示してコード - 試してみてください。それは私のためにChromeで動作しますが、いくつかの問題があるかもしれません。 div3の代わりに 'THREE.PlaneGeometry'を使用してCSS3Dを回避できますか? – WestLangley

+0

これは良い考えですが、Safariでは動作しませんが、CSS変換は実行可能ではありませんか? –

+0

申し訳ありませんが、何が起こっているのか分かりません。 'WebGLRenderer'だけを使うことを考えてください。 – WestLangley

答えて

2

免責事項:私はthree.jsについて何も知らない。私は少しだけOpenGLをやった。

オイラーアングルは、モデルビュー投影原点から来ています(74〜80行目)。私はこの背後にある論理を見ることができません。

divが球面上にある場合は、divの位置で球の法線を基準にする必要があります。幸いにも、あなたはすでにこれらの角度を持っています。名前はrotationです。

円グラフのオイラー角をdivの位置を決める回転角に置き換えた場合、ブラウザでは円の端にあるときにdivがエッジに表示され、中央にある。それは円の中を動いているように見えますが、画面上には縁があります。これはあなたが望む効果ですか?リンクされたコードへ

マイ修正:

82 var rotX = (rotation.x * (180/ Math.PI)); 
83 var rotY = (rotation.y * (180/ Math.PI)); 
84 var rotZ = 0; 

EDIT

ああ、OK。 rotation変数は、カメラの変数と同じです。赤道での接線を支配します。また、緯度を考慮して向きを変更する必要があります。

rotYを緯度と同じにします。次に、この回転が赤道回転の前に起こることを確認します。回転は可換ではありません。要約すると

次のように、https://jsfiddle.net/ao5wdm04/1/のコードからの変更点は以下のとおりです。

27 var lat = 45 * Math.PI/180; 
... 
82 var rotX = (rotation.x * (180/ Math.PI)); 
83 var rotY = - 45; 
... 
88 document.getElementById('face').style.webkitTransform = 'translate3d(' + x + 'px,' + y + 'px,0px) rotateY('+rotX+'deg) rotateX('+rotY+'deg)'; 

私は緯度がinitrender関数間で伝播する必要があるのか​​分かりません。私が言ったように、私は言語に精通していない。

+0

まあまあ、円が赤道に置かれている場合にのみ動作します。 27行目を0以外のもの(45)に変更すると、円は正しく回転しません。 –

+0

ありがとう、私が後にした効果でした! –

0

OpenGLやその他のグラフィックスでの変換と回転の詳細については、hereを参照してください。


基本 - 基本的には世界的な3Dでの変換の2種類

あり

  1. Translation
  2. Rotation

enter image description here

この例の小さな例はhereです。


私がそれらをすべて調べると、私は3D変換システムについて明確な概念があると思います。

あなたがそれらを理解することができれば、私は簡単にそれをシミュレートすることができます。なぜなら、あなたは同時にこの2つのことを行う必要があるからです。

が、これは

var camera, scene, renderer, raycaster, geometry, material, mesh, box; 
 
var rotation = { 
 
    x: 0, 
 
    y: 0 
 
}; 
 
var distance = 500; 
 

 
init(); 
 
animate(); 
 

 
function init() { 
 
    raycaster = new THREE.Raycaster(); ; 
 
    scene = new THREE.Scene(); 
 
    camera = new THREE.PerspectiveCamera(50, window.innerWidth/window.innerHeight, 1, 10000); 
 
    camera.position.z = distance; 
 
    camera.position.y = 100; 
 
    scene.add(camera); 
 

 
    geometry = new THREE.SphereGeometry(100, 50, 50, 50); 
 
    material = new THREE.MeshNormalMaterial(); 
 

 
    mesh = new THREE.Mesh(geometry, material); 
 
    scene.add(mesh); 
 

 
    var transform = new THREE.Matrix4().getInverse(scene.matrix); 
 

 
    var lat = 0 * Math.PI/180; 
 
    var lon = 90 * Math.PI/180; 
 
    var r = 100; 
 
    var p = new THREE.Vector3(-r * Math.cos(lat) * Math.cos(lon), 
 
    r * Math.sin(lat), 
 
    r * Math.cos(lat) * Math.sin(lon) 
 
); 
 
    p.applyMatrix4(transform); 
 

 
    var geometry = new THREE.CubeGeometry(10, 10, 10); 
 
    box = new THREE.Mesh(geometry, new THREE.MeshBasicMaterial({ 
 
    color: 0xff0000, 
 
    
 
    })); 
 
    box.position.set(p.x, p.y, p.z); 
 
    box.lookAt(mesh.position); 
 
    //scene.add(box); 
 
    box.updateMatrix(); 
 

 
    renderer = new THREE.WebGLRenderer(); 
 
    renderer.setSize(window.innerWidth, window.innerHeight); 
 

 
    document.body.appendChild(renderer.domElement); 
 

 
} 
 

 
function animate() { 
 

 
    requestAnimationFrame(animate); 
 
    render(); 
 
} 
 

 
function render() { 
 

 
    rotation.x += 0.01; 
 
    camera.position.x = distance * Math.sin(rotation.x) * Math.cos(rotation.y); 
 
    camera.position.y = distance * Math.sin(rotation.y); 
 
    camera.position.z = distance * Math.cos(rotation.x) * Math.cos(rotation.y); 
 

 
    camera.lookAt(mesh.position); 
 

 
    var w = window.innerWidth; 
 
    var h = window.innerHeight; 
 

 
    var mat = new THREE.Matrix4(); 
 
    var v = new THREE.Vector3(); 
 

 
    mat.copy(scene.matrix); 
 
    mat.multiply(box.matrix); 
 
    v.set(0, 0, 0); 
 
    v.applyMatrix4(mat); 
 
    v.project(camera); 
 
    
 
    var euler = new THREE.Euler().setFromVector3(v); 
 
    
 
    var rotX = (rotation.x * (180/ Math.PI)); 
 
    var rotY = (rotation.y * (180/ Math.PI)); 
 
    var rotZ = 0; 
 
    
 
    var x = (w * (v.x + 1)/2) - 12.5; //compensate the box size 
 
    var y = (h - h * (v.y + 1)/2) - 12.5; 
 
    document.getElementById('face').style.webkitTransform = 'translate3d(' + x + 'px,' + y + 'px,0px) rotateX('+rotY+'deg) rotateY('+rotX+'deg) rotateZ('+rotZ+'deg)'; 
 

 
    renderer.render(scene, camera); 
 

 
}
#face { 
 
    position: absolute; 
 
    width: 25px; 
 
    height: 25px; 
 
    border-radius: 50%; 
 
    background-color: red; 
 
}
<script src="https://rawgit.com/mrdoob/three.js/master/build/three.min.js"></script> 
 

 
<div id="face"></div>

関連する問題