1#[allow(unused)]
4use crate::F32Ext;
5
6use core::borrow::Borrow;
7use core::ops::{Add, Div, Mul, Sub};
8
9#[derive(Copy, Clone, PartialEq, Default, Debug)]
11pub struct Angle(f32);
12
13impl Angle {
14 pub const ZERO: Self = Self(0.);
16
17 pub fn from_degrees(degrees: f32) -> Self {
19 Self(degrees * core::f32::consts::PI / 180.)
20 }
21
22 pub fn from_radians(radians: f32) -> Self {
24 Self(radians)
25 }
26
27 pub fn from_gradians(gradians: f32) -> Self {
29 Self::from_degrees(gradians / 400. * 360.)
30 }
31
32 pub fn from_turns(turns: f32) -> Self {
34 Self::from_degrees(turns * 360.)
35 }
36
37 pub fn to_radians(self) -> f32 {
39 self.0
40 }
41
42 pub fn to_degrees(self) -> f32 {
44 self.0 * 180. / core::f32::consts::PI
45 }
46}
47
48#[derive(Copy, Clone, PartialEq, Default, Debug)]
50pub struct Vector {
51 pub x: f32,
52 pub y: f32,
53}
54
55impl Vector {
56 pub const ZERO: Self = Self { x: 0., y: 0. };
58
59 #[inline]
61 pub const fn new(x: f32, y: f32) -> Self {
62 Self { x, y }
63 }
64
65 #[inline]
67 pub fn length(self) -> f32 {
68 (self.x * self.x + self.y * self.y).sqrt()
69 }
70
71 #[inline]
73 pub fn length_squared(self) -> f32 {
74 self.x * self.x + self.y * self.y
75 }
76
77 #[inline]
79 pub fn distance_to(self, other: Self) -> f32 {
80 (self - other).length()
81 }
82
83 #[inline]
85 pub fn dot(self, other: Self) -> f32 {
86 self.x * other.x + self.y * other.y
87 }
88
89 #[inline]
91 pub fn cross(self, other: Self) -> f32 {
92 self.x * other.y - self.y * other.x
93 }
94
95 #[inline]
97 pub fn normalize(self) -> Self {
98 let length = self.length();
99 if length == 0. {
100 return Self::new(0., 0.);
101 }
102 let inverse = 1. / length;
103 Self::new(self.x * inverse, self.y * inverse)
104 }
105
106 pub fn ceil(self) -> Self {
109 Self::new(self.x.ceil(), self.y.ceil())
110 }
111
112 pub fn floor(self) -> Self {
115 Self::new(self.x.floor(), self.y.floor())
116 }
117
118 pub fn angle_to(self, other: Self) -> Angle {
120 Angle::from_radians(self.cross(other).atan2(self.dot(other)))
121 }
122
123 #[inline]
126 pub fn nearly_eq(self, other: Vector) -> bool {
127 self.nearly_eq_by(other, f32::EPSILON)
128 }
129
130 #[inline]
133 pub fn nearly_eq_by(self, other: Vector, epsilon: f32) -> bool {
134 (self.x - other.x).abs() < epsilon && (self.y - other.y).abs() < epsilon
135 }
136}
137
138impl Add for Vector {
139 type Output = Self;
140 #[inline]
141 fn add(self, rhs: Self) -> Self {
142 Self::new(self.x + rhs.x, self.y + rhs.y)
143 }
144}
145
146impl Sub for Vector {
147 type Output = Self;
148 #[inline]
149 fn sub(self, rhs: Self) -> Self {
150 Self::new(self.x - rhs.x, self.y - rhs.y)
151 }
152}
153
154impl Mul for Vector {
155 type Output = Self;
156 #[inline]
157 fn mul(self, rhs: Self) -> Self {
158 Self::new(self.x * rhs.x, self.y * rhs.y)
159 }
160}
161
162impl Mul<f32> for Vector {
163 type Output = Self;
164 #[inline]
165 fn mul(self, rhs: f32) -> Self {
166 Self::new(self.x * rhs, self.y * rhs)
167 }
168}
169
170impl Div for Vector {
171 type Output = Self;
172 #[inline]
173 fn div(self, rhs: Self) -> Self {
174 Self::new(self.x / rhs.x, self.y / rhs.y)
175 }
176}
177
178impl Div<f32> for Vector {
179 type Output = Self;
180 #[inline]
181 fn div(self, rhs: f32) -> Self {
182 let s = 1. / rhs;
183 Self::new(self.x * s, self.y * s)
184 }
185}
186
187impl From<[f32; 2]> for Vector {
188 fn from(v: [f32; 2]) -> Self {
189 Self::new(v[0], v[1])
190 }
191}
192
193impl From<[i32; 2]> for Vector {
194 fn from(v: [i32; 2]) -> Self {
195 Self::new(v[0] as f32, v[1] as f32)
196 }
197}
198
199impl From<(f32, f32)> for Vector {
200 fn from(v: (f32, f32)) -> Self {
201 Self::new(v.0, v.1)
202 }
203}
204
205impl From<(i32, i32)> for Vector {
206 fn from(v: (i32, i32)) -> Self {
207 Self::new(v.0 as f32, v.1 as f32)
208 }
209}
210
211impl From<(f32, i32)> for Vector {
212 fn from(v: (f32, i32)) -> Self {
213 Self::new(v.0, v.1 as f32)
214 }
215}
216
217impl From<(i32, f32)> for Vector {
218 fn from(v: (i32, f32)) -> Self {
219 Self::new(v.0 as f32, v.1)
220 }
221}
222
223impl From<f32> for Vector {
224 fn from(x: f32) -> Self {
225 Self::new(x, x)
226 }
227}
228
229impl From<i32> for Vector {
230 fn from(x: i32) -> Self {
231 let x = x as f32;
232 Self::new(x, x)
233 }
234}
235
236impl From<Vector> for [f32; 2] {
237 fn from(v: Vector) -> Self {
238 [v.x, v.y]
239 }
240}
241
242impl From<Vector> for (f32, f32) {
243 fn from(v: Vector) -> Self {
244 (v.x, v.y)
245 }
246}
247
248pub type Point = Vector;
250
251#[inline(always)]
252pub(super) fn normal(start: Vector, end: Vector) -> Vector {
253 Vector::new(end.y - start.y, -(end.x - start.x)).normalize()
254}
255
256#[derive(Copy, Clone, Default, Debug)]
258pub struct Transform {
259 pub xx: f32,
260 pub xy: f32,
261 pub yx: f32,
262 pub yy: f32,
263 pub x: f32,
264 pub y: f32,
265}
266
267impl Transform {
268 pub const IDENTITY: Self = Self {
270 xx: 1.,
271 xy: 0.,
272 yy: 1.,
273 yx: 0.,
274 x: 0.,
275 y: 0.,
276 };
277
278 pub fn new(xx: f32, xy: f32, yx: f32, yy: f32, x: f32, y: f32) -> Self {
280 Self {
281 xx,
282 xy,
283 yx,
284 yy,
285 x,
286 y,
287 }
288 }
289
290 pub fn translation(x: f32, y: f32) -> Self {
292 Self::new(1., 0., 0., 1., x, y)
293 }
294
295 pub fn rotation(angle: Angle) -> Self {
297 let (sin, cos) = angle.0.sin_cos();
298 Self {
299 xx: cos,
300 xy: sin,
301 yx: -sin,
302 yy: cos,
303 x: 0.,
304 y: 0.,
305 }
306 }
307
308 pub fn rotation_about(point: impl Into<Point>, angle: Angle) -> Self {
310 let p = point.into();
311 Self::translation(p.x, p.y)
312 .then_rotate(angle)
313 .then_translate(-p.x, -p.y)
314 }
315
316 pub fn scale(x: f32, y: f32) -> Self {
318 Self::new(x, 0., 0., y, 0., 0.)
319 }
320
321 pub fn skew(x: Angle, y: Angle) -> Self {
323 Self {
324 xx: 1.,
325 xy: y.0.tan(),
326 yx: x.0.tan(),
327 yy: 1.,
328 x: 0.,
329 y: 0.,
330 }
331 }
332
333 fn combine(a: &Transform, b: &Transform) -> Self {
334 let xx = a.xx * b.xx + a.yx * b.xy;
335 let yx = a.xx * b.yx + a.yx * b.yy;
336 let xy = a.xy * b.xx + a.yy * b.xy;
337 let yy = a.xy * b.yx + a.yy * b.yy;
338 let x = a.x * b.xx + a.y * b.xy + b.x;
339 let y = a.x * b.yx + a.y * b.yy + b.y;
340 Self {
341 xx,
342 yx,
343 xy,
344 yy,
345 x,
346 y,
347 }
348 }
349
350 pub fn then(&self, other: &Transform) -> Self {
353 Self::combine(self, other)
354 }
355
356 pub fn pre_translate(&self, x: f32, y: f32) -> Self {
359 Self::combine(&Self::translation(x, y), self)
360 }
361
362 pub fn then_translate(&self, x: f32, y: f32) -> Self {
365 let mut t = *self;
366 t.x += x;
367 t.y += y;
368 t
369 }
370
371 pub fn pre_rotate(&self, angle: Angle) -> Self {
374 Self::combine(&Self::rotation(angle), self)
375 }
376
377 pub fn then_rotate(&self, angle: Angle) -> Self {
380 Self::combine(self, &Self::rotation(angle))
381 }
382
383 pub fn pre_scale(&self, x: f32, y: f32) -> Self {
386 Self::combine(&Self::scale(x, y), self)
387 }
388
389 pub fn then_scale(&self, x: f32, y: f32) -> Self {
392 Self::combine(self, &Self::scale(x, y))
393 }
394
395 pub fn determinant(&self) -> f32 {
397 self.xx * self.yy - self.yx * self.xy
398 }
399
400 pub fn invert(&self) -> Option<Transform> {
402 let det = self.determinant();
403 if !det.is_finite() || det == 0. {
404 return None;
405 }
406 let s = 1. / det;
407 let a = self.xx;
408 let b = self.xy;
409 let c = self.yx;
410 let d = self.yy;
411 let x = self.x;
412 let y = self.y;
413 Some(Transform {
414 xx: d * s,
415 xy: -b * s,
416 yx: -c * s,
417 yy: a * s,
418 x: (b * y - d * x) * s,
419 y: (c * x - a * y) * s,
420 })
421 }
422
423 #[inline(always)]
425 pub fn transform_point(&self, point: Point) -> Point {
426 Vector {
427 x: (point.x * self.xx + point.y * self.yx) + self.x,
428 y: (point.x * self.xy + point.y * self.yy) + self.y,
429 }
430 }
431
432 #[inline(always)]
434 pub fn transform_vector(&self, vector: Vector) -> Vector {
435 Vector {
436 x: (vector.x * self.xx + vector.y * self.yx),
437 y: (vector.x * self.xy + vector.y * self.yy),
438 }
439 }
440}
441
442#[derive(Copy, Clone, PartialEq, Eq, Debug)]
444pub enum Origin {
445 TopLeft,
447 BottomLeft,
449}
450
451impl Default for Origin {
452 fn default() -> Self {
453 Self::TopLeft
454 }
455}
456
457#[derive(Copy, Clone, Debug, Default)]
459pub struct Placement {
460 pub left: i32,
463 pub top: i32,
466 pub width: u32,
468 pub height: u32,
470}
471
472impl Placement {
473 pub fn compute(
476 origin: Origin,
477 offset: impl Into<Vector>,
478 bounds: &Bounds,
479 ) -> (Vector, Placement) {
480 let offset = offset.into();
481 let mut bounds = *bounds;
482 bounds.min = (bounds.min + offset).floor();
483 bounds.max = (bounds.max + offset).ceil();
484 let offset = Vector::new(-bounds.min.x, -bounds.min.y);
485 let width = bounds.width() as u32;
486 let height = bounds.height() as u32;
487 let left = -offset.x as i32;
488 let top = if origin == Origin::BottomLeft {
489 (-offset.y).floor() + height as f32
490 } else {
491 -offset.y
492 } as i32;
493 (
494 offset,
495 Placement {
496 left,
497 top,
498 width,
499 height,
500 },
501 )
502 }
503}
504
505#[derive(Copy, Clone, Default, Debug)]
507pub struct Bounds {
508 pub min: Point,
509 pub max: Point,
510}
511
512impl Bounds {
513 pub fn new(min: Point, max: Point) -> Self {
515 Self { min, max }
516 }
517
518 pub fn from_points<I>(points: I) -> Self
520 where
521 I: IntoIterator,
522 I::Item: Borrow<Point>,
523 {
524 let mut b = BoundsBuilder::new();
525 for p in points {
526 b.add(*p.borrow());
527 }
528 b.build()
529 }
530
531 pub fn is_empty(&self) -> bool {
533 self.min.x >= self.max.x || self.min.y >= self.max.y
534 }
535
536 pub fn width(&self) -> f32 {
538 self.max.x - self.min.x
539 }
540
541 pub fn height(&self) -> f32 {
543 self.max.y - self.min.y
544 }
545
546 pub fn contains(&self, point: impl Into<Point>) -> bool {
548 let p = point.into();
549 p.x > self.min.x && p.x < self.max.x && p.y > self.min.y && p.y < self.max.y
550 }
551}
552
553pub(super) struct BoundsBuilder {
554 pub count: usize,
555 #[allow(dead_code)]
556 pub start: Point,
557 pub current: Point,
558 pub min: Point,
559 pub max: Point,
560}
561
562impl BoundsBuilder {
563 pub fn new() -> Self {
564 Self {
565 count: 0,
566 start: Point::ZERO,
567 current: Point::ZERO,
568 min: Point::new(f32::MAX, f32::MAX),
569 max: Point::new(f32::MIN, f32::MIN),
570 }
571 }
572
573 pub fn add(&mut self, p: Point) -> &mut Self {
574 let x = p.x;
575 let y = p.y;
576 if x < self.min.x {
577 self.min.x = x;
578 }
579 if x > self.max.x {
580 self.max.x = x;
581 }
582 if y < self.min.y {
583 self.min.y = y;
584 }
585 if y > self.max.y {
586 self.max.y = y;
587 }
588 self.count += 1;
589 self
590 }
591
592 pub fn build(&self) -> Bounds {
593 if self.count != 0 {
594 Bounds {
595 min: self.min,
596 max: self.max,
597 }
598 } else {
599 Bounds::default()
600 }
601 }
602}