import { type LatLng, bearingDegrees, haversineMeters } from "./geo" /** * Projiserer et vilkårlig punkt ned på en fast akse (typisk tee->green), * for et hull-diagram der "langs hullet" og "til siden" skal vises * uavhengig av spillerens gangretning -- ren klientberegning, ingen * Mapbox-kall (samme ADR-048-kostnadskontroll-prinsipp som geo.ts). * * `alongPercent`: 0 ved axisStart, 100 ved axisEnd -- IKKE klippet her * (kan bli <0 eller >100 hvis punktet ligger bak start/forbi slutt), * klipping skjer kun ved selve visningen. * `crossMeters`: avstand til siden av aksen. Positiv = til høyre for * aksens retning (sett fra axisStart mot axisEnd), negativ = venstre -- * samme klokke-positive konvensjon som bearingDegrees. */ export function projectOntoAxis( axisStart: LatLng, axisEnd: LatLng, point: LatLng, ): { alongPercent: number; crossMeters: number } { const axisLength = haversineMeters(axisStart, axisEnd) if (axisLength === 0) { return { alongPercent: 0, crossMeters: haversineMeters(axisStart, point) } } const axisBearing = bearingDegrees(axisStart, axisEnd) const pointDistance = haversineMeters(axisStart, point) const pointBearing = bearingDegrees(axisStart, point) // Normaliser vinkeldifferansen til (-180, 180] før trigonometri. const angleDiff = (((pointBearing - axisBearing + 540) % 360) - 180) * (Math.PI / 180) const along = pointDistance * Math.cos(angleDiff) const cross = pointDistance * Math.sin(angleDiff) return { alongPercent: (along / axisLength) * 100, crossMeters: cross } } /** Midtpunkt mellom to koordinater (enkel plan-tilnærming -- presist nok * på hull-skala, samme antakelse som resten av geo.ts). */ export function midpoint(a: LatLng, b: LatLng): LatLng { return { lat: (a.lat + b.lat) / 2, lng: (a.lng + b.lng) / 2 } }