0

I come accross a math problem about Interactive Computer Graphics. I summarize and abstract this problem as follows:

I'm going to rotation a 3d coordinate P(x1,y1,z1) around a point O(x0,y0,z0)

and there are 2 vectors u and v which we already know.

u is the direction to O before transformation.

v is the direction to O after transformation.

I want to know how to conduct the calculation and get the coordinate of Q

enter image description here

Thanks a lot.


Solution:

Rotation About an Arbitrary Axis in 3 Dimensions using the following matrix:

rotation axis vector (normalized): (u,v,w)

position coordinate of the rotation center: (a,b,c)

rotation angel: theta

enter image description here

Reference:

https://docs.google.com/viewer?a=v&pid=sites&srcid=ZGVmYXVsdGRvbWFpbnxnbGVubm11cnJheXxneDoyMTJiZTZlNzVlMjFiZTFi

HT XU
  • 137
  • 1
  • 3
  • 8
  • Quite simple. (1) Calc the distance from O to P (2) find coordinates of a point from O with the same distance at direction v. – Lior Kogan Jul 18 '17 at 07:54
  • Consider rotating `P(x1-x0, y1-y0, z1-z0)` around the origin `(0,0,0)` to yield `P*`. Then translate, where: `Q = P* + O(x0,y0,z0)`. (If this piques your interest, it might be time to learn about coordinate transforms, matrices, and the notion of points vs. vectors.) – Brett Hale Jul 18 '17 at 07:54

4 Answers4

1

By computing dot product between v and u get the angle l between the vectors. Do a cross product of v and u (normalized) to produce axis of rotation vector a. Let w be a vector along vector u from O to P. To rotate point P into Q apply the following actions (in pseudo code) having axis a and angle l computed above:

float4 Rotate(float4 w, float l, float4 a) 
{
    float4x4 Mr = IDENTITY;
    quat_t quat = IDENTITY;
    float4 t = ZERO;

    float xx, yy, zz, xy, xz, yz, wx, wy, wz;

    quat[X] = a[X] * sin((-l / 2.0f));
    quat[Y] = a[Y] * sin((-l / 2.0f));
    quat[Z] = a[Z] * sin((-l / 2.0f));
    quat[W] = cos((-l / 2.0f));

    xx = quat[X] * quat[X];
    yy = quat[Y] * quat[Y];
    zz = quat[Z] * quat[Z];

    xy = quat[X] * quat[Y];
    xz = quat[X] * quat[Z];

    yz = quat[Y] * quat[Z];

    wx = quat[W] * quat[X];
    wy = quat[W] * quat[Y];
    wz = quat[W] * quat[Z];

    Mr[0][0] = 1.0f - 2.0f * (yy + zz);
    Mr[0][1] = 2.0f * (xy + wz);
    Mr[0][2] = 2.0f * (xz - wy);
    Mr[0][3] = 0.0f;
    Mr[1][0] = 2.0f * (xy - wz);
    Mr[1][1] = 1.0f - 2.0f * (xx + zz);
    Mr[1][2] = 2.0f * (yz + wx);
    Mr[1][3] = 0.0f;
    Mr[2][0] = 2.0f * (xz + wy);
    Mr[2][1] = 2.0f * (yz - wx);
    Mr[2][2] = 1.0f - 2.0f * (xx + yy);
    Mr[2][3] = 0.0f;
    Mr[3][0] = 0.0f;
    Mr[3][1] = 0.0f;
    Mr[3][2] = 0.0f;
    Mr[3][3] = 1.0f;

    w = Mr * w;
    return w;
}

Point Q is at the end of the rotated vector w. Algorithm used in the pseudo code is quaternion rotation.

Dori
  • 675
  • 1
  • 7
  • 26
1

for just single point no rotations is needed ... so knowns are:

u,v,O,P

so we now the distance is not changing:

|P-O| = |Q-O|

and directions are parallel to u,v so:

Q = O + v*(|P-O|/|v|)

But I suspect you want to construct rotation (transform matrix) such that more points (mesh perhaps) are transformed. If that is true then you need at least one known to get this right. Because there is infinite possible rotations transforming P -> Q but the rest of the mesh will be different for each ... so you need to know at least 2 non trivial points pair P0,P1 -> Q0,Q1 or axis of rotation or plane parallel to rotation or any other data known ...

Anyway in current state you can use as rotation axis vector perpendicular to u,v and angle obtained from dot product:

axis = cross (u,v)
ang = +/-acos(dot(u,v))

You just need to find out the sign of angle so try both and use the one for which the resultinq Q is where it should be so dot(Q-O,v) is max. To rotate around arbitrary axis and point use:

Also this might be helpfull:

Spektre
  • 49,595
  • 11
  • 110
  • 380
0

If you know u, v, P, and O then I would suggest that you compute |OP| which should be preserved under rotations. Then multiply this length by the unit vector -v (I assumed u, v are unit vectors: if not - normalize them) and translate the origin by this -|OP|v vector. The negative sign in front of v comes from the description given in your question:"v is the direction to O after transformation".

AGN Gazer
  • 8,025
  • 2
  • 27
  • 45
0

P and Q are at the same distance R to O
R = sqrt( (x1-x0)^2 + (y1-y0)^2 + (z1-z0)^2 )

and OQ is collinear to v, so OQ = v * R / ||v|| where ||v|| is the norm of v
||v|| = sqrt( xv^2 + yv^2 + zv^2 )

So the coordinates of Q(xq,yq,zq) are:

xq= xo + xv * R / ||v||
yq= yo + yv * R / ||v||
zq= zo + zv * R / ||v||

Jerome Demantke
  • 161
  • 1
  • 8