61 lines
2.5 KiB
Text
61 lines
2.5 KiB
Text
# 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(compass_st: CompassState) -> int {
|
|
if compass_st.cmp_list == null { return 0 }
|
|
return len(compass_st.cmp_list)
|
|
}
|
|
|
|
# the i-th mark, or an empty one past the end
|
|
export function compass_at(compass_st: CompassState, i: int) -> CompassMark {
|
|
if i < 0 or i >= compass_count(compass_st) { return new CompassMark }
|
|
return compass_st.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(compass_st: CompassState, i: int) -> float {
|
|
let m = compass_at(compass_st, i)
|
|
return compass_bearing_to(m.x, m.z)
|
|
}
|
|
|
|
export function compass_dist(compass_st: CompassState, i: int) -> float {
|
|
let m = compass_at(compass_st, 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(compass_st: CompassState) -> int {
|
|
for i in 0 .. compass_count(compass_st) { if compass_st.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
|
|
}
|