0

Greetings, With javascript, I am trying to make a very easy animation, an image moves from one X and Y coordination to another X Y coordination. I have 4 constant such as:

var startX = 0; //starting X of an image
var startY = 0; //starting Y of an image
var endX = 100; //ending X of an image
var endY = 200; //ending Y of an image

//these 2 are used for keeping the "current" position of animated image, 
var currentX = startX ;
var currentY = startY ;

//every 150 ms, updates the location of the coordinates
function move(){

if( (currentX == endX) && (currentY == endY) )
break;

if(currentX  < endX){
currentX  = currentX  + step_amount;
}

if(currentX  > endX){
currentX  = currentX  - step_amount;
}

if(currentY < endY){
currentY = currentY + step_amount;
}

if(currentY > endY){
currentY = currentY - step_amount;
}
setInterval("move()", 150);
}

This does the job, however it is not smooth, I will be grateful if you help me improve my naive algorithm for a better move function that is always going for the "shortest path".

Svante
  • 50,694
  • 11
  • 78
  • 122
  • How do you set/calulate step_amount, and shouldn't you have different step values for x and y dimensions if you want to move in a straight line? – Lars Haugseth Jun 29 '09 at 09:33
  • Change the last line to setInterval(move, 50). It will be three times smoother. – scvalex Jun 29 '09 at 09:35

5 Answers5

2

Sounds like you need (a variation of) the Bresenham line drawing algorithm.

H H
  • 263,252
  • 30
  • 330
  • 514
1

The shortest distance between two points is a straight line. So you should probably move along that.

What that would imply is that in your code, you should not use the same step amount for both X and Y coordinates. Instead compute Y step based on X step and the slope of the shortest path line.

slope = (startY - endY) / (startX - endX);
Y_step = X_step * slope;

Secondly, in your current algorithm, once your image reaches the destination point, it'll continue to oscillate about it. I think you should get rid of the statements that take a negative step.

G S
  • 35,511
  • 22
  • 84
  • 118
0

Since you are always moving two coordinates together, you only need to check against one of them, e.g.

if (currentX < endX) {
    currentX += xStep;
    currentY += yStep;
}
rtn
  • 127,556
  • 20
  • 111
  • 121
0

Try something like this to move the object in a straight line:

var numberOfSteps = 100;
var stepDX = (endX - startX) / numberOfSteps;
var stepDY = (endY - startY) / numberOfSteps;
var step = 0;

Inside the move() function:

if (step <= numberOfSteps) {
    currentX = startX + stepDX * step;
    currentY = startY + stepDY * step;
    step++;
}

Cast currentX/currentY to integer before applying to the object you want to move.

Lars Haugseth
  • 14,721
  • 2
  • 45
  • 49
0

This is my implementation, many thanks to Frederik The Fool

Compute slope:

if(this.x === target.x){
    this.slope = 1;
}else{
    this.slope = (this.y - target.y)/(this.x - target.x);
}

Ystep:

if(this.y > this.target.y){ 
    this.y = Math.max(this.target.y, this.y - Math.abs(this.slope * distance));
}else if(this.shape.y < this.target.y){
    this.y = Math.min(this.target.y, this.y + Math.abs(this.slope * distance));
}
Carl Bosch
  • 1,281
  • 16
  • 14