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:
Bruno Perdigão
2024-08-30 17:23:48 -03:00
parent 90e83d77a7
commit bdcadfd100
2 changed files with 20 additions and 26 deletions
@@ -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
+18 -11
View File
@@ -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: