import numpy as np import math def distance_point_to_line_segment(px, py, x1, y1, x2, y2): # Calculate the squared distance from point (px, py) to the line segment [(x1, y1), (x2, y2)] def sqr_distance_point_to_segment(): line_length_sq = (x2 - x1)**2 + (y2 - y1)**2 if line_length_sq == 0: return (px - x1)**2 + (py - y1)**2 t = max(0, min(1, ((px - x1) * (x2 - x1) + (py - y1) * (y2 - y1)) / line_length_sq)) return ((px - (x1 + t * (x2 - x1)))**2 + (py - (y1 + t * (y2 - y1)))**2) # Calculate the closest point on the line segment to the given point (px, py) def closest_point_on_line_segment(): line_length_sq = (x2 - x1)**2 + (y2 - y1)**2 if line_length_sq == 0: return x1, y1 t = max(0, min(1, ((px - x1) * (x2 - x1) + (py - y1) * (y2 - y1)) / line_length_sq)) closest_x = x1 + t * (x2 - x1) closest_y = y1 + t * (y2 - y1) return closest_x, closest_y closest_point = closest_point_on_line_segment() distance = math.sqrt(sqr_distance_point_to_segment()) return closest_point, distance def min_distance_from_line_to_circle(line_start, line_end, circle_center, circle_radius): closest_point, distance = distance_point_to_line_segment(circle_center[0], circle_center[1], line_start[0], line_start[1], line_end[0], line_end[1]) min_distance = max(0, distance - circle_radius) return min_distance # def twist_counter(pose_pred, prev_pose_pred=None, in_petal=False, petal_count=0): # if pose_pred is None: # return petal_count, in_petal # min_dist = 0 # # Users/lokamoto/Comprehensive_AQA/output/joint_plots/FINAWorldChampionships2019_Women10m_final_r1_0 # pose_pred = pose_pred[0] # vector1 = [pose_pred[2][0] - pose_pred[3][0], 0-(pose_pred[2][1] - pose_pred[3][1])] # if prev_pose_pred is not None: # prev_pose_pred = prev_pose_pred[0] # prev_pose_pred = [prev_pose_pred[2][0] - prev_pose_pred[3][0], 0-(prev_pose_pred[2][1] - prev_pose_pred[3][1])] # # m = (vector1[1] - prev_pose_pred[1])/(vector1[0] - prev_pose_pred[0]) # # b = prev_pose_pred[1] - m * prev_pose_pred[0] # # min_dist = np.abs(b)/np.sqrt(m**2+1) # min_dist = min_distance_from_line_to_circle(prev_pose_pred, vector1, (0, 0), 5) # if min_dist is not None and in_petal and np.linalg.norm(vector1) > 5 and min_dist == 0: #and np.linalg.norm(vector1) > 8 # petal_count += 1 # # print('leaving petal') # # print('going in new petal') # elif not in_petal and np.linalg.norm(vector1) > 5: #and min_dist > 3: #and np.linalg.norm(vector1) > 8 # in_petal = True # # print('going in petal') # elif in_petal and np.linalg.norm(vector1) < 5: # in_petal = False # petal_count += 1 # # print('leaving petal') # # print(vector) # return petal_count, in_petal def twist_counter(pose_pred, prev_pose_pred=None, in_petal=False, petal_count=0): # if key[0].startswith('FINAWorldChampionships2019'): # valid = 19 # outer = 3 # inner = 3 # elif key[0].startswith('FINADivingWorldCup2021'): # valid = 19 # outer = 5.5 # inner = 5.5 valid = 17 outer = 10 inner = 9 if pose_pred is None: return petal_count, in_petal min_dist = 0 pose_pred = pose_pred[0] vector1 = [pose_pred[2][0] - pose_pred[3][0], 0-(pose_pred[2][1] - pose_pred[3][1])] if prev_pose_pred is not None: prev_pose_pred = prev_pose_pred[0] prev_pose_pred = [prev_pose_pred[2][0] - prev_pose_pred[3][0], 0-(prev_pose_pred[2][1] - prev_pose_pred[3][1])] min_dist = min_distance_from_line_to_circle(prev_pose_pred, vector1, (0, 0), 0.5) if np.linalg.norm(vector1) > valid: return petal_count, in_petal if min_dist is not None and in_petal and np.linalg.norm(vector1) > outer and min_dist == 0: #and np.linalg.norm(vector1) > 8 petal_count += 1 elif not in_petal and np.linalg.norm(vector1) > outer: #and min_dist > 3: #and np.linalg.norm(vector1) > 8 in_petal = True elif in_petal and np.linalg.norm(vector1) < inner: in_petal = False petal_count += 1 return petal_count, in_petal # def som_counter(pose_pred=None, prev_pose_pred=None, half_som_count=0, handstand=False): # if pose_pred is None: # return half_som_count # pose_pred = pose_pred[0] # vector1 = [pose_pred[7][0] - pose_pred[6][0], 0-(pose_pred[7][1] - pose_pred[6][1])] # flip y axis # if (not handstand and half_som_count % 2 == 0) or (handstand and half_som_count %2 == 1): # vector2 = [0, -1] # else: # vector2 = [0, 1] # unit_vector_1 = vector1 / np.linalg.norm(vector1) # unit_vector_2 = vector2 / np.linalg.norm(vector2) # dot_product = np.dot(unit_vector_1, unit_vector_2) # current_angle = math.degrees(np.arccos(dot_product)) # if prev_pose_pred is not None: # prev_pose_pred = prev_pose_pred[0] # prev_vector = [prev_pose_pred[7][0] - prev_pose_pred[6][0], 0-(prev_pose_pred[7][1] - prev_pose_pred[6][1])] # flip y axis # prev_unit_vector = prev_vector / np.linalg.norm(prev_vector) # prev_angle_diff = math.degrees(np.arccos(np.dot(unit_vector_1, prev_unit_vector))) # # if prev_angle_diff > 120: # # print('pose pred is probably off') # # return half_som_count # # print("unit_vector_1:", unit_vector_1) # # print("looking for vector:", vector2) # if current_angle < 80: # half_som_count += 1 # return half_som_count def som_counter(pose_pred=None, prev_pose_pred=None, half_som_count=0, handstand=False): if pose_pred is None: return half_som_count, True pose_pred = pose_pred[0] vector1 = [pose_pred[7][0] - pose_pred[6][0], 0-(pose_pred[7][1] - pose_pred[6][1])] # flip y axis if (not handstand and half_som_count % 2 == 0) or (handstand and half_som_count %2 == 1): vector2 = [0, -1] else: vector2 = [0, 1] unit_vector_1 = vector1 / np.linalg.norm(vector1) unit_vector_2 = vector2 / np.linalg.norm(vector2) dot_product = np.dot(unit_vector_1, unit_vector_2) current_angle = math.degrees(np.arccos(dot_product)) if prev_pose_pred is not None: prev_pose_pred = prev_pose_pred[0] prev_vector = [prev_pose_pred[7][0] - prev_pose_pred[6][0], 0-(prev_pose_pred[7][1] - prev_pose_pred[6][1])] # flip y axis prev_unit_vector = prev_vector / np.linalg.norm(prev_vector) prev_angle_diff = math.degrees(np.arccos(np.dot(unit_vector_1, prev_unit_vector))) if prev_angle_diff > 115: return half_som_count, True # print("unit_vector_1:", unit_vector_1) # print("looking for vector:", vector2) if current_angle <= 80: half_som_count += 1 return half_som_count, False