mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-19 14:41:25 +00:00
more improvement on distance and angle calculations
This commit is contained in:
@@ -387,7 +387,6 @@ class PolylineDecorator:
|
|||||||
|
|
||||||
if is_input_on:
|
if is_input_on:
|
||||||
if cls.use_default_container:
|
if cls.use_default_container:
|
||||||
print("FOI")
|
|
||||||
snap_vector = Vector(
|
snap_vector = Vector(
|
||||||
(float(cls.input_panel["X"]), float(cls.input_panel["Y"]), default_container_elevation)
|
(float(cls.input_panel["X"]), float(cls.input_panel["Y"]), default_container_elevation)
|
||||||
)
|
)
|
||||||
@@ -414,7 +413,7 @@ class PolylineDecorator:
|
|||||||
|
|
||||||
distance = (snap_vector - last_point).length
|
distance = (snap_vector - last_point).length
|
||||||
if distance > 0:
|
if distance > 0:
|
||||||
angle = tool.Cad.angle_3_vectors(snap_vector, last_point, second_to_last_point, degrees=True)
|
angle = tool.Cad.angle_3_vectors(second_to_last_point, last_point, snap_vector, degrees=True)
|
||||||
if cls.input_panel:
|
if cls.input_panel:
|
||||||
cls.input_panel["X"] = str(round(snap_vector.x, 3))
|
cls.input_panel["X"] = str(round(snap_vector.x, 3))
|
||||||
cls.input_panel["Y"] = str(round(snap_vector.y, 3))
|
cls.input_panel["Y"] = str(round(snap_vector.y, 3))
|
||||||
@@ -495,22 +494,24 @@ class PolylineDecorator:
|
|||||||
distance = float(cls.input_panel["D"])
|
distance = float(cls.input_panel["D"])
|
||||||
|
|
||||||
if distance < 0 or distance > 0:
|
if distance < 0 or distance > 0:
|
||||||
new_angle = radians(float(cls.input_panel["A"]))
|
angle = radians(float(cls.input_panel["A"]))
|
||||||
print(cls.input_panel["A"])
|
|
||||||
# new_angle = radians(30)
|
# 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
|
v1 = second_to_last_point - last_point
|
||||||
v2 = last_point - snap_vector
|
v2 = snap_vector - last_point
|
||||||
|
|
||||||
|
v1.normalize()
|
||||||
|
v2.normalize()
|
||||||
|
|
||||||
# Calculate the axis of rotation
|
# Calculate the axis of rotation
|
||||||
axis = v1.cross(v2).normalized()
|
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)
|
||||||
|
|
||||||
# Calculate the rotated vector
|
coords = rot_vector * distance + last_point
|
||||||
# rotated_vector = v2 * math.cos(new_angle) + axis * math.sin(new_angle) * v1.length + v1 * (1 - math.cos(new_angle)) * (dot_product / v1.length**2)
|
|
||||||
# dir_vec = snap_vector - last_point
|
|
||||||
# coords = dir_vec.normalized() * distance + last_point
|
|
||||||
rot_mat = Matrix.Rotation(new_angle, 3, axis)
|
|
||||||
coords = (v1.normalized() @ rot_mat) * distance + last_point
|
|
||||||
|
|
||||||
x = coords[0]
|
x = coords[0]
|
||||||
y = coords[1]
|
y = coords[1]
|
||||||
@@ -521,7 +522,6 @@ class PolylineDecorator:
|
|||||||
if "Z" in list(cls.input_panel.keys()):
|
if "Z" in list(cls.input_panel.keys()):
|
||||||
cls.input_panel["Z"] = str(round(z, 3))
|
cls.input_panel["Z"] = str(round(z, 3))
|
||||||
|
|
||||||
print(cls.input_panel)
|
|
||||||
return cls.input_panel
|
return cls.input_panel
|
||||||
|
|
||||||
return cls.input_panel
|
return cls.input_panel
|
||||||
|
|||||||
@@ -2327,7 +2327,7 @@ class MeasureTool(bpy.types.Operator):
|
|||||||
self.number_is_negative = False
|
self.number_is_negative = False
|
||||||
self.is_input_on = False
|
self.is_input_on = False
|
||||||
self.input_options = ["D", "A", "X", "Y", "Z"]
|
self.input_options = ["D", "A", "X", "Y", "Z"]
|
||||||
self.input_type = "OFF"
|
self.input_type = None
|
||||||
self.input_value_xy = [None, None]
|
self.input_value_xy = [None, None]
|
||||||
self.input_panel = {"D": "", "A": "", "X": "", "Y": "", "Z": ""}
|
self.input_panel = {"D": "", "A": "", "X": "", "Y": "", "Z": ""}
|
||||||
self.snap_angle = None
|
self.snap_angle = None
|
||||||
@@ -2352,11 +2352,8 @@ class MeasureTool(bpy.types.Operator):
|
|||||||
if self.input_type in {"X", "Y", "Z"}:
|
if self.input_type in {"X", "Y", "Z"}:
|
||||||
self.input_panel = PolylineDecorator.calculate_distance_and_angle(context, self.is_input_on)
|
self.input_panel = PolylineDecorator.calculate_distance_and_angle(context, self.is_input_on)
|
||||||
elif self.input_type in {"D", "A"}:
|
elif self.input_type in {"D", "A"}:
|
||||||
print("!")
|
|
||||||
self.input_panel = PolylineDecorator.calculate_x_y_and_z(context)
|
self.input_panel = PolylineDecorator.calculate_x_y_and_z(context)
|
||||||
print("!", self.input_panel)
|
# self.input_panel = PolylineDecorator.calculate_distance_and_angle(context, self.is_input_on)
|
||||||
self.input_panel = PolylineDecorator.calculate_distance_and_angle(context, self.is_input_on)
|
|
||||||
print("!2", self.input_panel)
|
|
||||||
else:
|
else:
|
||||||
self.input_panel[self.input_type] = self.number_output
|
self.input_panel[self.input_type] = self.number_output
|
||||||
tool.Blender.update_viewport()
|
tool.Blender.update_viewport()
|
||||||
@@ -2368,7 +2365,7 @@ class MeasureTool(bpy.types.Operator):
|
|||||||
if event.type == "MOUSEMOVE" or event.type == "INBETWEEN_MOUSEMOVE":
|
if event.type == "MOUSEMOVE" or event.type == "INBETWEEN_MOUSEMOVE":
|
||||||
self.mousemove_count += 1
|
self.mousemove_count += 1
|
||||||
self.is_input_on = False
|
self.is_input_on = False
|
||||||
self.input_type = "OFF"
|
self.input_type = None
|
||||||
PolylineDecorator.set_input_panel(self.input_panel, self.input_type)
|
PolylineDecorator.set_input_panel(self.input_panel, self.input_type)
|
||||||
tool.Snap.clear_snapping_ref()
|
tool.Snap.clear_snapping_ref()
|
||||||
tool.Blender.update_viewport()
|
tool.Blender.update_viewport()
|
||||||
@@ -2492,7 +2489,7 @@ class MeasureTool(bpy.types.Operator):
|
|||||||
if is_valid:
|
if is_valid:
|
||||||
tool.Snap.insert_polyline_point(self.input_panel)
|
tool.Snap.insert_polyline_point(self.input_panel)
|
||||||
self.is_input_on = False
|
self.is_input_on = False
|
||||||
self.input_type = "OFF"
|
self.input_type = None
|
||||||
self.number_input = []
|
self.number_input = []
|
||||||
self.number_output = ""
|
self.number_output = ""
|
||||||
PolylineDecorator.set_input_panel(self.input_panel, self.input_type)
|
PolylineDecorator.set_input_panel(self.input_panel, self.input_type)
|
||||||
@@ -2532,7 +2529,7 @@ class MeasureTool(bpy.types.Operator):
|
|||||||
if event.value == "RELEASE" and event.type in {"ESC"}:
|
if event.value == "RELEASE" and event.type in {"ESC"}:
|
||||||
self.recalculate_inputs(context)
|
self.recalculate_inputs(context)
|
||||||
self.is_input_on = False
|
self.is_input_on = False
|
||||||
self.input_type = "OFF"
|
self.input_type = None
|
||||||
PolylineDecorator.set_input_panel(self.input_panel, self.input_type)
|
PolylineDecorator.set_input_panel(self.input_panel, self.input_type)
|
||||||
tool.Blender.update_viewport()
|
tool.Blender.update_viewport()
|
||||||
else:
|
else:
|
||||||
|
|||||||
@@ -88,12 +88,14 @@ class Cad:
|
|||||||
def angle_3_vectors(cls, v1, v2, v3, degrees=False):
|
def angle_3_vectors(cls, v1, v2, v3, degrees=False):
|
||||||
"""
|
"""
|
||||||
> takes 3 vectors. The order matters, v2 is the center point.
|
> takes 3 vectors. The order matters, v2 is the center point.
|
||||||
< returns the potentially signed angle as degrees or radians
|
< returns the signed angle as degrees or radians
|
||||||
"""
|
"""
|
||||||
d1 = v1 - v2
|
d1 = v1 - v2
|
||||||
d2 = v3 - v2
|
d2 = v3 - v2
|
||||||
|
|
||||||
axis = d1.cross(d2)
|
axis = d1.cross(d2)
|
||||||
|
print(axis)
|
||||||
|
print(round(axis.z, 2))
|
||||||
axis.normalize()
|
axis.normalize()
|
||||||
|
|
||||||
# Calculate the unsigned angle between the "d1" and "d2" vectors
|
# Calculate the unsigned angle between the "d1" and "d2" vectors
|
||||||
@@ -101,8 +103,8 @@ class Cad:
|
|||||||
|
|
||||||
|
|
||||||
# Determine the sign of the angle based on the provided axis
|
# Determine the sign of the angle based on the provided axis
|
||||||
parameter = axis.z < 0
|
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 <= 0 else 1
|
sign = -1 if parameter else 1
|
||||||
|
|
||||||
if degrees:
|
if degrees:
|
||||||
a = math.degrees(a)
|
a = math.degrees(a)
|
||||||
|
|||||||
Reference in New Issue
Block a user