2015-01-09 3 views
0

나는 그것에 정지 거리를 설정하고 그 목표 지점에 도달하기 위해 그 정지 거리에서 객체를 얼마나 느리게해야하는지 계산하고자하는 스프라이트 애니메이션이 있습니다. 속도. 그러나 그 순간 나는 올바른 결과를 얻지 못하고 있습니다.설정된 거리와 목표 속도에 대한 속도를 계산하는 방법

내 코드는 다음과 같습니다

function updatePosition(obj,brake){ 
    var delta = new Date().getTime() - obj.timer; //time since last frame 

    if(brake){   
     obj.velocity -= (Math.pow(obj.velocity,2) - Math.pow(obj.targetSpeed,2))/(2 * obj.stopDist); 
     if(obj.velocity < obj.targetSpeed){ 
      obj.velocity = obj.targetSpeed; 
     } 
    } 
} 

내 문제는 스프라이트가 훨씬 속도도 위의 목표 속도와 정지 거리를지나갑니다이다.

나는 빨간색 점이 여기에 목적지에 여행으로 바이올린을 만든 : http://jsfiddle.net/4tLmz3ch/1/

는 그것이 그것의 목적지에 도달하기 전에 잘해야 목표 속도를하려고한다 obj.stopDist에 의해 설정된 거리를 이동합니다. 그러나 나는 분명히 여기에 수학으로 잘못된 것을 얻고있다.

희망 사항을 이해하면 오해를 설명하는 데 도움이됩니다.

+0

속도는 스칼라 값이 아닙니다. 당신은 스칼라와 벡터 계산을 뒤섞어 쓰고 있습니다. 그리고 나는 그것이 큰 문제 중 하나라고 생각합니다. – JLRishe

+0

@JLRishe 당신이 무슨 뜻인지 100 % 확신하지 못하겠습니까? 속도 값을 변경하지 않아야합니까? – Sir

+0

나는 그것을 가지고있어. – mike510a

답변

3

이 문제는 미리 원하는 가속을 결정하고 새로 고침 할 때마다이 문제를 사용하면 훨씬 간단 해집니다. 그런 다음 각각의 프레임의 전체 코드 (도면 논리를 제외하고 하나 개의 차원을 가정)은 단지된다 :

function frame() { 
    var t = new Date().getTime(); 
    var tDelta = t - obj.lastTime; 

    obj.lastTime = t; 

    obj.pos += obj.velocity * tDelta; 

    if (obj.velocity > obj.destVelocity) { 
     obj.velocity += obj.acceleration * tDelta; 
    } 

    draw(); 

    setTimeout(frame, 1); 
} 

는 시작과 끝 위치 및 속도 (일정 가속도 가정) 요구되는 가속도에 대한 식을 주어진다

따라서이 같은 객체 초기화

(2 * v0 * (vf - v0) + (vf - v0)^2)/(2 * (xf - x0))

: 여기

var obj = { 
    start: 10, 
    height: 200, 
    stopDist: 300, 
    dest: 500, 
    lastTime: new Date().getTime(), 
    velocity: 0.05, 
    destVelocity: 0.01, 
    pos: undefined, 
    acceleration: undefined 
}; 

우리가 개성 공단 할 수있는 방법입니다 k all this off :

function start(){ 
    var v0 = obj.velocity, 
     vf = obj.destVelocity, 
     x0 = obj.start, 
     xf = x0 + x.stopDist, 
     vDelta = vf - v0; 

    obj.pos = x0; 
    obj.acceleration = (2 * v0 * vDelta + vDelta * vDelta)/(2 * (xf - x0)); 

    frame(); 
} 

1 번째 사례를 먼저 해결하는 것이 좋습니다. 여기 모두가 함께 있습니다.

var canvas = document.getElementById('canvas'); 
 
var test = document.getElementById('test'); 
 
var ctx = canvas.getContext('2d'); 
 

 
function drawDot(color, x, y) { 
 
    ctx.fillStyle = color; 
 
    ctx.fillRect(x - 2, y - 2, 4, 4); 
 
} 
 

 
function draw() { 
 
    ctx.clearRect(0, 0, canvas.width, canvas.height); 
 

 
    drawDot("red", obj.pos.x, obj.pos.y); 
 
    drawDot("white", obj.start.x, obj.start.y); 
 
    drawDot("green", obj.dest.x, obj.dest.y); 
 
    drawDot("yellow", obj.stopLocation.x, obj.stopLocation.y); 
 
    
 
    var dx = obj.pos.x - obj.start.x, 
 
     dy = obj.pos.y - obj.start.y, 
 
     dist = Math.sqrt(dx * dx + dy *dy), 
 
     v = obj.velocity, 
 
     speed = Math.sqrt(v.x * v.x + v.y * v.y); 
 
    
 
    ctx.fillText("distance traveled: " + dist.toFixed(5), 20, 400); 
 
    ctx.fillText("speed:    " + speed.toFixed(5), 20, 420); 
 
} 
 

 
var obj = { 
 
    start: { x: 400, y: 230 }, 
 
    stopDist: 350, 
 
    dest: { x: 50, y: 330 }, 
 
    lastTime: new Date().getTime(), 
 
    startSpeed: 0.05, 
 
    destSpeed: 0.1, 
 

 
    pos: null, 
 
    velocity: null, 
 
    destVelocity: null, 
 
    acceleration: null 
 
}; 
 

 
function sign(value) { 
 
    return value > 0 ? 1 : (value < 0 ? -1 : 0); 
 
} 
 

 
function reached(start, current, dest) { 
 
    return current === dest || 
 
     sign(current - dest) === sign(dest - start); 
 
} 
 

 
function frame() { 
 
    var t = new Date().getTime(), 
 
     tDelta = t - obj.lastTime, 
 
     v = obj.velocity, 
 
     destv = obj.destVelocity, 
 
     startv = obj.startVelocity; 
 
    obj.lastTime = t; 
 

 
    obj.pos.x += v.x * tDelta; 
 
    obj.pos.y += v.y * tDelta; 
 
    
 
    if (!reached(startv.x, v.x, destv.x) || 
 
     !reached(startv.y, v.y, destv.y)) { 
 
     v.x += obj.acceleration.x * tDelta; 
 
     v.y += obj.acceleration.y * tDelta; 
 
    } 
 

 
    draw(); 
 

 
    setTimeout(frame, 1); 
 
} 
 

 
function calcAcceleration(p0, pf, v0, vf) { 
 
    var vDelta = vf - v0; 
 
    
 
    return pf === p0 
 
     ? 0 
 
     : (2 * v0 * vDelta + vDelta * vDelta)/(2 * (pf - p0)); 
 
} 
 

 
function start() { 
 
    // positions and deltas 
 
    var start = obj.start, 
 
     dest = obj.dest, 
 
     dx = dest.x - start.x, 
 
     dy = dest.y - start.y, 
 
     totalDistance = Math.sqrt(dx * dx + dy * dy); 
 
    
 
    // x and y component ratio 
 
    var cx = dx/totalDistance, 
 
     cy = dy/totalDistance; 
 
    
 
    var stopLocation = { x: cx * obj.stopDist + start.x, 
 
         y: cy * obj.stopDist + start.y }; 
 
    
 
    // velocities 
 
    var startSpeed = obj.startSpeed, 
 
     destSpeed = obj.destSpeed, 
 
     startVelocity = { x: cx * startSpeed, y: cy * startSpeed }, 
 
     endVelocity = { x: cx * destSpeed, y: cy * destSpeed }; 
 
    console.log(startVelocity); 
 
    console.log(endVelocity); 
 
    
 
    // acceleration 
 
    var acceleration = { 
 
     x: calcAcceleration(start.x, stopLocation.x, startVelocity.x, endVelocity.x), 
 
     y: calcAcceleration(start.y, stopLocation.y, startVelocity.y, endVelocity.y) 
 
    }; 
 

 
    obj.pos = Object.create(start); 
 
    obj.startVelocity = startVelocity; 
 
    obj.velocity = Object.create(startVelocity); 
 
    obj.stopLocation = stopLocation; 
 
    obj.destVelocity = endVelocity; 
 
    obj.acceleration = acceleration; 
 
    
 
    frame(); 
 
} 
 

 
start();
#canvas{ 
 
    background-color:black; 
 
}
<canvas id="canvas" width="700" height="700"></canvas>

: 여기

http://jsfiddle.net/x7842xcb/3/


그리고

var canvas = document.getElementById('canvas'); 
 
var test = document.getElementById('test'); 
 
var ctx = canvas.getContext('2d'); 
 

 
function drawDot(color, x, y) { 
 
    ctx.fillStyle = color; 
 
    ctx.fillRect(x - 2, y - 2, 4, 4); 
 
} 
 

 
function draw() { 
 
    ctx.clearRect(0, 0, canvas.width, canvas.height); 
 

 
    drawDot("red", obj.pos, obj.height); 
 
    drawDot("white", obj.start, obj.height); 
 
    drawDot("green", obj.dest, obj.height); 
 
    drawDot("yellow", obj.start + obj.stopDist, obj.height); 
 

 
    ctx.fillText("x = " + obj.pos.toFixed(5), 20, 400); 
 
    ctx.fillText("v = " + obj.velocity.toFixed(5), 20, 420); 
 
    ctx.fillText("distance traveled: " + (obj.pos - obj.start).toFixed(2), 20, 440); 
 
} 
 

 
var obj = { 
 
    start: 10, 
 
    height: 200, 
 
    stopDist: 300, 
 
    dest: 500, 
 
    lastTime: new Date().getTime(), 
 
    velocity: 0.05, 
 
    destVelocity: 0.01, 
 
    pos: undefined, 
 
    acceleration: undefined 
 
}; 
 

 
function frame() { 
 
    var t = new Date().getTime(), 
 
     tDelta = t - obj.lastTime; 
 
    obj.lastTime = t; 
 

 
    obj.pos += obj.velocity * tDelta; 
 
    if (obj.velocity > obj.destVelocity) { 
 
     obj.velocity += obj.acceleration * tDelta; 
 
    } 
 

 
    draw(); 
 

 
    setTimeout(frame, 1); 
 
} 
 

 
function start() { 
 
    var v0 = obj.velocity, 
 
     vf = obj.destVelocity, 
 
     x0 = obj.start, 
 
     xf = x0 + obj.stopDist, 
 
     vDelta = vf - v0; 
 

 
    obj.pos = x0; 
 
    obj.acceleration = (2 * v0 * vDelta + vDelta * vDelta)/(2 * (xf - x0)); 
 

 
    frame(); 
 
} 
 

 
start();
#canvas{ 
 
    background-color:black; 
 
}
<canvas id="canvas" width="700" height="700"></canvas>
는 2D 버전 (감수)입니다 나는 사실 이후 수정에 대해서는 617,451,515,

http://jsfiddle.net/1r3q4oob/3/

편집 :

내 원래의 구현은 현재 속도의 X와 Y 두 구성 요소가 있다면 그것은 단지 속도를 업데이트 할 것이라고했다과 문제 목표 속도보다 크다.이것은 올바른 동작을 방해하는 경우 :

  • 는 X 또는 시작 및 종료 속도 모두의 Y 구성 요소였다 0 (즉 완벽하게 수평 또는 수직으로 이동 된 경우)
  • 시작의 X 또는 Y 구성 요소 최종 속도는 음성이었다 (즉 왼쪽으로는 최대 여행 한 경우) 감소보다는 증가하는 데 필요한
  • 속도 (즉, 도트 이 목표 속도에을 가속화했다)

내가 해결 이것과 함께 reached() 함수의 추가는 기본적으로 (a) 목적지 속도가 이면 사이에서 현재의 속도와 시작 속도 (즉, 현재 속도가 목적지 속도를 지나쳤습니다.), 또는 (b) 현재 속도가 목적지 속도와 같습니다.

+0

jsFiddle에서 작업하고 있습니다. 그러나 어떤 이유로 내 웹 사이트에 구현할 때'velocity.x> destVelocity.x'가'false'인지 확인해야합니다. 그러나 'y 축'의 경우 '참'입니다. 즉 가속을 사용하여 속도를 변경하지 않습니다. 왜 그런지 모르겠지만 목표 속도는 시작 속도보다 낮게 설정됩니다. =/내가 잘못 될 수도있는 곳을 볼 수 있도록 붙여 넣기 파일에 코드를 표시 할 수 있습니까? – Sir

+0

좋아, 나는 파고를했는데 경로가 예를 들어 목적지와 시작 x 또는 y가 같은 직선 축에 있다면 문제가있다. 예 : http://jsfiddle.net/8kzptxus/ 속도에 변화가 없음을 확인하십시오. – Sir

+0

수정되지 않은 예제 코드에서도 시도해 보았습니다. http://jsfiddle.net/au5ht6oh/ 속도가 변경되지 않았습니다. – Sir