Re: Rotate a 3D vector
by FoxtrotUniform (Prior) on Oct 17, 2004 at 23:58 UTC

Here's the short version: multiply your source vector by a 3d rotation matrix. Zaxo's snippet is nifty, but not quite sufficient as it doesn't do matrix math.
The extra complexity that comes with moving from 2d rotations to 3d rotations is the fact that, in 3d, you don't really have a canonical axis to rotate around. In the xy plane, when you do a rotation by r radians, you pretty much have to rotate around the z axis. In 3d space, you can rotate around the x, y, or z axis, or around an arbitrary vector (if that gives you problems, think of it as rotating around several canonical axes at once). So you can't easily describe a 3d rotation with a single parameter; you basically need a matrix (or a quaternion, but let's not go there).
 [reply] 
Re: Rotate a 3D vector
by Anonymous Monk on Oct 18, 2004 at 08:55 UTC

R_{X}=
 1
 0
 0
 0
 cos φ
  sin φ
 0
 sin φ
 cos φ

R_{Y}=
 cos θ
 0
 sin θ
 0
 1
 0
 0
 sin θ
 cos θ

R_{Z}=
 cos ψ
 sin ψ
 0
 sin ψ
 cos ψ
 0
 0
 0
 1

Then your rotation matrix is R_{X} * R_{Y} * R_{Z}, with θ the amount of rotation around the X axis, φ the amount of rotation around the Y axis, and ψ the amount of rotation around the Z axis.
 [reply] 

Sorry for bumping an old thread.. i hope this saves a bit of someones time: Ry is wrong, it should be:
cos(th) 0 sin(th)
0 1 0
sin(th) 0 cos(th)
rgds,
Mitja  [reply] [d/l] 

how do you find the angles è, ö, and ø between two vectors?
 [reply] 

To find the angle between the two vectors, you need to normalize them (so they have length of 1 unit) by doing this (v is the vector you want to normalize):
float distance = sqrt(v.x*v.x + v.y*v.y + v.z*v.z);
v.x = v.x/distance;
v.y = v.y/distance;
v.z = v.z/distance;
Then find the dot product of the two normalized vectors (Va and Vb):
float dotProduct = Va.x*Vb.x + Va.y*Vb.y + Va.z*Vb.z;
This gives you the cosine of the angle, so simple do:
acos(dotProduct);
This will give you the angle. I think this post was a bit late :S  [reply] [d/l] [select] 
Re: Rotate a 3D vector
by itub (Priest) on Oct 18, 2004 at 13:14 UTC

 [reply] 
Re: Rotate a 3D vector
by true (Pilgrim) on Oct 18, 2004 at 00:44 UTC

The program i am writing is generating sinewave based seaweed and kelp plants for povray. I wanted to rotate my vector points around a simple y axis, but can't get a concrete example to get started. The sine wav part is done though:) I do not want to use povray to rotate because i want to output to obj file which means i need real coordinates not translated. Any chance you can show me in perl code how to rotate a vector around a single axis? thanks for help.
 [reply] 
Re: Rotate a 3D vector
by true (Pilgrim) on Oct 18, 2004 at 02:59 UTC

Back to the trenches with me. I'm starting with a 2d space till i can wrap my head around it. The code and examples i am finding are not matching up in 3d space. Here's my closest attempt which still is wrong. Can anyone help?
# 2 points on a plane
my $x = 2;
my $y = 1;
#yang is the yangle 0360 i want to rotate by
my $yang = 45;
#convert yang to radians
$yang = 3.14159265358979*$yang/180;
#rad is the radius of my sphere
my $rad = sqrt($x**2 + $y**2);
my $x = cos($yang)*$rad;
my $y = sin($yang)*$rad;
print "x=$x\ny=$y\n";
Advice appreciated.
 [reply] [d/l] 

Just a little change, the formula was not correct (as I pointed out in my previous post in this thread)
# 2 points on a plane
my $x = 2;
my $y = 1;
#yang is the yangle 0360 i want to rotate by
my $yang = 45;
#convert yang to radians
$yang = 3.14159265358979*$yang/180;
my $xnew = cos($yang)*$x  sin($yang)*y;
my $ynew = sin($yang)*$x + cos($yang)*y;
print "x=$xnew, y=$ynew\n";
 [reply] [d/l] 
Re: Rotate a 3D vector
by true (Pilgrim) on Oct 18, 2004 at 00:02 UTC

Clarification then. i only need to rotate the vector on the z axis. So the 3dvector point 3 1 3 is rotated 23 degrees on the z axis only. Any help?
 [reply] 

sub rotate {
my ( $x,$y,$z,$angle ) = @_;
$angle = deg2rad($angle);
my $x_new = cos($angle)*$x  sin($angle)*$y;
my $y_new = sin($angle)*$x + cos($angle)*$y;
return $x_new, $y_new, $z;
}
sub deg2rad { return 3.14159265358979*$_[0]/180 };
Here is a nice article with a pretty applet Update Corrected error noted by johnnywang
 [reply] [d/l] 

The beauty of concrete! Thanks so much for a perfect example tachyon.
Also, a good page about the topic: 2D Math
 [reply] 

just want to point out it's not quite right. You need to first find the polar angle for the original point (x,y), then add the $angle to that for the new polar angle.
Updated. I'm only refering to the geometric meaning. There is a formula: multiplying by the rotation matrix given by ((cos, sin),(sin, cos)) (not perl notation!)
 [reply] 

Well, the quickanddirty way to do it is to scale your x component by cos(t) and your y component by sin(t). You might be happier with a matrixbased solution in the long run, though.
Edit: The math above is, of course, totally bogus. I plead momentary imbecility. johnnywang has the correct solution. D'oh!
What kind of program are you writing, btw?
 [reply] 
Re: Rotate a 3D vector
by Anonymous Monk on Oct 18, 2004 at 07:31 UTC

How would you do this by hand?
 [reply] 