Skip to main content

agg_rust/
trans_polar.rs

1//! Polar coordinate transformation.
2//!
3//! Port of the `trans_polar` class from `examples/trans_polar.cpp`.
4//! Converts rectangular coordinates to polar (spiral) coordinates.
5
6use crate::span_interpolator_linear::Transformer;
7
8/// Polar coordinate transformation.
9///
10/// Maps rectangular coordinates to polar space, optionally with spiral effect.
11#[derive(Clone, Copy)]
12pub struct TransPolar {
13    pub base_angle: f64,
14    pub base_scale: f64,
15    pub base_x: f64,
16    pub base_y: f64,
17    pub translation_x: f64,
18    pub translation_y: f64,
19    pub spiral: f64,
20}
21
22impl TransPolar {
23    pub fn new() -> Self {
24        Self {
25            base_angle: 1.0,
26            base_scale: 1.0,
27            base_x: 0.0,
28            base_y: 0.0,
29            translation_x: 0.0,
30            translation_y: 0.0,
31            spiral: 0.0,
32        }
33    }
34}
35
36impl Transformer for TransPolar {
37    fn transform(&self, x: &mut f64, y: &mut f64) {
38        let x1 = (*x + self.base_x) * self.base_angle;
39        let y1 = (*y + self.base_y) * self.base_scale + (*x * self.spiral);
40        *x = x1.cos() * y1 + self.translation_x;
41        *y = x1.sin() * y1 + self.translation_y;
42    }
43}
44
45#[cfg(test)]
46mod tests {
47    use super::*;
48
49    #[test]
50    fn test_origin_transform() {
51        let t = TransPolar::new();
52        let (mut x, mut y) = (0.0, 0.0);
53        t.transform(&mut x, &mut y);
54        assert!((x - 0.0).abs() < 1e-10);
55        assert!((y - 0.0).abs() < 1e-10);
56    }
57
58    #[test]
59    fn test_nonzero_transform() {
60        let mut t = TransPolar::new();
61        t.base_angle = std::f64::consts::PI / 180.0;
62        t.base_scale = 1.0;
63        t.translation_x = 200.0;
64        t.translation_y = 200.0;
65
66        let (mut x, mut y) = (90.0, 100.0);
67        t.transform(&mut x, &mut y);
68        // At 90 degrees: cos(pi/2) ≈ 0, sin(pi/2) ≈ 1
69        // x = cos(90 * pi/180) * 100 + 200 ≈ 200
70        // y = sin(90 * pi/180) * 100 + 200 ≈ 300
71        assert!((x - 200.0).abs() < 1.0);
72        assert!((y - 300.0).abs() < 1.0);
73    }
74}