2017-02-24 22 views
1

私はthree.jsで3D紡績ホイールのアニメーションを作ろうとしています。ホイールを加速するためにキーを押して、キーを離すと摩擦で減速して止まります。Three.jsスピードと摩擦でアニメーションをする

私はこのサイトでさまざまな例を試しましたが、正しく動作させることはできません。私は物理学を理解していますが、レンダーループで実装するのは苦労しています。

また、今後、私は減速曲線を実現したいと考えています。 誰かがこのようなことをする手掛かりを持っていますか?事前に

おかげ

編集:

私はそれをしたいよう

は最後にちょっと働いて何かを持って!デルタは、アニメーション作品を作るための鍵だったように思え `

var container, outputLeap; 
 
var camera, scene, renderer; 
 

 
var windowHalfX = window.innerWidth/2; 
 
var windowHalfY = window.innerHeight/2; 
 

 
var sceneRoot = new THREE.Group(); 
 
var wheelSpin = new THREE.Group(); 
 
var wheelMesh; 
 

 
var clock = new THREE.Clock(); 
 

 
var speed = 0.1; 
 
var decelRate = 100; 
 

 
function onWindowResize() { 
 
    windowHalfX = window.innerWidth/2; 
 
    windowHalfY = window.innerHeight/2; 
 

 
    camera.aspect = window.innerWidth/window.innerHeight; 
 
    camera.updateProjectionMatrix(); 
 

 
    renderer.setSize(window.innerWidth, window.innerHeight); 
 
} 
 

 
function onWindowResize() { 
 
    windowHalfX = window.innerWidth/2; 
 
    windowHalfY = window.innerHeight/2; 
 

 
    camera.aspect = window.innerWidth/window.innerHeight; 
 
    camera.updateProjectionMatrix(); 
 

 
    renderer.setSize(window.innerWidth, window.innerHeight); 
 
} 
 

 

 
function init() { 
 
    outputLeap = document.getElementById('output-leap'); 
 
    container = document.getElementById('container'); 
 

 

 
    camera = new THREE.PerspectiveCamera(30, window.innerWidth/window.innerHeight, 0.1, 80); 
 

 
    scene = new THREE.Scene(); 
 

 
    var geometryWheel = new THREE.CylinderGeometry(3, 3, 0.05, 32); 
 
    var materialWheel = new THREE.MeshBasicMaterial({ 
 
    color: 0xffff00, 
 
    wireframe: true 
 
    }); 
 
    var wheelMesh = new THREE.Mesh(geometryWheel, materialWheel); 
 
    scene.add(sceneRoot); 
 

 
    sceneRoot.add(wheelSpin); 
 
    wheelSpin.add(wheelMesh); 
 

 
    renderer = new THREE.WebGLRenderer(); 
 
    renderer.setClearColor(0x000000); 
 
    renderer.setPixelRatio(window.devicePixelRatio); 
 
    renderer.setSize(window.innerWidth, window.innerHeight); 
 
    container.appendChild(renderer.domElement); 
 

 
    window.addEventListener('resize', onWindowResize, false); 
 
} 
 

 
function render() { 
 

 
    var time = clock.getElapsedTime(); 
 
    var delta = clock.getDelta(); 
 

 
    camera.position.y = 15; 
 

 
    if (speed > 0) 
 
    speed = Math.max(0, speed - decelRate * delta); 
 
    else 
 
    speed = Math.min(0, speed + decelRate * delta); 
 

 
    camera.lookAt(scene.position); 
 
    wheelSpin.rotation.y -= speed; 
 

 
    outputLeap.innerHTML = 'Rotation: ' + speed; 
 

 
    renderer.render(scene, camera); 
 
} 
 

 

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

 

 
init(); 
 
animate();
<!DOCTYPE html> 
 
<html lang="en"> 
 

 
<head> 
 
    <title></title> 
 
    <meta charset="utf-8"> 
 
    <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0"> 
 
</head> 
 

 
<body> 
 
    <div id="info-top"> 
 
    <div id="output"></div> 
 
    <div id="output-leap"><br></div> 
 
    </div> 
 
    <div id="container"></div> 
 
    <script src="http://threejs.org/build/three.min.js"> 
 
    </script> 
 
    <script src='js/THREEx.KeyboardState.js'></script> 
 
    <script> 
 
    </script> 
 
</body> 
 

 
</html>

:これは私のコードです。しかし、今私はなぜだろうか?また、スピードと減速の変数をより現実的な値にどのように変換するのだろうか?

+0

ポストを簡素化されました – gman

答えて

1

摩擦および関連する加速度をシミュレートする方法は多数あります。

ここでは単純な統合によるものです。

摩擦(ドラッグ)は、速度の指数に関連する力です。その力は、移動する(回転する)オブジェクトの質量に対して作用します。

摩擦の位置が中央にあるので回転するオブジェクトがあるという事実は無視できます。また、軸がベアリングまたは潤滑シャフト上で回転していることが予想されます。ほとんどの場合、これはドラッグと表現できます。

ドラッグ関数からすべての係数、面積、粘性、転がり摩擦、およびかすを取り除くと(それらはすべて直線関係にあります)、コア関数を見てください。 drag = 1/2 * v*vここで、vは速度である。それをいくつかの係数で掛け合わせると、力が得られます。

速度は、車軸に接触する車輪の部分の動きであり、車軸の半径とスピンの速度から得られます。

これでシムを設定できます。

wheel = { 
    mass : 100, // mass 
    axleRadius : 40, // the lower the radius the less the drag 
    deltaRot : 0.3, // rate of turn per unit time. 
    dragCoff : 0.1, //coefficients of drag 
} 

その速度からドラッグ

var drag = 0.5 * velocity * velocity * wheel.dragCoff; 

ホイールの質量F = MA

に(力として)、そのドラッグの適用を受ける車軸

var velocity = wheel.deltaRot * axleRadius; 

に対する速度を取得します

var accel = drag/wheel.mass; 

アクセラレーションを元に戻す車軸に触れる表面上の速度

wheel.deltaRot -= accel/wheel.axleRadius; 

そして、あなたは車軸を回す車輪の良い近似を持っています。

車軸の半径は、ドラッグに大きな影響を与えます。半径が大きいほど、ドラッグが大きくなります。 dragCoffは、アクスルに触れる表面積、転がり抵抗、潤滑粘度を含む、我々が含まなかったすべての要因です。それらはすべての線形関係です(シミュレーション中に車軸半径を変更しないと仮定しているので)速度平方和と比較して、あなたのニーズに合うように1つの数値としてバンドルできます(もちろん1つよりも少ない)

そして質量が大きいほど、車輪が回転します。

は簡単なデモとしての機能は、あなたがこれまでに作ったものを少し

var wheel = { 
 
    mass : 100, 
 
    radius : 100, // has no effect on the sim 
 
    axleRadius : 30, 
 
    deltaRot : 1.3, 
 
    dragCoff : 0.2, //coefficients of drag 
 
    rotation : 0, 
 
} 
 
function updateWheel(w){ 
 
    w.deltaRot -= ((0.5 * Math.pow(w.deltaRot * w.axleRadius,2) * w.dragCoff)/w.mass)/w.axleRadius; 
 
    w.rotation += w.deltaRot; 
 
} 
 
function drawCircle(radius,x=0,y=0){ 
 
    ctx.beginPath(); 
 
    ctx.arc(0,0,radius,0,Math.PI * 2); 
 
    ctx.fill(); 
 
} 
 
function display() { 
 
    ctx.setTransform(1, 0, 0, 1, 0, 0); // reset transform 
 
    ctx.globalAlpha = 1; // reset alpha 
 
    ctx.clearRect(0, 0, w, h); 
 
    updateWheel(wheel); 
 
    ctx.setTransform(1,0,0,1,cw,ch); // draw at center of canvas 
 
    ctx.rotate(wheel.rotation); 
 
    ctx.fillStyle = "black"; 
 
    drawCircle(wheel.radius); 
 
    ctx.fillStyle = "red"; 
 
    drawCircle(wheel.radius-10); 
 
    ctx.fillStyle = "black"; 
 
    ctx.fillRect(0,-10,wheel.radius-5,20); 
 
    ctx.fillStyle = "white"; 
 
    drawCircle(wheel.axleRadius+2); 
 
    ctx.fillStyle = "black"; 
 
    drawCircle(wheel.axleRadius); 
 
} 
 

 
var w, h, cw, ch, canvas, ctx, globalTime = 0, firstRun = true; 
 
;(function(){ 
 
    var createCanvas, resizeCanvas; 
 
    createCanvas = function() { 
 
     var c, cs; 
 
     cs = (c = document.createElement("canvas")).style; 
 
     cs.position = "absolute"; 
 
     cs.top = cs.left = "0px"; 
 
     cs.zIndex = 1000; 
 
     document.body.appendChild(c); 
 
     return c; 
 
    } 
 
    resizeCanvas = function() { 
 
     if (canvas === undefined) { 
 
      canvas = createCanvas(); 
 
     } 
 
     canvas.width = innerWidth; 
 
     canvas.height = innerHeight; 
 
     ctx = canvas.getContext("2d"); 
 
     cw = (w = canvas.width)/2; 
 
     ch = (h = canvas.height)/2; 
 
     wheel.deltaRot = 1.3; 
 
    } 
 
    function update() { // Main update loop 
 
     display(); // call demo code 
 
     requestAnimationFrame(update); 
 
    } 
 
    setTimeout(function(){ 
 
     resizeCanvas(); 
 
     window.addEventListener("resize", resizeCanvas); 
 
     requestAnimationFrame(update); 
 
    },0); 
 
})();

関連する問題