XNA Creators Club Online
Page 1 of 1 (8 items)
Sort Posts: Previous Next

Need Help...Rotate a vector to point toward a position

Last post 03-25-2008 7:40 PM by Ashour. 7 replies.
  • 03-24-2008 9:55 PM

    Need Help...Rotate a vector to point toward a position

    Hello community.  I have a question that I hope someone can answer.  Does anyone know how to rotate a vector so that it points towards a position in 3D space?

    For example let's say I have a ray with a unit-length vector direction pointing down the positive Z-axis and an origin at (0, 0, 0).  Let's also say I have an object positioned at (25, 10, 35).  How can I rotate the normalized vector of the ray so that it is pointing directly at the object?

    Any help would be greatly appreciated.

  • 03-25-2008 3:17 AM In reply to

    Re: Need Help...Rotate a vector to point toward a position

    Assume you have two Vector3 variables called viewpoint (representing the position of the viewer) and target (representing the position of the target). The directional vector from the viewpoint to the target is then simply calculated as (target - viewpoint). You can then normalize the result and assign it to the ray's direction.

    Therefore, with the example you gave, the viewpoint would be (0,0,0) and the target is (25,10,35). So the direction would be (25,10,35) - (0,0,0) which equals (25,10,35). Just normalize this result and assign it to the ray.

  • 03-25-2008 9:52 AM In reply to

    Re: Need Help...Rotate a vector to point toward a position

    My motivation for asking my question was that I had a 3D character that was facing in a specific direction and I want that character to be able to rotate to look at a target position.  I used the ray as an example where the ray's origin marked the characters position and the ray's direction marked where the character was facing.

    My goal is to rotate the character from its current direction to a new one.

  • 03-25-2008 11:19 AM In reply to

    Re: Need Help...Rotate a vector to point toward a position

    Answer

    I figured it out.  My solution was to take the three vectors of interest and use a little bit of trig to find the result.  By taking the direction the object is currently facing and by taking the direction between the object's position and its target position you can find the cross product (normalized) which will act as the rotation axis.  The angle to rotate to turn the object's original direction to face its target is then:

     

    double angle = Math.Acos((double)Vector3.Dot(obj.Direction,
    vecToTarget));

     

    Therefore to find the axis of rotation and the angle that is to be used to cause an object to face a target position you can use the following:

     

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    // Assume Position and Direction returns a Vector3 object.
    Vector3 vecToTarget = Vector3.Normalize(target.Position -
    obj.Position);
    double angle = Math.Acos((double)Vector3.Dot(obj.Direction,
    vecToTarget));
    Vector3 axisToRotate = Vector3.Cross(obj.Direction,
    vecToTarget);
    axisToRotate.Normalize();
    Matrix rotationMatrix = Matrix.CreateFromAxisAngle(axisToRotate,
    (float)angle);

     

    Alternatively you can create a quaternion to rotate.  One thing to note is that you will have to avoid situations where vectors are (0, 0, 0) to avoid NaN returns from normalization.  Other than that this works fine in my sample program.

  • 03-25-2008 11:45 AM In reply to

    Re: Need Help...Rotate a vector to point toward a position

    If you want a unit vector pointing from 0,0,0 toward a point in space (e.g., 25,10,35) all you would need to do, I believe, is

    Vector3 Direction_to_point = Vector3.Normalize(new Vector3(25,10,35) );

    [edit] or, yeah, just do what kyle says above..

    Best,

    Byron

    ..shaders make you feel... powerful, or very very stupid.
    http://drjbn.spaces.live.com/
  • 03-25-2008 3:16 PM In reply to

    Re: Need Help...Rotate a vector to point toward a position

    The problem is not as simple as "just subtract one from the other."
    Also, the problem does not require trig.
    Here is a different statement of the same problem:
    "I have an arrow/ship/character that is built to point down the Z axis when in Identity rotation at position P. How do I rotate it so that it points at object O, with up axis U ?"
    The actual math involved, as long as O is not linearly dependent with U, is simple.
    1) Create the vector D = (O-P).
    2) Create the vector U cross D, and normalize. Call this "Right"
    3) Create the vector Right cross U and normalize. Call this "Backwards"
    4) Create the vector Backwards cross Right. Call this "Up"
    4) Your matrix is now these three vectors written in rows (assuming row vectors on the right):

    // O is your object's position
    // P is the position of the object to face
    // U is the nominal "up" vector (typically Vector3.Y)
    // Note: this does not work when O is straight below or straight above P
    Matrix RotateToFace(Vector3 O, Vector3 P, Vector3 U)
    {
    Vector3 D = (O - P);
    Vector3 Right = Vector3.Cross(U, D);
    Vector3.Normalize(ref Right, out Right);
    Vector3 Backwards = Vector3.Cross(Right, U);
    Vector3.Normalize(ref Backwards, out Backwards);
    Vector3 Up = Vector3.Cross(Backwards, Right);
    Matrix rot = new Matrix(Right.X, Right.Y, Right.Z, 0, Up.X, Up.Y, Up.Z, 0, Backwards.X, Backwards.Y, Backwards.Z, 0, 0, 0, 0, 1);

    If your object is modeled pointing down some axis other than positive Z, you can pre-multiply the matrix that turns the model around to face Z, and then multiply this matrix, to get the final orientation matrix.

    What this does, geometrically, is:
    * Assuming the Z axis will be pointing at the object
    * Using the nominal "up" to find where the "right" (X) axis will point. This means that the above/below positions won't work, because "right" could be anything.
    * Using the calculated Z and X axes, calculate the actual "up" (Y) axis that's aligned with the initial up, but creates an orthogonal coordinate space.
    That in turn gets turned into a matrix, which ends up being the matrix you use to rotate the object.

    Math is Cool!

    Jon Watte, Direct3D MVP kW X-port 3ds Max .X exporter kW Animation source code
  • 03-25-2008 4:20 PM In reply to

    Re: Need Help...Rotate a vector to point toward a position

    Thanks for the information.  I'll definitely try this out later.
  • 03-25-2008 7:40 PM In reply to

    Re: Need Help...Rotate a vector to point toward a position

    I used once the TurnToFace function in the aiming sample but it didn't work quite well in other stuff so i used the following function provided by "Gnome Hero" and it worked great note: i mainly used it to turn an arrow towards a checkpoint so am not sure if it gonna work with you.

    it was not in the following form but i converted it to static form

            /// <summary>
    /// The effective code in the following method was made by Gnome Hero.
    /// it should return a matrix of an arrow pointing to a specific 3D point
    /// </summary>
    /// <param name="ArrowPosition">The position of the arrow</param>
    /// <param name="TargetPosition">The target which the arrow should point to</param>
    /// <returns></returns>
    public static Matrix ArrowMatrix(Vector3 ArrowPosition, Vector3 TargetPosition)
    {
    Vector3 tminusp = TargetPosition - ArrowPosition;
    Vector3 ominusp = Vector3.Backward;
    tminusp.Normalize();
    float theta = (float)System.Math.Acos(Vector3.Dot(tminusp, ominusp));
    Vector3 cross = Vector3.Cross(ominusp, tminusp);

    cross.Normalize();

    Quaternion targetQ = Quaternion.CreateFromAxisAngle(cross, theta);
    Matrix WorldMatrix = Matrix.CreateFromQuaternion(targetQ)* Matrix.CreateTranslation(ArrowPosition);

    return WorldMatrix;
    }
     
    Hope that helps.
    Ashour
Page 1 of 1 (8 items) Previous Next