Generate Local Rx Ry Rz Values To Transform a Plane into a Target Plane

Hey, I bet this Question has already been answered somewhere on here but i can´t find a Solution that works. I have two planes Plane A and Plane B. I would like to Orient Plane A to the same orientation as Plane B by Rotating Plane A around its local axis, x y z(in this order). I tried to decompose the transformation result from the orient Component but with this method i could only get the global x y z rotations. I specifically need to know the angles. Thanks in advance

Hi @Tobias_Grüters ,

This is one possible approach, keep in mind that this approach is not very good but I tried to stick to your request (calculate X,Y,Z in that specific order).

import Rhino.Geometry as rg
import math

def extract_rotation_angles(plane_a, plane_b):
    rotation = rg.Transform.PlaneToPlane(plane_a, plane_b)
    angle_x, angle_y, angle_z = decompose_rotation_matrix(rotation)
    return angle_x, angle_y, angle_z

def decompose_rotation_matrix(transform):
    angle_y = math.asin(-clamp(transform.M20, -1.0, 1.0))
    if abs(transform.M20) < 0.99999:
        angle_x = math.atan2(transform.M21, transform.M22)
        angle_z = math.atan2(transform.M10, transform.M00)
    else:
        angle_x = math.atan2(-transform.M12, transform.M11)
        angle_z = 0
    return angle_x, angle_y, angle_z

def clamp(val, min_val, max_val):
    return max(min(val, max_val), min_val)

def apply_rotation(plane, angle_x, angle_y, angle_z):
    rotation_x = rg.Transform.Rotation(angle_x, rg.Vector3d.XAxis, plane.Origin)
    rotation_y = rg.Transform.Rotation(angle_y, rg.Vector3d.YAxis, plane.Origin)
    rotation_z = rg.Transform.Rotation(angle_z, rg.Vector3d.ZAxis, plane.Origin)
    combined_rotation = rotation_z * rotation_y * rotation_x
    rotated_plane = rg.Plane(plane)
    rotated_plane.Transform(combined_rotation)
    return rotated_plane

plane_a = rg.Plane.WorldXY
plane_b = rg.Plane.WorldYZ
angles = extract_rotation_angles(plane_a, plane_b)
print("Rotation Angles (in radians):", angles)

rotated_plane = apply_rotation(plane_a, *angles)
is_aligned = rotated_plane.Normal.IsParallelTo(plane_b.Normal, 1e-6) and rotated_plane.Origin.DistanceTo(plane_b.Origin) < 1e-6
print("Planes are aligned:", is_aligned)

There are some cases in which this solution will not work, some cases in which It should return multiple valid solutions, anyway that’s a proof of concept of your idea.
I would consider a different implementation personally, calculating X,Y,Z is not the best approach imo.

Hope this helps,
Farouk

Your constraints make this more difficult when there is this easy way:


align_plane_2024Jan23a.gh (4.8 KB)

Also:

3. Attach minimal versions of all the relevant files

Thank you Farouk,

this was very helpfull.