Last active
November 30, 2023 08:10
-
-
Save JohnDowson/38ece155a33f3cf9131ee116fa334fc5 to your computer and use it in GitHub Desktop.
Get N point catenary approximation given attachment points, tension and mass per length unit
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
pub fn catenary(start: Pos2, end: Pos2, h: f32, m: f32, n: usize) -> impl Iterator<Item = Pos2> { | |
fn find_t0(k: f32, c: f32) -> f32 { | |
if c == 0.0 { | |
return 0.5; | |
} | |
let a = k.cosh(); | |
let b = k.sinh(); | |
let d = 1.0 - (a - b); | |
let r = (c * c + b * b - a * a + a + a - 1.0).sqrt(); | |
((r - c) / d).ln() / k | |
} | |
let w = (end.x - start.x).abs().sqrt(); | |
let a = (h * w.ln()) / (m * w.ln()); | |
let a = -a; // invert gravity because in egui +y is down | |
let k = w / a.abs(); | |
let c = (end.y - start.y) / a; | |
let t0 = find_t0(k, c); | |
let y0 = start.y - a * (-w * t0 / a).cosh(); | |
(0..=n).map(move |i| { | |
let t = i as f32 / n as f32; | |
let x = (1.0 - t) * start.x + t * end.x; | |
let y = y0 + a * (w * (t - t0) / a).cosh(); | |
pos2(x, y) | |
}) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment