diff --git a/skais/ais/ais_trajectory.py b/skais/ais/ais_trajectory.py index 70daaa2c2ae24638c64761f8ad16401099510053..3cbc82a842c873b036035ea569a253cc87f73d04 100644 --- a/skais/ais/ais_trajectory.py +++ b/skais/ais/ais_trajectory.py @@ -137,17 +137,28 @@ def compute_position_dist_std(dat, radius): return dist_means +@jit(nopython=True) +def angle_between_three_points(p1, p2, p3): + alpha = bearing(p2, p1) + beta = bearing(p2, p3) + result = alpha - beta + if result > 180: + return 180 - result + else: + return result + def compute_point_angles(dat): angles = np.zeros(dat.shape[0]) + + p1 = (dat[0][0], dat[0][1]) + p2 = (dat[1][0], dat[1][1]) + angles[0] = bearing(p1, p2) for i in range(1, dat.shape[0] - 1): p1 = (dat[i - 1][0], dat[i - 1][1]) p2 = (dat[i][0], dat[i][1]) p3 = (dat[i + 1][0], dat[i + 1][1]) - alpha = bearing(p2, p1) - beta = bearing(p2, p3) - - angles[i] = 180 - abs(abs(alpha - beta) - 180) + angles[i] = angle_between_three_points(p1, p2, p3) return angles @@ -182,6 +193,7 @@ def angle_dispersion(dat, radius): return disp + class AISTrajectory: def __init__(self, df, interpolation_time=None): df = df.drop_duplicates(subset=['ts_sec']) diff --git a/skais/tests/ais/test_ais_trajectory.py b/skais/tests/ais/test_ais_trajectory.py index d4e51ac1cc49b50ecadb223c507106fe92bddf0d..e8100e31a9b1c6051d15c7e5260eb8bfdfbd6ca3 100644 --- a/skais/tests/ais/test_ais_trajectory.py +++ b/skais/tests/ais/test_ais_trajectory.py @@ -4,7 +4,8 @@ import unittest import pandas as pd import numpy as np -from skais.ais.ais_trajectory import AISTrajectory, compute_std, to_rad, bearing, to_deg, compute_point_angles +from skais.ais.ais_trajectory import AISTrajectory, compute_std, to_rad, bearing, to_deg, compute_point_angles, \ + angle_between_three_points class TestAISTrajectory(unittest.TestCase): @@ -354,6 +355,35 @@ class TestAISTrajectory(unittest.TestCase): self.assertAlmostEqual(result, expected) + def test_angle_between_three_points_1(self): + p1 = (0, -10) + p2 = (0, 0) + p3 = (10, 0) + + self.assertAlmostEqual(90, angle_between_three_points.py_func(p1, p2, p3), places=3) + + def test_angle_between_three_points_2(self): + p1 = (0, -10) + p2 = (0, 0) + p3 = (-10, 0) + + self.assertAlmostEqual(-90, angle_between_three_points.py_func(p1, p2, p3), places=3) + + def test_angle_between_three_points_3(self): + p1 = (0, -10) + p2 = (0, 0) + p3 = (10, 10) + + self.assertAlmostEqual(180 - 44.56139, angle_between_three_points.py_func(p1, p2, p3), places=3) + + def test_angle_between_three_points_4(self): + p1 = (0, 0) + p2 = (0, 10) + p3 = (0, 0) + + self.assertAlmostEqual(0, abs(angle_between_three_points.py_func(p1, p2, p3)), places=3) + + # def test_compute_position_angle_std(self): # dat = [(0, i * 10) for i in range(5)] + [(0, 50 - i * 10) for i in range(5)] # result = compute_position_angle_std(dat, 2)