Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add possibility to rotate through custom rotation matrices #53

WoLpH opened this issue May 6, 2017 · 2 comments

Add possibility to rotate through custom rotation matrices #53

WoLpH opened this issue May 6, 2017 · 2 comments


Copy link

WoLpH commented May 6, 2017

Copied from wolph's blog:

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 =, pitchMatrix)

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…

@WoLpH WoLpH self-assigned this Jun 11, 2017
Copy link

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 =, 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 WoLpH closed this as completed in 9553e7c Mar 10, 2018
Copy link
Owner Author

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 :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
None yet

No branches or pull requests

2 participants