Rotation Matrix given angle and point in X,Y,Z

前端 未结 3 1892
故里飘歌
故里飘歌 2020-12-03 19:57

I am doing image manipulation and I want to rotate all of the pixels in xyz space based on an angle, the origin, and an x,y, and z coordinate.

I just need to setup t

相关标签:
3条回答
  • 2020-12-03 20:14

    Use the Matrix3D Structure (MSDN) - Represents a 4 x 4 matrix used for transformations in 3-D space

    Take a look here for a tutorial: Building a 3D Engine

    Essentially, matrices are built for X, Y, and Z rotations and then you can multiply the rotations in any order.

    public static Matrix3D NewRotateAroundX(double radians)
    {
        var matrix = new Matrix3D();
        matrix._matrix[1, 1] = Math.Cos(radians);
        matrix._matrix[1, 2] = Math.Sin(radians);
        matrix._matrix[2, 1] = -(Math.Sin(radians));
        matrix._matrix[2, 2] = Math.Cos(radians);
        return matrix;
    }
    public static Matrix3D NewRotateAroundY(double radians)
    {
        var matrix = new Matrix3D();
        matrix._matrix[0, 0] = Math.Cos(radians);
        matrix._matrix[0, 2] = -(Math.Sin(radians));
        matrix._matrix[2, 0] = Math.Sin(radians);
        matrix._matrix[2, 2] = Math.Cos(radians);
        return matrix;
    }
    public static Matrix3D NewRotateAroundZ(double radians)
    {
        var matrix = new Matrix3D();
        matrix._matrix[0, 0] = Math.Cos(radians);
        matrix._matrix[0, 1] = Math.Sin(radians);
        matrix._matrix[1, 0] = -(Math.Sin(radians));
        matrix._matrix[1, 1] = Math.Cos(radians);
        return matrix;
    }
    
    0 讨论(0)
  • 2020-12-03 20:21

    Function rotateAroundAxis() rotates point around any axis in 3D. It is my solution to the rotation in 3D using analytic geometry and programming to model the process. The code is in JavaScript.

    function rotateAroundAxis(A, B, C, alpha, precision) {
      // A is rotated point, BC is axis, alpha is angle
      // A, B, C are points in format [Ax, Ay, Az], alpha is float, precision is int
      // A2 is output in format [A2x, A2y, A2z]
      if((A[0] - B[0])*(A[1] - C[1]) == (A[1] - B[1])*(A[0] - C[0]) && (A[1] - B[1])*(A[2] - C[2]) == (A[1] - C[1])*(A[2] - B[2]) && (A[0] - B[0])*(A[2] - C[2]) == (A[0] - C[0])*(A[2] - B[2])) {
        return A
      }// Return the original point if it is on the axis.
      var D = findClosestPoint(A, B, C, precision);
      var w = crossProduct(new Array(C[0] - B[0], C[1] - B[1], C[2] - B[2]), new Array(C[0] - A[0], C[1] - A[1], C[2] - A[2]));
      var W = pointPlusVector(A, w);
      var sizeAW = vectorSize(A, W);
      var sizeDA = vectorSize(D, A);
      var sizeAE = sizeDA*(Math.sin(0.5*alpha))/(Math.cos(0.5*alpha));
      var E = new Array(A[0] + (W[0] - A[0])*sizeAE/sizeAW, A[1] + (W[1] - A[1])*sizeAE/sizeAW, A[2] + (W[2] - A[2])*sizeAE/sizeAW);
      var sizeDE = vectorSize(D, E);
      var sizeEF = sizeAE*Math.sin(alpha/2);
      var F = new Array(D[0] + (E[0] - D[0])*(sizeDE - sizeEF)/sizeDE, D[1] + (E[1] - D[1])*(sizeDE - sizeEF)/sizeDE, D[2] + (E[2] - D[2])*(sizeDE - sizeEF)/sizeDE);
      var A2 = new Array(A[0] + 2*(F[0] - A[0]), A[1] + 2*(F[1] - A[1]), A[2] + 2*(F[2] - A[2]))
      return A2;
    }
    
    function angleSize(A, S, B) {
      ux = A[0] - S[0]; uy = A[1] - S[1]; uz = A[2] - S[2];
      vx = B[0] - S[0]; vy = B[1] - S[1]; vz = B[2] - S[2];
      if((Math.sqrt(ux*ux + uy*uy + uz*uz)*Math.sqrt(vx*vx + vy*vy + vz*vz)) == 0) {return 0}
      return Math.acos((ux*vx + uy*vy + uz*vz)/(Math.sqrt(ux*ux + uy*uy + uz*uz)*Math.sqrt(vx*vx + vy*vy + vz*vz)));
    }
    
    function findClosestPoint(N, B, C, precision) {
      // We will devide the segment BC into many tiny segments and we will choose the point F where the |NB F| distance is the shortest.
      if(B[0] == C[0] && B[1] == C[1] && B[2] == C[2]) {return B}
      var shortest = 0;
      for(var i = 0; i <= precision; i++) {
        var Fx = Math.round(precision*precision*(B[0] + (C[0] - B[0])*i/precision))/(precision*precision);
        var Fy = Math.round(precision*precision*(B[1] + (C[1] - B[1])*i/precision))/(precision*precision);
        var Fz = Math.round(precision*precision*(B[2] + (C[2] - B[2])*i/precision))/(precision*precision);
        var sizeF = vectorSize(new Array(N[0], N[1], N[2]), new Array(Fx, Fy, Fz));
        if(i == 0 || sizeF < shortest) { // first run or condition
          shortest = sizeF;
          F = new Array(Fx, Fy, Fz);
        }
      }
      // recursion, if it is an outer point return findClosestPoint(we mirror further point in the closer one)
      if(F[0] == Math.round(precision*precision*(B[0]))/(precision*precision) && F[1] == Math.round(precision*precision*(B[1]))/(precision*precision) && F[2] == Math.round(precision*precision*(B[2]))/(precision*precision)) { // F == B
        if(Math.round(precision*precision*180*angleSize(C, B, N)/Math.PI)/(precision*precision) <= 90){return F} else {return findClosestPoint(N, new Array(2*B[0] - C[0], 2*B[1] - C[1], 2*B[2] - C[2]), B, precision)}
      } else if (F[0] == Math.round(precision*precision*(C[0]))/(precision*precision) && F[1] == Math.round(precision*precision*(C[1]))/(precision*precision) && F[2] == Math.round(precision*precision*(C[2]))/(precision*precision)) { // F == C
        if(Math.round(precision*precision*180*angleSize(B, C, N)/Math.PI)/(precision*precision) <= 90) {return F} else {return findClosestPoint(N, C, new Array(2*C[0] - B[0], 2*C[1] - B[1], 2*C[2] - B[2]), precision)}
      } else {return F;}
    }
    
    function vectorSize(A, B) {
      var ux = A[0] - B[0];
      var uy = A[1] - B[1];
      var uz = A[2] - B[2];
      return Math.sqrt(ux*ux + uy*uy + uz*uz);
    }
    
    function crossProduct(u, v) {
      return (new Array(u[1]*v[2] - u[2]*v[1], u[2]*v[0] - u[0]*v[2], u[0]*v[1] - u[1]*v[0]));
    }
    
    function pointPlusVector (A, v) {
      return (new Array(A[0] + v[0], A[1] + v[1], A[2] + v[2]));
    }
    
    0 讨论(0)
  • 2020-12-03 20:28

    The complete rotation matrices are derived and given at https://sites.google.com/site/glennmurray/Home/rotation-matrices-and-formulas.

    From the paper:

    5.2 The simplified matrix for rotations about the origin

    Note this assumes that (u, v, w) is a direction vector for the axis of rotation and that u^2 + v^2 + w^2 = 1.

    Simplified 3D matrix for rotations about the origin.

    If you have a point (x, y, z) that you want to rotate, then we can obtain a function of of seven variables that yields the rotated point:

    f(x, y, z, u, v, w, theta) =

    Formula for rotated point.

    The paper also includes matrices and formulas for rotations about an arbitrary axis (not necessarily through the origin), Java code available under the Apache license, and a link to a web app that illustrates rotations.

    0 讨论(0)
提交回复
热议问题