View Full Version : Angle between 2 vectors
pixlix2 06-10-2006, 01:56 PM Hello everyone,
can anyone help me with a problem of calculating an angle between two vectors? There is a little catch, though. I don't think I can just use the dot product for this, because I need the angle rotation about one specified axis only.
http://i33.photobucket.com/albums/d60/pixlix/vectors.gif
I have the vectors A and B. Now I want to know how much I need to rotate vector A around the Y-axis until it aligns with vector B in this axis. I don't want to rotate A about the X or Z axis.
Why I want to do this:
I have a particle system with instanced "billboard"-planes that should always aim in the direction of an animated locator. But I can't use the build-in "aim" function of the instancer, because I only want to have the cards rotate about the Y-axis (there are people on the cards and it would not look too good if their feet would rotate away from the ground)
So I think I need to do this aim-constraint by hand by rotating each plane the right amount around the y-axis so they point to the locator...
Any help would be great!
Many thanks!
|
|
tciny
06-10-2006, 02:14 PM
If the y coordinate of both vectors is zero, then the dot product will be fine because the shortest rotation will always be around the y axis.
So I'd say... just set the y value of the vector pointing at the camera to 0 and calculate the direction between that and 0 0 1 and you should have the angle you need to rotate your plane by (if the plane is on the XY axis)
GennadiyKorol
06-10-2006, 02:29 PM
Yep, try calculating the angle between the projections of your vectors on XZ plane.
pixlix2
06-10-2006, 05:52 PM
Many thanks to both of you!
Sometimes the most obvious thing, like just setting the Y component to 0 doesn't come to my mind. Anyhow, it kind of works, but not really. But this has probably nothing to do with the Y-axis.
THe problem is, when I'm calculating the angle between the aim-axis vector (the aim direction of my billboard card) and the aim itself (the locator or a camera) I can get only values between 0 and 180 degrees. As soon the angle should get wider than 180, the "angle()" function calculates the angle from the opposite side. This is not so good for my purpose :)
Maybe someone has an idea what I could do? I made a little video to illustrate how the instances behave now:
video link (http://media.putfile.com/aim2)
// set aim axis to X
vector $aimAxis = <<1,0,0>>;
// get worldpos of locator and discard y ->set to 0
vector $myLoc = `xform -q -ws -t locator1`;
$myLoc = <<$myLoc.x,0,$myLoc.z>>;
// get worldpos of particle and discard y ->set to 0
vector $pPosition = particleShape1.worldPosition;
$pPosition = <<$pPosition.x, 0, $pPosition.z>>;
// I think I need to take the particle position (offset from the origin) into account
vector $aim = $myLoc - $pPosition;
//calculate angle and assign to custom rotation attribute
float $myAngle = `rad_to_deg(angle( $aimAxis,$aim))`;
particleShape1.myRotPP = <<0,$myAngle,0>>;
Pleaaase... have mercy upon me :)
tciny
06-10-2006, 08:28 PM
Rotate the vector by the angle, check the angle between that new vector and the view one. If it's not very close to zero, use the inverted angle.
pixlix2
06-11-2006, 01:55 PM
tciny, Du bist meine liebste Wurstfachverkäuferin! :D
Ok, I finally got it working. Even with all the great help it was pretty hard for a scripting newbie like me, but hey, I've learned alot!
//set aim axis to X
vector $aimAxis = <<1,0,0>>;
vector $rotAxis = <<0,1,0>>;
//get worldpos of locator and discard y ->set to 0
vector $myLoc = `xform -q -ws -t locator1`;
$myLoc = <<$myLoc.x,0,$myLoc.z>>;
//get worldpos of particle and discard y ->set to 0
vector $pPosition = particleShape1.worldPosition;
$pPosition = <<$pPosition.x, 0, $pPosition.z>>;
// I think I need to take the particle position (offset from the origin) into account
vector $aim = unit($myLoc - $pPosition);
//calculate angle and assign to custom rotation attribute
float $myDegAngle = angle( $aimAxis,$aim);
float $myAngle = `rad_to_deg($myDegAngle)`;
//check if angle is larger than 180 and use the inverse angle
vector $testRotate = `rot $aimAxis $rotAxis $myDegAngle`;
float $isFlipped = angle($testRotate,$aim);
if ($isFlipped > 0.0001)
$myAngle = (180 - $myAngle) + 180 ;
//finally assign the value to the custom attribute
particleShape1.myRotPP = <<0,$myAngle,0>>;
Thanks everyone!
CGTalk Moderation
06-11-2006, 01:55 PM
This thread has been automatically closed as it remained inactive for 12 months. If you wish to continue the discussion, please create a new thread in the appropriate forum.
vBulletin v3.0.5, Copyright ©2000-2012, Jelsoft Enterprises Ltd.