Skip to content

Instantly share code, notes, and snippets.

@JohnDowson
Last active November 30, 2023 08:10
Show Gist options
  • Save JohnDowson/38ece155a33f3cf9131ee116fa334fc5 to your computer and use it in GitHub Desktop.
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
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