feat(packages): ludic.compass - bearing marks on a strip: marks gathered once a frame from an open registry of providers (CompassProviders), gated by the viewer's tier, sorted tracked / note / plain and culled to a cap; bearings and distances off the viewer's facing, the tracked mark, a capture that lets a guide hear the providers whatever the tier, the eight points, and the radar's range per tier with blips on a unit disc; the viewer through a port
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
dc71fc986c
commit
1005a677f2
10 changed files with 453 additions and 0 deletions
61
packages/ludic.compass/bearing.ludic
Normal file
61
packages/ludic.compass/bearing.ludic
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
# bearing.ludic - the frame's marks as the strip reads them: how many, each one, where it bears
|
||||
# from the viewer's facing and how far it is. A heading is the world's (0 toward -z, a quarter
|
||||
# turn toward -x), a bearing is the heading less the viewer's yaw, in -pi .. pi.
|
||||
export function compass_count() -> int {
|
||||
if cmp_list == null { return 0 }
|
||||
return len(cmp_list)
|
||||
}
|
||||
|
||||
# the i-th mark, or an empty one past the end
|
||||
export function compass_at(i: int) -> CompassMark {
|
||||
if i < 0 or i >= compass_count() { return new CompassMark }
|
||||
return cmp_list[i]
|
||||
}
|
||||
|
||||
export function compass_wrap(a: float) -> float {
|
||||
var r = a
|
||||
let turn = 2.0 * CMP_PI
|
||||
while r > CMP_PI { r -= turn }
|
||||
while r < -CMP_PI { r += turn }
|
||||
return r
|
||||
}
|
||||
|
||||
export function compass_heading(dx: float, dz: float) -> float { return Math.atan2(-dx, -dz) }
|
||||
|
||||
# a world heading as the strip sees it
|
||||
export function compass_rel(heading: float) -> float { return compass_wrap(heading - CompassWorld.yaw()) }
|
||||
|
||||
export function compass_bearing_to(x: float, z: float) -> float { return compass_rel(compass_heading(x - CompassWorld.x(), z - CompassWorld.z())) }
|
||||
|
||||
export function compass_dist_to(x: float, z: float) -> float {
|
||||
let dx = x - CompassWorld.x()
|
||||
let dz = z - CompassWorld.z()
|
||||
return Math.sqrt(dx * dx + dz * dz)
|
||||
}
|
||||
|
||||
export function compass_bearing(i: int) -> float {
|
||||
let m = compass_at(i)
|
||||
return compass_bearing_to(m.x, m.z)
|
||||
}
|
||||
|
||||
export function compass_dist(i: int) -> float {
|
||||
let m = compass_at(i)
|
||||
return compass_dist_to(m.x, m.z)
|
||||
}
|
||||
|
||||
# where a bearing falls across a strip showing `half` radians either side: -1 .. 1, or past it
|
||||
export function compass_strip_t(bearing: float, half: float) -> float { return bearing / Math.max(half, 0.001) }
|
||||
|
||||
# the objective: the first tracked mark of the frame, or -1
|
||||
export function compass_tracked() -> int {
|
||||
for i in 0 .. compass_count() { if cmp_list[i].prio >= COMPASS_TRACKED { return i } }
|
||||
return -1
|
||||
}
|
||||
|
||||
# which of eight points an offset lies toward: 0 the heading 0, then a quarter turn in two steps
|
||||
# at a time toward -x (for a world where 0 is north: N, NW, W, SW, S, SE, E, NE)
|
||||
export function compass_octant(dx: float, dz: float) -> int {
|
||||
var deg = compass_heading(dx, dz) * 180.0 / CMP_PI
|
||||
if deg < 0.0 { deg += 360.0 }
|
||||
return int(Math.floor(deg / 45.0 + 0.5)) % 8
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue