polygons_intersection2d/
polygons_intersection2d.rs

1mod utils2d;
2
3use kiss3d::prelude::*;
4use parry2d::math::Rotation;
5use parry2d::shape::Ball;
6use parry2d::transformation::polygons_intersection_points;
7use utils2d::draw_polygon;
8
9const RENDER_SCALE: f32 = 30.0;
10
11#[kiss3d::main]
12async fn main() {
13    let mut window = Window::new("polygons_intersection2d").await;
14    let mut camera = PanZoomCamera2d::new(Vec2::ZERO, 2.0);
15    let mut scene = SceneNode2d::empty();
16    let font = Font::default();
17
18    let spikes = spikes_polygon();
19    let mut animated_spikes = spikes.clone();
20
21    let star = star_polygon();
22
23    let animation_scale = 2.0;
24    let animation_rotation = Rotation::new(0.008);
25
26    let spikes_render_pos = Vec2::new(-150.0, 0.0);
27    let star_render_pos = Vec2::new(150.0, 0.0);
28
29    let start_time = web_time::Instant::now();
30
31    while window.render_2d(&mut scene, &mut camera).await {
32        let i = (start_time.elapsed().as_secs_f32() * 60.0) as i32;
33
34        /*
35         *
36         * Compute the rotated/scaled polygons, and compute their intersection with the original
37         * polygon.
38         *
39         */
40        animated_spikes
41            .iter_mut()
42            .for_each(|pt| *pt = animation_rotation.transform_vector(*pt));
43        let spikes_intersections = polygons_intersection_points(&spikes, &animated_spikes);
44
45        let animated_star: Vec<_> = star
46            .iter()
47            .map(|pt| {
48                animation_rotation.powf(i as f32).transform_vector(*pt)
49                    * ((i as f32 / 100.0).sin().abs() * animation_scale)
50            })
51            .collect();
52
53        let star_intersections = polygons_intersection_points(&star, &animated_star);
54
55        /*
56         *
57         * Render the polygons and their intersections.
58         *
59         */
60        draw_polygon(&mut window, &spikes, RENDER_SCALE, spikes_render_pos, BLUE);
61        draw_polygon(
62            &mut window,
63            &animated_spikes,
64            RENDER_SCALE,
65            spikes_render_pos,
66            GREEN,
67        );
68
69        draw_polygon(&mut window, &star, RENDER_SCALE, star_render_pos, BLUE);
70        draw_polygon(
71            &mut window,
72            &animated_star,
73            RENDER_SCALE,
74            star_render_pos,
75            GREEN,
76        );
77
78        if let Ok(intersections) = spikes_intersections {
79            window.draw_text(
80                &format!("# spikes intersections: {}", intersections.len()),
81                Vec2::new(0.0, 15.0),
82                20.0,
83                &font,
84                WHITE,
85            );
86            for intersection in intersections {
87                draw_polygon(
88                    &mut window,
89                    &intersection,
90                    RENDER_SCALE,
91                    spikes_render_pos,
92                    RED,
93                );
94            }
95        }
96
97        if let Ok(intersections) = star_intersections {
98            window.draw_text(
99                &format!("# star intersections: {}", intersections.len()),
100                Vec2::new(0.0, 35.0),
101                20.0,
102                &font,
103                WHITE,
104            );
105            for intersection in intersections {
106                draw_polygon(
107                    &mut window,
108                    &intersection,
109                    RENDER_SCALE,
110                    star_render_pos,
111                    RED,
112                );
113            }
114        }
115    }
116}
117
118fn star_polygon() -> Vec<Vec2> {
119    let mut star = Ball::new(1.5).to_polyline(10);
120    star.iter_mut().step_by(2).for_each(|pt| *pt = *pt * 0.6);
121    star
122}
123
124fn spikes_polygon() -> Vec<Vec2> {
125    let teeths = 5;
126    let width = 10.0;
127    let height = 5.0;
128    let tooth_width = width / (teeths as f32);
129    let center = Vec2::new(width / 2.0, height / 2.0);
130
131    let mut polygon = vec![
132        Vec2::new(width, 0.0) - center,
133        Vec2::new(width, height) - center,
134        Vec2::new(0.0, height) - center,
135    ];
136
137    for i in 0..teeths {
138        let x = i as f32 * tooth_width;
139        polygon.push(Vec2::new(x, 0.0) - center);
140        polygon.push(Vec2::new(x + tooth_width / 2.0, height * 0.8) - center);
141    }
142
143    polygon
144}