2017-02-24 284 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是速度。將其乘以一定係數調整,我們得到了力量。

速度是車輪接觸車軸的部分的運動,我們從軸和旋轉速度的半徑得到。

因此,我們可以設置SIM卡。

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 velocity = wheel.deltaRot * axleRadius; 

速度從車輪上的質量F =毫安

該速度

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

應用該拖動(作爲力)獲取拖動

var accel = drag/wheel.mass; 

將加速度轉換回t表面鄰速度觸摸車軸

wheel.deltaRot -= accel/wheel.axleRadius; 

而且你在車軸上的車輪轉向的一個很好的近似。

軸半徑對阻力有很大影響。半徑越大,阻力越大。 dragCoff是我們沒有包括的所有因素,如表面積接觸軸,軸承滾動阻力,潤滑粘度。他們都是線性關係(因爲我認爲你不會改變模擬過程中的軸半徑)相比,速度的平方,因此可以捆綁爲一個數字,以滿足您的需求(當然少於一個)

而且質量越大,車輪旋轉的時間越長。

作爲一個簡單的演示功能已經被簡化了一點

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); 
 
})();