RhinoCommon Transformation matrix


#1

Is it possible to use RhinoCommon transformation matrix in such a way, that I could define transformation axis?

The code below is something I am trying to translate, and wondering if there is alterative in for defining transformation matrices

// construct a transform matrix from our axes
glm::mat3x3 object_transform;
object_transform[0] = vector0; //Vector
object_transform[1] = vector1; //Vector
object_transform[2] = vector2; //Vector

// invert the matrix
glm::mat3x3 object_to_world_transform = glm::inverse(object_transform);

// transform the outward normal (vector) using the matrix
glm::vec3 normal = object_to_world_transform * axis_z;

#2

Should work - i just did something similar: I recreated a cameraprojection matrix with values i took from a blender camera matrix. It worked as expected, but you have to be careful with the coordinate systems: left/right handed, y-up and z-up… also the matrices can be column or row major it seems… Took me a few tries to get the right sequence.
Rhinocommon Transform should already have all the methods you need.


#3

I have never worked with matrices.

Is it possible to get an example how to:

  1. Create Matrix of 3x4 I assume in C# it is lilke this:

Rhino.Geometry.Matrix m = new Rhino.Geometry.Matrix(3, 4);

  1. How to assign values to rhino matrix?
    Basically I have 4 points and want to create matrix like this:
    | x0.x x0.y x0.z 1 |
    | x1.x x1.y x1.z 1 |
    | x2.x x2.y x2.z 1 |
    | x3.x x3.y x3.z 1 |

  2. And calculate determinant of it?


#4

My knowledge of matrices is also not the best, but you should use the rhino.transform class, as it has way more functions implemented and is basically a 4x4 matrix…

Transform t = new Transform(0);
t.M00 = x0.x;
t.M01 = x0.y;
etc..
double determinant = t.Determinant;

If the result looks wrong, swap rows and columns.


(Menno Deij - van Rijswijk) #5

The transformation matrix is indeed a 4x4 matrix. The 3x3 sub-matrix defines the scaling and rotation matrix, and the 4th column’s first 3 entries the translation. The fourth row’s elements are all zero except the last one that is 1:

| r00 r01 r02 | t0 |
| r10 r11 r12 | t1 |
| r20 r21 r22 | t2 |
|   0   0   0 |  1 |

Such a 4x4 matrix can encode all affine transformations (i.e. rotation, translation, scaling, shearing, etc.)

For more information, google it or start reading here https://math.stackexchange.com/questions/336/why-are-3d-transformation-matrices-4-times-4-instead-of-3-times-3


#6

Thanks for the reply,

I trying to solve unify mesh windings problem by reading this stackoverflow post:

However It seems that it does not work for me or I simply do not know enough about matrices.

Could you please take a look at my code. The function below check if the winding is clockwise or not, but far from working outputting correct true and false statements:

private void RunScript(Mesh x, Point3d y, ref object A)
  {

unify.gh (22.5 KB)

    bool[] f = new bool[x.Faces.Count];

    for(int i = 0; i < x.Faces.Count; i++){
      x.Faces[i] = x.Faces[i].Flip();
      Vector3f vecA = new Vector3f (x.Vertices[x.Faces[i].A].X, x.Vertices[x.Faces[i].A].Y, x.Vertices[x.Faces[i].A].Z);
      Vector3f vecB = new Vector3f (x.Vertices[x.Faces[i].B].X, x.Vertices[x.Faces[i].B].Y, x.Vertices[x.Faces[i].B].Z);
      Vector3f vecC = new Vector3f (x.Vertices[x.Faces[i].C].X, x.Vertices[x.Faces[i].C].Y, x.Vertices[x.Faces[i].C].Z);
      //Vector3f v0 = Vector3f.Subtract(vecA, vecB);
      //Vector3f v1 = Vector3f.Subtract(vecB, vecC);
      //Vector3f v2 = Vector3f.Subtract(vecC, vecA);
      //f[i] = CheckWinding(vecA, vecB, vecC, y);
      f[i] = CheckWinding(v0, v1, v2);
    }

    A = f;

  }

  // <Custom additional code> 
  public bool CheckWinding(Vector3f v0, Vector3f v1, Vector3f v2)
  {
    //Calculate three axis
    Vector3f axis_x = v1 - v0;    // edge v0 -> v1
    Vector3f axis_y = v2 - v0;    // edge v0 -> v2
    Vector3f axis_z = Vector3f.CrossProduct(axis_x, axis_y);
    axis_z.Unitize();
  
    //Construct a transform matrix from our axes
    Transform t = new Transform(0);
    
    t.M00 = axis_x.X;
    t.M01 = axis_x.Y;
    t.M02 = axis_x.Z;
    t.M03 = 1;
    
    t.M10 = axis_y.X;
    t.M11 = axis_y.Y;
    t.M12 = axis_y.Z;
    t.M13 = 1;
    
    t.M20 = axis_z.X;
    t.M21 = axis_z.Y;
    t.M22 = axis_z.Z;
    t.M23 = 1;
    
    t.M30 = 0;
    t.M31 = 0;
    t.M32 = 0;
    t.M33 = 1;
    

  
    //Invert the matrix
    t.TryGetInverse(out t);
    
    //Transform the outward normal using matrix
    axis_z.Transform(t);
    

    return (axis_z.Z > 0);
  }

#7

Looks to me like the check posted on Stack Exchange is flawed. The matrix represents a transformation to the local space of the basis defined by axes x, y, and z. Applying this transformation to the z axis will always result in (0,0,1), so, unless I’m missing something, this just seems like a very expensive way of checking if the z axis is pointing in the same direction as itself.


#8

Yeah, this does not work. For me it looked super complex way for checking windings.
But after playing with matrices several times and seeing random results, I gave up.