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

Orienting Objects Along a Line in 3D Space

Last post 8/3/2009 1:00 AM by siferion. 4 replies.
  • 7/29/2009 8:07 AM

    Orienting Objects Along a Line in 3D Space

    Given a line between two Vector3 endpoints, how can I calculate the angle of that line so I can set the orientation of objects along it's length?

    I want something along the lines (ho ho) of a chain or segmented rope.
  • 7/29/2009 9:38 AM In reply to

    Re: Orienting Objects Along a Line in 3D Space

    EssAitch:
    Given a line between two Vector3 endpoints, how can I calculate the angle of that line so I can set the orientation of objects along it's length?

    I want something along the lines (ho ho) of a chain or segmented rope.

    If your two points are A and B, (B-A).Length() gives you the distance between the two points, and Vector2.Normalize(B-A) gives you the direction vector between the two points. Given these two values you can step along the line at a given rate and place objects or draw bitmaps.

    To compute a rotation value so that objects appear to be facing along the path of the line, you can use the Math.Atan2(y, x) function to compute an angle based on the direction vector.
    Kevin Gadd, Squared Interactive
    Development Blog | Twitter
    Help playtest my game, Inferus!
  • 7/31/2009 2:37 PM In reply to

    Re: Orienting Objects Along a Line in 3D Space

    Atan2 works great for 2D but the question is in 3D.

    3D requires up to 3 angles to be computed.
    I have handled this a couple different ways depending on my needs at the time.
    The 'simplest' is to use Atan2 but you need to calculate two angles (One along the horizontal 'ground' plane, and one along the vertical)

    So, assuming you are using xna-space (z-x is the ground plane, y is 'up') you can do something like this

    Vector3 A,B,deltaAB;//set A,B how ever you need
    deltaAB=B-A;
    float horizontalAngle=(float)Math.ATan2(deltaAB.X,deltaAB.Z);

    //to calculate the vertical angle use the length of the ground component of deltaAB and deltaAB.Z
    Vector3 deltaAB_Ground=deltaAB;
    deltaAB_Ground=0;//make flat
    float verticalAngle=(float)Math.ATan2(deltaAB.Z,deltaAB_Ground.Length());

    one way to use these angles (depending on how you want to define your rotations) is

    Matrix horTransform=Matrix.CreateRotationY(horizontalAngle);
    Matrix verTransform=Matrix.CreateRotatoinZ(verticalAngle);//this could be CreateRotationX instead depending on which 'vertical' rotatoin you want.



    the other method flows simialr to this (and again it depends on your particular needs):

    Vector3 A,B,deltaAB,unitAB;
    deltaAB=B-A;
    unitAB=Vector3.Normalize(deltaAB);

    Matrix transform=Matrix.CreateWorld(new Vector3(0,0,0),unitAB,new Vector3(0,1,0));//this will give you a single matrix that applies a rotation on all 3-axis based on the direction of unitAB. Also allows for a translation and definiation of 'up'

    code with pride, not ego!
  • 8/2/2009 9:38 PM In reply to

    Re: Orienting Objects Along a Line in 3D Space

    Thanks all.

    After a fair amount of searching and head scratching I settled on a solution that uses the dot and cross products of the two vectors to get a rotation matrix.

     
            /// <summary> 
            /// Create a rotation matrix to align one vector with another. 
            /// </summary> 
            /// <param name="movableVector">Must be normalised.</param> 
            /// <param name="targetVector">Must be normalised.</param> 
            /// <returns>A rotation matrix</returns> 
            public static Matrix Align(Vector3 movableVector, Vector3 targetVector) 
            { 
                Vector3 rotAxis = Vector3.Cross(movableVector, targetVector); 
                float theta = (float)Math.Acos((double)Vector3.Dot(movableVector, targetVector)); 
     
                return Matrix.CreateFromAxisAngle(rotAxis, theta); 
            } 
     

  • 8/3/2009 1:00 AM In reply to

    Re: Orienting Objects Along a Line in 3D Space

    Well an alternative to solving it, assuming your target vector is end - start.

    float yaw = (float)Math.Atan(targetVector.X / targetVector.Y); 
    if (targetVector.X < 0) 
        yaw += MathHelper.Pi; 
     
    float pitch = (float)Math.Asin(targetVector.Y); 
    if ((targetVector.X > 0 && targetVector.Z > 0) || (targetVector.X < 0 && targetVector.Z < 0)) 
         pitch = MathHelper.Pi - pitch; 
     
    // this part could just as easily be Matrix, I just prefer quaternions for rotations 
    Quaternion rotation = Quaternion.CreateFromYawPitchRoll(yaw, pitch, 0f); 

    Now if you want to incorporate roll, you would need a second target vector representing a right facing vector from your start point.
Page 1 of 1 (5 items) Previous Next