dear_imgui_rs/utils/
geometry.rs1use crate::sys;
2
3impl crate::ui::Ui {
4 #[doc(alias = "GetCursorScreenPos")]
6 pub fn get_cursor_screen_pos(&self) -> [f32; 2] {
7 let pos = self.run_with_bound_context(|| unsafe { sys::igGetCursorScreenPos() });
8 [pos.x, pos.y]
9 }
10
11 #[doc(alias = "GetContentRegionAvail")]
13 pub fn get_content_region_avail(&self) -> [f32; 2] {
14 let size = self.run_with_bound_context(|| unsafe { sys::igGetContentRegionAvail() });
15 [size.x, size.y]
16 }
17
18 pub fn is_point_in_rect(
20 &self,
21 point: [f32; 2],
22 rect_min: [f32; 2],
23 rect_max: [f32; 2],
24 ) -> bool {
25 point[0] >= rect_min[0]
26 && point[0] <= rect_max[0]
27 && point[1] >= rect_min[1]
28 && point[1] <= rect_max[1]
29 }
30
31 pub fn distance(&self, p1: [f32; 2], p2: [f32; 2]) -> f32 {
33 let dx = p2[0] - p1[0];
34 let dy = p2[1] - p1[1];
35 (dx * dx + dy * dy).sqrt()
36 }
37
38 pub fn distance_squared(&self, p1: [f32; 2], p2: [f32; 2]) -> f32 {
40 let dx = p2[0] - p1[0];
41 let dy = p2[1] - p1[1];
42 dx * dx + dy * dy
43 }
44
45 pub fn line_segments_intersect(
47 &self,
48 p1: [f32; 2],
49 p2: [f32; 2],
50 p3: [f32; 2],
51 p4: [f32; 2],
52 ) -> bool {
53 let d1 = self.cross_product(
54 [p4[0] - p3[0], p4[1] - p3[1]],
55 [p1[0] - p3[0], p1[1] - p3[1]],
56 );
57 let d2 = self.cross_product(
58 [p4[0] - p3[0], p4[1] - p3[1]],
59 [p2[0] - p3[0], p2[1] - p3[1]],
60 );
61 let d3 = self.cross_product(
62 [p2[0] - p1[0], p2[1] - p1[1]],
63 [p3[0] - p1[0], p3[1] - p1[1]],
64 );
65 let d4 = self.cross_product(
66 [p2[0] - p1[0], p2[1] - p1[1]],
67 [p4[0] - p1[0], p4[1] - p1[1]],
68 );
69
70 (d1 > 0.0) != (d2 > 0.0) && (d3 > 0.0) != (d4 > 0.0)
71 }
72
73 fn cross_product(&self, v1: [f32; 2], v2: [f32; 2]) -> f32 {
75 v1[0] * v2[1] - v1[1] * v2[0]
76 }
77
78 pub fn normalize(&self, v: [f32; 2]) -> [f32; 2] {
80 let len = (v[0] * v[0] + v[1] * v[1]).sqrt();
81 if len > f32::EPSILON {
82 [v[0] / len, v[1] / len]
83 } else {
84 [0.0, 0.0]
85 }
86 }
87
88 pub fn dot_product(&self, v1: [f32; 2], v2: [f32; 2]) -> f32 {
90 v1[0] * v2[0] + v1[1] * v2[1]
91 }
92
93 pub fn angle_between_vectors(&self, v1: [f32; 2], v2: [f32; 2]) -> f32 {
95 let dot = self.dot_product(v1, v2);
96 let len1 = (v1[0] * v1[0] + v1[1] * v1[1]).sqrt();
97 let len2 = (v2[0] * v2[0] + v2[1] * v2[1]).sqrt();
98
99 if len1 > f32::EPSILON && len2 > f32::EPSILON {
100 (dot / (len1 * len2)).acos()
101 } else {
102 0.0
103 }
104 }
105
106 pub fn is_point_in_circle(&self, point: [f32; 2], center: [f32; 2], radius: f32) -> bool {
108 self.distance_squared(point, center) <= radius * radius
109 }
110
111 pub fn triangle_area(&self, p1: [f32; 2], p2: [f32; 2], p3: [f32; 2]) -> f32 {
113 let cross = self.cross_product(
114 [p2[0] - p1[0], p2[1] - p1[1]],
115 [p3[0] - p1[0], p3[1] - p1[1]],
116 );
117 cross.abs() * 0.5
118 }
119}