Jump to content
  • Advertisement
Sign in to follow this  
jsg007

How to transform (rotate) an object with an orientation vector?

This topic is 2830 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hello,

Does anybody know how could I create a transformation(rotation) matrix for an object, by only using an orientation vector?

I need this to make my object always face a specific point ( the input vector would be the normalized direction ).

Thanks!

Share this post


Link to post
Share on other sites
Advertisement

Hello,

Does anybody know how could I create a transformation(rotation) matrix for an object, by only using an orientation vector?

I need this to make my object always face a specific point ( the input vector would be the normalized direction ).

Thanks!



This problem is underspecified without another vector - most people use the world up vector but this will lead to gimble lock when looking up :)

Cheers, Paul.

Share this post


Link to post
Share on other sites

most people use the world up vector but this will lead to gimble lock when looking up

That's not gimbal lock. (But, you're right that the method in question can fail when the view and reference vectors are parallel or nearly parallel.)

@The OP: Is this essentially a 2-d problem? That is, are the two objects in the same plane and generally 'upright' with respect to some frame of reference?

Share this post


Link to post
Share on other sites

[quote name='wildbunny' timestamp='1299711087' post='4783757']
most people use the world up vector but this will lead to gimble lock when looking up

That's not gimbal lock. (But, you're right that the method in question can fail when the view and reference vectors are parallel or nearly parallel.)

@The OP: Is this essentially a 2-d problem? That is, are the two objects in the same plane and generally 'upright' with respect to some frame of reference?
[/quote]

Sorry for the late reply. I actually want to place trees and plants on a heightmap, but they don't look very well sitting all up straight, especially on steep angles; I want them to face the normal of the heightmap... but I have no idea how can I construct a transformation matrix for this.

Share this post


Link to post
Share on other sites

[quote name='jyk' timestamp='1299724520' post='4783825']
[quote name='wildbunny' timestamp='1299711087' post='4783757']
most people use the world up vector but this will lead to gimble lock when looking up

That's not gimbal lock. (But, you're right that the method in question can fail when the view and reference vectors are parallel or nearly parallel.)

@The OP: Is this essentially a 2-d problem? That is, are the two objects in the same plane and generally 'upright' with respect to some frame of reference?
[/quote]

Sorry for the late reply. I actually want to place trees and plants on a heightmap, but they don't look very well sitting all up straight, especially on steep angles; I want them to face the normal of the heightmap... but I have no idea how can I construct a transformation matrix for this.
[/quote]


Are you sure?

Have a look at some landscape pictures containing trees in the real world - they don't stick out like that, they point up :)




Share this post


Link to post
Share on other sites

but I have no idea how can I construct a transformation matrix for this.

Leaving aside the question of which direction the objects should be oriented, here's how you can (robustly) construct a basis from a single direction vector:

- Find the element (x, y, or z) of the direction vector with the smallest absolute value

- Take the cross product of the direction vector and the cardinal basis vector corresponding to this element (for example, if direction.x has the smallest absolute value, you would cross with (1, 0, 0))

- Normalize the result to yield the second basis vector

- Compute the third basis vector as the cross product of the first (the direction vector) and second basis vectors

Not sure if I got all the steps right, but it should be close. This method isn't suitable for all applications, but it's a good choice for building an arbitrary orientation from a direction vector when it only needs to be done once, since the results are guaranteed to be valid regardless of how the input vector is oriented.

Share this post


Link to post
Share on other sites
Hi, if you have two vectors A and B. You want to find a rotation, about an angle alpha around and axis R, of A such as A is aligned with B.

the angle alpha is obtain from the dot product definition:

alpha = acos( A . B / |A||B| )

And the axis R by the cross product:

R = normalized( A x B )

Share this post


Link to post
Share on other sites
An absolutely easy though not the cheapest method is to build a quaternion from your direction vector and the angle you want to turn. Then get the matrix equivalent to this quaternion. There are plenty of sources (wikipedia) where you can get directly these formulas.

Also you can rotate directly with the quaternion:



//quaternion multiplication
function quat_mult(Quaternion q1, Quaternion q2)
{
result.a = (q1.a*q2.a -q1.b*q2.b -q1.c*q2.c -q1.d*q2.d)
result.b = (q1.a*q2.b +q1.b*q2.a +q1.c*q2.d -q1.d*q2.c)
result.c = (q1.a*q2.c -q1.b*q2.d +q1.c*q2.a +q1.d*q2.B)
result.d = (q1.a*q2.d +q1.b*q2.c -q1.c*q2.b +q1.d*q2.a)
return result
}

//Quaternion multiplication without the .a component
function quat_pointmult( Quaternion q1, Quaternion q2)
{
result.x = (q1.a*q2.b +q1.b*q2.a +q1.c*q2.d -q1.d*q2.c)
result.y = (q1.a*q2.c -q1.b*q2.d +q1.c*q2.a +q1.d*q2.B)
result.z = (q1.a*q2.d +q1.b*q2.c -q1.c*q2.b +q1.d*q2.a)

return result
}

//Uses quaternion mathematics to perform a rotation
function quat_rot(Point point,Point rotVec,real angle)
{
real sinCoeff
Quaternion rotQuat
Quaternion pointQuat
Quaternion conjQuat
Quaternion temp

sinCoeff=sin(angle*0.5)

rotQuat.a = cos(angle*0.5)

rotQuat.b=sinCoeff*rotVec.x
rotQuat.c=sinCoeff*rotVec.y
rotQuat.d=sinCoeff*rotVec.z

pointQuat.a =0
pointQuat.b = point.x
pointQuat.c = point.y
pointQuat.d = point.z
//calculate conjugate of the quaternion
conjQuat.a = rotQuat.a
conjQuat.b = -rotQuat.b
conjQuat.c = -rotQuat.c
conjQuat.d = -rotQuat.d

//perform rotation
temp=quat_mult(rotQuat,pointQuat)
point=quat_pointmult(temp,conjQuat)

return point
}


Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!