Skip to content

Instantly share code, notes, and snippets.

@rene-d
Last active November 20, 2024 07:16
Show Gist options
  • Save rene-d/67d2d36e143e753de4f459e00b6f5565 to your computer and use it in GitHub Desktop.
Save rene-d/67d2d36e143e753de4f459e00b6f5565 to your computer and use it in GitHub Desktop.
#!/usr/bin/env python3
import os
import typing as t
from dataclasses import dataclass
from pathlib import Path
import gpxpy.gpx
import matplotlib.pyplot as plt
import numpy as np
from geopy.distance import geodesic, great_circle
from scipy import optimize
@dataclass
class Position:
rank: int
"""Rank."""
boat: int
"""Boat ID."""
pos: t.Tuple[float, float]
"""(latitude,longitude)."""
dtf: float
"""Distance To Finish."""
# situation à 2024-11-19 18:00:00Z
boats = [
(1, 100, (11.38819, -29.69734), 21898.62),
(2, 112, (12.29817, -28.87315), 21942.12),
(3, 59, (11.90237, -32.12561), 21962.91),
(4, 79, (12.33021, -30.47561), 21963.93),
(5, 29, (13.31248, -23.19468), 21981.4),
(6, 85, (12.46197, -31.18362), 21981.4),
(7, 24, (12.83107, -30.36251), 21991.72),
(8, 17, (13.03418, -29.82524), 21996.75),
(9, 109, (13.12718, -29.47032), 21997.88),
(10, 3, (13.04665, -30.4648), 22005.68),
(11, 15, (13.24158, -29.79702), 22008.57),
(12, 8, (13.36931, -30.3552), 22023.13),
(13, 2030, (13.55294, -31.22079), 22045.5),
(14, 13, (15.01302, -29.69932), 22111.45),
(15, 9, (14.75602, -31.11975), 22114.32),
(16, 777, (14.6393, -31.84201), 22117.56),
(17, 1297, (15.30331, -31.1623), 22146.86),
(18, 64, (15.5461, -20.21022), 22150.58),
(19, 83, (15.86659, -28.71502), 22150.83),
(20, 10, (15.2953, -31.69812), 22153.72),
(21, 5, (16.07474, -28.7498), 22163.48),
(22, 30, (16.10143, -29.05133), 22168.25),
(23, 14, (16.23872, -28.53493), 22170.96),
(24, 27, (15.83012, -30.84266), 22173.47),
(25, 18, (16.03118, -30.41587), 22179.88),
(26, 172, (16.01677, -31.02538), 22186.76),
(27, 1000, (16.36148, -30.19907), 22196.62),
(28, 34, (17.06822, -27.10704), 22207.26),
(29, 1461, (17.02256, -27.80812), 22210.35),
(30, 1, (16.83, -29.30191), 22213.93),
(31, 22, (16.82604, -30.60685), 22228.85),
(32, 56, (17.32101, -28.82298), 22237.85),
(33, 1101, (17.11098, -30.76336), 22247.49),
(34, 7, (18.10653, -27.17554), 22269.61),
(35, 71, (17.9222, -30.9677), 22297.58),
(36, 49, (20.08421, -26.79358), 22385.4),
(37, 26, (20.27418, -30.45783), 22429.58),
(38, 5005, (21.44229, -27.90038), 22473.51),
(39, 23, (26.48877, -15.8225), 22851.54),
(40, 53, (39.20913, -13.00027), 23619.75),
]
boats = [Position(*p) for p in boats]
leader = boats[0]
# dtl = dtf - min(dtf)
# min(dtf) <=> leader
def dist_to_leader(boat, marque):
# return (great_circle(marque, boat.pos).meters - great_circle(marque, leader.pos).meters) / 1852
return (geodesic(marque, boat.pos).meters - geodesic(marque, leader.pos).meters) / 1852
def dichotomie(lat, lon_a, lon_b, d_cible, boat):
while (lon_b - lon_a) > 0.1:
lon = (lon_a + lon_b) / 2
d = dist_to_leader(boat, (lat, lon))
if d <= d_cible:
lon_b = lon
else:
lon_a = lon
lon = round((lon_a + lon_b) / 2, 6)
return (lat, lon)
marque = (-34.994004, 19.335938) # Le Cap
marque = (-4.313546, -25.587158)
for boat in boats[1:]:
dtl_calc = dist_to_leader(boat, marque)
dtl = boat.dtf - leader.dtf
e = round(abs(dtl_calc - dtl) / dtl * 100, 1)
print(f"{boat.boat:4} {dtl_calc:8.3f} {dtl:8.3f} {e:g}")
exit()
for i in range(35, 40):
boat = boats[i]
gpx = gpxpy.gpx.GPX()
gpx_track = gpxpy.gpx.GPXTrack(name="test")
gpx.tracks.append(gpx_track)
gpx_segment = gpxpy.gpx.GPXTrackSegment()
gpx_track.segments.append(gpx_segment)
lon_w = -45
lon_e = 22
lon = (lon_w + lon_e) / 2
for lat in range(-32, 8, 4):
######
def f(lon):
return dist_to_leader(boat, (lat, lon))
dtl = boat.dtf - leader.dtf
x = np.linspace(lon_w, lon_e, 100)
y = [f(lon) for lon in x]
plt.plot(x, y, color="red")
plt.axhline(y=dtl, color="blue", linestyle="-")
plt.show()
roots = optimize.fsolve(lambda x: f(x) - dtl, lon)
lon = roots[0]
######
print(f"{lat},{lon}")
gpx_segment.points.append(gpxpy.gpx.GPXTrackPoint(lat, lon))
Path(f"hyperboule{i}.gpx").write_text(gpx.to_xml())
os.system(f"open -a GPXSee dicho{i}.gpx")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment