Thanks to ali_m for his solution on Stack Overflow, which we used as a starting point.
# Press the Blue Button to preview this as a CrossCompute Tool
xy_table_path = 'three-points.csv'
target_folder = '/tmp'
from pandas import read_csv
xy_table = read_csv(xy_table_path)
xy_table
if len(xy_table) < 3:
print('xy_table.error = expected at least three points')
raise AssertionError
a_xy = xy_table.iloc[0].x, xy_table.iloc[0].y
b_xy = xy_table.iloc[1].x, xy_table.iloc[1].y
c_xy = xy_table.iloc[2].x, xy_table.iloc[2].y
print(a_xy)
print(b_xy)
print(c_xy)
from shapely.geometry import GeometryCollection, LineString
g = GeometryCollection([
LineString([a_xy, b_xy]),
LineString([b_xy, c_xy]),
])
g
try:
import cairosvg
except ImportError:
import pip
pip.main(['install', 'cairosvg'])
import cairosvg
from os.path import join
target_path = join(target_folder, 'angle.png')
cairosvg.svg2png(bytestring=g._repr_svg_(), write_to=target_path)
print('angle_image_path = %s' % target_path)
import numpy as np
b_xy = np.array(b_xy)
b_xy
recentered_a_xy = a_xy - b_xy
recentered_c_xy = c_xy - b_xy
print(recentered_a_xy)
print(recentered_c_xy)
reversed_recentered_a_xy = recentered_a_xy[::-1]
reversed_recentered_c_xy = recentered_c_xy[::-1]
print(reversed_recentered_a_xy)
print(reversed_recentered_c_xy)
a_angle_in_radians = np.arctan2(*reversed_recentered_a_xy)
c_angle_in_radians = np.arctan2(*reversed_recentered_c_xy)
print(a_angle_in_radians)
print(c_angle_in_radians)
angle_in_degrees = np.rad2deg(a_angle_in_radians - c_angle_in_radians)
angle_in_degrees
if angle_in_degrees < 0:
angle_in_degrees *= -1
if angle_in_degrees > 180:
angle_in_degrees = 360 - angle_in_degrees
angle_in_degrees
if int(angle_in_degrees) == angle_in_degrees:
angle_in_degrees = int(angle_in_degrees)
print('angle_in_degrees = %s' % angle_in_degrees)