diff --git a/main.py b/main.py index 0276c28..0581f41 100644 --- a/main.py +++ b/main.py @@ -1,3 +1,4 @@ +import math from typing import List, Tuple import matplotlib.pyplot as plt @@ -54,7 +55,11 @@ if abs(xs[0] - xs[1]) < 1e-6 and abs(ys[0] - ys[1]) < 1e-6: return self.set_positions((xs[0], ys[0]), (xs[1], ys[1])) - super().draw(renderer) + try: + super().draw(renderer) + except Exception: + # If patch drawing fails (e.g., degenerate path), skip drawing the arrow + return def do_3d_projection(self, renderer=None): xs3d, ys3d, zs3d = self._verts3d @@ -108,6 +113,28 @@ return data_list +def compute_and_format_angle(pts: List[Tuple[float, float, float]]) -> str: + if len(VECTOR_PAIRS) < 2: + return "Angle v1-v2: N/A" + (a1, b1) = VECTOR_PAIRS[0] + (a2, b2) = VECTOR_PAIRS[1] + p1s = pts[a1] + p1e = pts[b1] + p2s = pts[a2] + p2e = pts[b2] + v1 = (p1e[0] - p1s[0], p1e[1] - p1s[1], p1e[2] - p1s[2]) + v2 = (p2e[0] - p2s[0], p2e[1] - p2s[1], p2e[2] - p2s[2]) + norm1 = math.sqrt(v1[0] ** 2 + v1[1] ** 2 + v1[2] ** 2) + norm2 = math.sqrt(v2[0] ** 2 + v2[1] ** 2 + v2[2] ** 2) + if norm1 < 1e-9 or norm2 < 1e-9: + return "Angle v1-v2: N/A" + dot = v1[0] * v2[0] + v1[1] * v2[1] + v1[2] * v2[2] + cos_val = max(-1.0, min(1.0, dot / (norm1 * norm2))) + angle_rad = math.acos(cos_val) + angle_deg = math.degrees(angle_rad) + return f"Angle v1-v2: {angle_deg:.2f}°" + + # Function to visualize thumb data with a slider def visualize_thumb_data(data: List[ThumbFrameData]): if not data: @@ -193,6 +220,10 @@ ) arrow_labels.append(lbl) + # Angle display between v1 and v2 (figure-relative text) + angle_text = fig.text(0.02, 0.95, "", fontsize=12, weight="bold") + angle_text.set_text(compute_and_format_angle(points)) + ax.set_xlabel("X") ax.set_ylabel("Y") ax.set_zlabel("Z") @@ -243,6 +274,9 @@ mid_z = 0.5 * (z1 + z2) + LABEL_OFFSET_Z_FACTOR * (z_max - z_min) arrow_labels[i_pair].set_position((mid_x, mid_y, mid_z)) + # Update angle text between v1 and v2 + angle_text.set_text(compute_and_format_angle(points)) + ax.set_title(f"Frame {data[frame_idx].frame_number}") fig.canvas.draw_idle()