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

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

Add possibility to rotate through custom rotation matrices #53

WoLpH opened this issue May 6, 2017 · 2 comments
Assignees
Labels

Comments

@WoLpH
Copy link
Owner

@WoLpH 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…

@WoLpH WoLpH added the enhancement label Jun 1, 2017
@WoLpH WoLpH self-assigned this Jun 11, 2017
@Uvar

This comment has been minimized.

Copy link
Collaborator

@Uvar 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 WoLpH closed this in 9553e7c Mar 10, 2018
@WoLpH

This comment has been minimized.

Copy link
Owner Author

@WoLpH 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
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
2 participants
You can’t perform that action at this time.