Simple Trig

I used to use spatial transformer to move some objects around, but i need to change how the units move around. 



How to move an object at a steady speed from point sourceX, sourceY to point targetX, targetY



The distance between the source and targets is straight forward  being being

FastMath.sqrt(FastMath.sqr(targetX - startX) + FastMath.sqr(targetY - startY))



The speed is constant and multiplied by the tpf, so can calculate how far the object has travelled each frame.

But how do I calculate what the new sourceX and sourceY is after each frame with the distance travelled.




well, target vector - source vector will give you a direction and distance vector. So with this distance vector you can scale it for how far you want to move by using speed and tpf. Then add this distance vector to you source vector and voila!

nymon said:

So with this distance vector you can scale it for how far you want to move by using speed and tpf.


Its the scaling it part that eludes me. ? How do i know what to scale the x, y, and z by ??

Well, if you store the start point than it's just a simple interpolation from point A to point B. If not, then you could define 'speed', say 1 jME unit per second, so the distance you WANT to travel is 'speed * tpf', we'll call this value 'dist'. Knowing the distance/direction vector from your current location to the destination (target - source), it is a simple division of 'dist / (target - source)' to get the fraction of movement along that vector, then multiply the result against your direction vector to get the actual movement.



Psuedo…



float speed = 1.0f;

Vector3f target = getTargetLocation();



update(float tpf) {



  float dist = speed * tpf;

  Vector3f direction = target - getCurrentLocation();



  Vector3f newLoc = (dist / direction) * direction;



  setLocation(newLoc);

}



Obviously you wouldn't want to create all those vectors every time, maybe use a class temp and make use of the *Local arithmetic functions of Vector3f. This should be mathematically correct.

Damn, darn and lost of little buggery bits.



Get the general idea of multiplying the dist ( distance travelled per frame ) by the scale of the point, that way it treats it like a ratio. Think the last beer has finally put the brain to sleep.



its the  line

Vector3f newLoc = (dist / direction) * direction;

dividing by direction and then multiplying it gives the same result.

Ill get a test case ready in the morning ----> sleeeeep


Vector3f newLoc = (dist / direction) * direction;



He means


Vector3f newLoc = direction.mult(dist/direction.length());



but it won't work as expected (I think)

EDIT:
It's better to use Vector3f.interpolate()

Thank you both for your help.



Solution posted for 2D scenario


public class TestMoveToPoint extends SimpleGame {
 
  private Sphere s;
  /**
   * Entry point for the test,
   * @param args
   */
  public static void main(String[] args) {
    TestMoveToPoint app = new TestMoveToPoint();
    app.setDialogBehaviour(NEVER_SHOW_PROPS_DIALOG);
    app.start();
  }
 
  float speed = 20.0f;
 
  float targetX = 30f;
  float targetZ = 195f;
 
  float originalPosX;
  float originalPosZ;
   
  float distRemaining;
  float distTravelled;
  float pctTravelled;
 
  protected void simpleUpdate() {    
    distTravelled = speed * tpf;
    distRemaining = getDistance(targetX, targetZ, s.getLocalTranslation().x, s.getLocalTranslation().z);
    
     if(distRemaining <= 0.01f) {
        s.getLocalTranslation().x = targetX;
        s.getLocalTranslation().z = targetZ;
        System.out.println("Arrived");
     } else {
        pctTravelled = 1/(distRemaining / distTravelled);
        s.getLocalTranslation().x = (1-pctTravelled) * s.getLocalTranslation().x + (pctTravelled * targetX);
        s.getLocalTranslation().z = (1-pctTravelled) * s.getLocalTranslation().z + (pctTravelled * targetZ);       
     }
  }

  public float getDistance(float targetX, float targetZ, float ax, float az) {
     return FastMath.sqrt(FastMath.sqr(targetX - ax) + FastMath.sqr(targetZ - az));
  }
 
 
  /**
   * builds the trimesh.
   * @see com.jme.app.SimpleGame#initGame()
   */
  protected void simpleInitGame() {
    s = new Sphere("Planet", 25, 25, 25);
    s.setModelBound(new BoundingSphere());
    s.updateModelBound();
    rootNode.attachChild(s);
    s.setLocalTranslation(10,10,10);
    originalPosX = s.getLocalTranslation().x;
    originalPosZ = s.getLocalTranslation().z;
   
  
  }
}