What is a good technique to enable an object to move between to points in a nice curved motion?
The end position could also be in motion, such as the trajectory of a homing missile.
Answer
Assuming you want this to be a frame-by-frame thing (where the target could even be moving), and not a precomputed trajectory, this is actually incredibly simple:
Every frame, compare the velocity-vector of the missile to the vector (positiontarget - positionmissile); that is, the vector pointing from the missile to the target. Every frame, if the two vectors do not have the same direction, then rotate the veloity-vector a little bit towards the other vector, so every frame the missle gets a little bit closer to looking at its target.
You can determine whether to rotate clockwise or counter-clockwise by looking at the sign of the cross-product between the two vectors.
[Edit] XNA-ish code (I don't have XNA to test this):
//Once a frame:
//Get vector spanning from missile to target
Vector2 vectorToTarget = target.Position - missile.Position;
//Convert to Vector3 to do cross-product
Vector3 vectorToTarget3 = new Vector3(vectorToTarget, 0);
Vector3 missileVelocity3 = new Vector3(missile.Velocity, 0);
//Rotate clockwise/counter-clockwise is determined by sign of cross-product
int crossProductSign = Vector3.Cross(missileVelocity3, vectorToTarget3).Z;
//Positive cross-product means rotate counter-clockwise, negative is clockwise
double rotationAngle = 0;
if(crossProductSign > 0)
rotationAngle = -0.05;
else if(crossProductSign < 0)
rotationAngle = 0.05;
//I'm not sure how to do rotation in XNA, but the internets tell me it's something like this:
missile.velocity = Vector2.Transform(missile.velocity, Matrix.CreateRotationZ(rotationAngle))
Note that, because rotationAngle
has only three possible values, all possible values of Matrix.CreateRotationZ(rotationAngle)
can be cached so you don't have to call it every frame.
No comments:
Post a Comment