mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-13 19:07:57 +00:00
Refactor tool.Cad.angle_3_vectors
This functions was built to work with the input calculations for the polytool. Part of its code was being duplicated in another part of the code. The refactor keeps most of the calculation in the same place.
This commit is contained in:
@@ -413,7 +413,7 @@ class PolylineDecorator:
|
||||
|
||||
distance = (snap_vector - last_point).length
|
||||
if distance > 0:
|
||||
angle = tool.Cad.angle_3_vectors(second_to_last_point, last_point, snap_vector, degrees=True)
|
||||
angle = tool.Cad.angle_3_vectors(second_to_last_point, last_point, snap_vector, new_angle=None, degrees=True)
|
||||
if cls.input_panel:
|
||||
cls.input_panel["X"] = str(round(snap_vector.x, 3))
|
||||
cls.input_panel["Y"] = str(round(snap_vector.y, 3))
|
||||
@@ -496,20 +496,7 @@ class PolylineDecorator:
|
||||
if distance < 0 or distance > 0:
|
||||
angle = radians(float(cls.input_panel["A"]))
|
||||
|
||||
# TODO This is basically the reverse process of tool.Cad.angle_3_vectors
|
||||
# Combine them into a single function
|
||||
v1 = second_to_last_point - last_point
|
||||
v2 = snap_vector - last_point
|
||||
|
||||
v1.normalize()
|
||||
v2.normalize()
|
||||
|
||||
# Calculate the axis of rotation
|
||||
axis = v1.cross(v2).normalized()
|
||||
rot_mat = Matrix.Rotation(angle, 3, axis)
|
||||
parameter = round(axis.z, 2) < 0 or (round(axis.y, 2) == 0 and round(axis.x < 0)) or (round(axis.x, 2) == 0 and round(axis.y < 0))
|
||||
|
||||
rot_vector = (v1 @ rot_mat) if parameter else (rot_mat @ v1)
|
||||
rot_vector = tool.Cad.angle_3_vectors(second_to_last_point, last_point, snap_vector, angle, degrees=True)
|
||||
|
||||
coords = rot_vector * distance + last_point
|
||||
|
||||
|
||||
@@ -85,32 +85,39 @@ class Cad:
|
||||
return math.degrees(a) if degrees else a
|
||||
|
||||
@classmethod
|
||||
def angle_3_vectors(cls, v1, v2, v3, degrees=False):
|
||||
def angle_3_vectors(cls, v1, v2, v3, new_angle=None, degrees=False):
|
||||
"""
|
||||
> takes 3 vectors. The order matters, v2 is the center point.
|
||||
< returns the signed angle as degrees or radians
|
||||
< if a new angle is provided, return the rotation vector
|
||||
"""
|
||||
d1 = v1 - v2
|
||||
d2 = v3 - v2
|
||||
|
||||
axis = d1.cross(d2)
|
||||
print(axis)
|
||||
print(round(axis.z, 2))
|
||||
axis.normalize()
|
||||
d1.normalize()
|
||||
d2.normalize()
|
||||
|
||||
axis = d1.cross(d2).normalized()
|
||||
|
||||
# Calculate the unsigned angle between the "d1" and "d2" vectors
|
||||
a = d1.angle(d2)
|
||||
|
||||
|
||||
# Determine the sign of the angle based on the provided axis
|
||||
# If new_angle, determine the direction of the rotation
|
||||
parameter = round(axis.z, 2) < 0 or (round(axis.y, 2) == 0 and round(axis.x < 0)) or (round(axis.x, 2) == 0 and round(axis.y < 0))
|
||||
sign = -1 if parameter else 1
|
||||
|
||||
if degrees:
|
||||
a = math.degrees(a)
|
||||
return a * sign
|
||||
if new_angle:
|
||||
rot_mat = Matrix.Rotation(new_angle, 3, axis)
|
||||
rot_vector = (d1 @ rot_mat) if parameter else (rot_mat @ d1)
|
||||
return rot_vector
|
||||
else:
|
||||
return a
|
||||
sign = -1 if parameter else 1
|
||||
|
||||
if degrees:
|
||||
a = math.degrees(a)
|
||||
return a * sign
|
||||
else:
|
||||
return a
|
||||
|
||||
@classmethod
|
||||
def is_x(cls, value: float, x: float, tolerance: float | None = None) -> bool:
|
||||
|
||||
Reference in New Issue
Block a user