# Add possibility to rotate through custom rotation matrices #53

Closed
opened this issue May 6, 2017 · 2 comments
Closed

# Add possibility to rotate through custom rotation matrices#53

opened this issue May 6, 2017 · 2 comments
Labels

### WoLpH commented May 6, 2017

 Copied from wolph's blog: https://w.wol.ph/about/#comment-174 First, many thanks for your numpy-stl module. Most helpful. I have one suggestion to make: The only rotation you have enabled in your code is around an arbitrary axis (and a point), which is super helpful. I understand that you are using the rotation_matrix function which calculates the appropriate rotation matrix, which you then use to rotate the stl. I would find it very useful (and powerful) to provide a second function that would allow a rotation around a user supplied rotation matrix. What I am thinking is this: ``````rollMatrix = mesh.Mesh.rotation_matrix((1,0,0), heel_rads) pitchMatrix = mesh.Mesh.rotation_matrix((0,1,0), pitch_rads) combinedMatrix = numpy.dot(rollMatrix, pitchMatrix) my_mesh.rotate_using_matrix(combinedMatrix) `````` This would allow for very easy chaining of matrices. The work-around is very easy, but this seems like a really quick and useful addition…

### Uvar commented Jul 6, 2017

 In the past I used something like this, in which orient is the unit normal of a facet which is intended to face downwards.: `````` def rotation(self, orient): "This function might cause xy-plane rotation, that does not matter much" alpha = 0.5 * math.pi - math.atan2(orient[Y], orient[X]) beta = -0.5 * math.pi - math.atan2( orient[Z], math.sqrt(orient[X] ** 2 + orient[Y] ** 2)) sin_a = math.sin(alpha) cos_a = math.cos(alpha) sin_b = math.sin(beta) cos_b = math.cos(beta) rotation_matrix = numpy.transpose(( (cos_a, -sin_a, 0), (cos_b * sin_a, cos_b * cos_a, -sin_b), (sin_b * sin_a, sin_b * cos_a, cos_b), )) return rotation_matrix def transform(self, orient): rotation_matrix = self.rotation(orient) rotated_vectors = numpy.dot(self.vectors, rotation_matrix) rotated_vectors = numpy.array(rotated_vectors, dtype='float32') max_ = rotated_vectors.max(axis=(0, 1)) min_ = rotated_vectors.min(axis=(0, 1)) rotated_vectors[:, :, Z] -= min_[Z] # translation to have Z_min == 0. Not required per se max_[Z] -= min_[Z] min_[Z] -= min_[Z] return rotated_vectors, rotation_matrix `````` Rotating according to a rotation matrix is as simple as taking the dot product of the data with the rotation matrix.

### WoLpH commented Mar 10, 2018

 For completeness I've simply split the rotation method into multiple functions right now, but you're right @Uvar, the rotations and translations could simply be combined in a single operation instead. The transform method already supports this :)