问题
I want to rotate a P3 (that is somewhere near) around a vector (that intersects P1 and P2) by x degrees.
P1 and P2 are 2 points that are intersected by vector(line) e from image. I've researched and searched a lot and found some good materials, but my trigonometry skills are so poor. I need this for PAWN (small), here i have some code, but doesn't really work as intended. If anyone can help me, i'll be very thankful :)
Image link: http://upload.wikimedia.org/wikipedia/commons/thumb/5/51/Euler_AxisAngle.png/220px-Euler_AxisAngle.png
P1 / P2 / P3 = (x,y,z)
float vec[3];
SubtractVectors(P1, P2, vec);
float newp[3];
float rotation[4][4];
SetupMatrix(90.0, vec, rotation);
MultiplyMatrix(P3, rotation, newp);
//---------------------------------
stock void MultiplyMatrix(float input[3], float rotation[4][4], float output[3])
{
float input2[4];
input2[0] = input[0];
input2[1] = input[1];
input2[2] = input[2];
input2[3] = 1.0;
float output2[4];
for(int i = 0 ; i < 4 ; i++)
{
for(int j = 0 ; j < 4 ; j++)
{
output2[i] += rotation[i][j] * input2[j];
}
}
output[0] = output2[0];
output[1] = output2[1];
output[2] = output2[2];
}
stock void SetupMatrix(float angle, float vector[3], float rotation[4][4])
{
float L = (vector[0] * vector[0] + vector[1] * vector[1] + vector[2] * vector[2]);
angle = angle * M_PI / 180.0;
float u2 = vector[0] * vector[0];
float v2 = vector[1] * vector[1];
float w2 = vector[2] * vector[2];
rotation[0][0] = (u2 + (v2 + w2) * Cosine(angle)) / L;
rotation[0][1] = (vector[0] * vector[1] * (1 - Cosine(angle)) - vector[2] * SquareRoot(L) * Sine(angle)) / L;
rotation[0][2] = (vector[0] * vector[2] * (1 - Cosine(angle)) + vector[1] * SquareRoot(L) * Sine(angle)) / L;
rotation[0][3] = 0.0;
rotation[1][0] = (vector[0] * vector[1] * (1 - Cosine(angle)) + vector[2] * SquareRoot(L) * Sine(angle)) / L;
rotation[1][1] = (v2 + (u2 + w2) * Cosine(angle)) / L;
rotation[1][2] = (vector[1] * vector[2] * (1 - Cosine(angle)) - vector[0] * SquareRoot(L) * Sine(angle)) / L;
rotation[1][3] = 0.0;
rotation[2][0] = (vector[0] * vector[2] * (1 - Cosine(angle)) - vector[1] * SquareRoot(L) * Sine(angle)) / L;
rotation[2][1] = (vector[1] * vector[2] * (1 - Cosine(angle)) + vector[0] * SquareRoot(L) * Sine(angle)) / L;
rotation[2][2] = (w2 + (u2 + v2) * Cosine(angle)) / L;
rotation[2][3] = 0.0;
rotation[3][0] = 0.0;
rotation[3][1] = 0.0;
rotation[3][2] = 0.0;
rotation[3][3] = 1.0;
}
回答1:
look at quaternions they do exactly what you need. if you do not use them like me then:
construct transform matrix
M
representing your rotational axis coordinate systemfirst look here: transform matrix anatomy. For example origin is the point
P1
SoX
axis isP2-P1
(rotation axis). LetQ = (1.0,0.0,0.0)
or(0.0,1.0,0.0)
choose one that is not parallel toX
axis vector soX = P2-P1 Q = (1.0,0.0,0.0) or (0.0,1.0,0.0) Y = cros(X,Q) Z = cros(X,Y)
now you can negate axises or change their cross product operands order to match the axises direction you need (if desired). Also do not forget to make all the axises unit vectors
so now do local coordinate system (LCS) rotation
look here LCS transforms and here LCS rotation around X axis lrotx C++ implementation search for
lrotx
at the end of answerso now
take GCS point
P
you want to rotate get its LCS coordinates (for unrotated transform matrixM
)Q = inverse(M)*P // if `M` before rotation was one then you can do Q=P instead
rotate:
M = inverse(inverse(M)*rotation)
convert
Q
back to GCSQ = M*Q
that it is all ...
[Notes]
if you have wrong rotation direction then just negate one of the axises ... or use negated angle
来源:https://stackoverflow.com/questions/26561355/rotate-point-around-vector-3d