1use core::{
13 fmt,
14 ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign},
15};
16
17#[derive(Clone, Copy, Debug, PartialEq)]
19#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
20#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
21#[repr(C)]
22pub struct Affine([f64; 6]);
23
24impl Affine {
25 pub const IDENTITY: Affine = Affine::scale(1.0);
27
28 pub const FLIP_Y: Affine = Affine::new([1.0, 0., 0., -1.0, 0., 0.]);
31
32 pub const FLIP_X: Affine = Affine::new([-1.0, 0., 0., 1.0, 0., 0.]);
34
35 #[inline]
53 pub const fn new(c: [f64; 6]) -> Affine {
54 Affine(c)
55 }
56
57 #[inline]
59 pub const fn scale(s: f64) -> Affine {
60 Affine([s, 0.0, 0.0, s, 0.0, 0.0])
61 }
62
63 #[inline]
66 pub const fn scale_non_uniform(s_x: f64, s_y: f64) -> Affine {
67 Affine([s_x, 0.0, 0.0, s_y, 0.0, 0.0])
68 }
69
70 #[inline]
72 pub fn translate<V: Into<Vec2>>(p: V) -> Affine {
73 let p = p.into();
74 Affine([1.0, 0.0, 0.0, 1.0, p.x, p.y])
75 }
76
77 pub fn map_unit_square(rect: Rect) -> Affine {
82 Affine([rect.width(), 0., 0., rect.height(), rect.x0, rect.y0])
83 }
84
85 #[inline]
87 pub fn as_coeffs(self) -> [f64; 6] {
88 self.0
89 }
90
91 pub fn determinant(self) -> f64 {
93 self.0[0] * self.0[3] - self.0[1] * self.0[2]
94 }
95
96 pub fn inverse(self) -> Affine {
100 let inv_det = self.determinant().recip();
101 Affine([
102 inv_det * self.0[3],
103 -inv_det * self.0[1],
104 -inv_det * self.0[2],
105 inv_det * self.0[0],
106 inv_det * (self.0[2] * self.0[5] - self.0[3] * self.0[4]),
107 inv_det * (self.0[1] * self.0[4] - self.0[0] * self.0[5]),
108 ])
109 }
110
111 pub fn transform_rect_bbox(self, rect: Rect) -> Rect {
119 let p00 = self * Point::new(rect.x0, rect.y0);
120 let p01 = self * Point::new(rect.x0, rect.y1);
121 let p10 = self * Point::new(rect.x1, rect.y0);
122 let p11 = self * Point::new(rect.x1, rect.y1);
123 Rect::from_points(p00, p01).union(Rect::from_points(p10, p11))
124 }
125
126 #[inline]
128 pub fn is_finite(&self) -> bool {
129 self.0[0].is_finite()
130 && self.0[1].is_finite()
131 && self.0[2].is_finite()
132 && self.0[3].is_finite()
133 && self.0[4].is_finite()
134 && self.0[5].is_finite()
135 }
136
137 #[inline]
139 pub fn is_nan(&self) -> bool {
140 self.0[0].is_nan()
141 || self.0[1].is_nan()
142 || self.0[2].is_nan()
143 || self.0[3].is_nan()
144 || self.0[4].is_nan()
145 || self.0[5].is_nan()
146 }
147}
148
149impl Default for Affine {
150 #[inline]
151 fn default() -> Affine {
152 Affine::IDENTITY
153 }
154}
155
156impl Mul<Point> for Affine {
157 type Output = Point;
158
159 #[inline]
160 fn mul(self, other: Point) -> Point {
161 Point::new(
162 self.0[0] * other.x + self.0[2] * other.y + self.0[4],
163 self.0[1] * other.x + self.0[3] * other.y + self.0[5],
164 )
165 }
166}
167
168impl Mul for Affine {
169 type Output = Affine;
170
171 #[inline]
172 fn mul(self, other: Affine) -> Affine {
173 Affine([
174 self.0[0] * other.0[0] + self.0[2] * other.0[1],
175 self.0[1] * other.0[0] + self.0[3] * other.0[1],
176 self.0[0] * other.0[2] + self.0[2] * other.0[3],
177 self.0[1] * other.0[2] + self.0[3] * other.0[3],
178 self.0[0] * other.0[4] + self.0[2] * other.0[5] + self.0[4],
179 self.0[1] * other.0[4] + self.0[3] * other.0[5] + self.0[5],
180 ])
181 }
182}
183
184impl MulAssign for Affine {
185 #[inline]
186 fn mul_assign(&mut self, other: Affine) {
187 *self = self.mul(other);
188 }
189}
190
191impl Mul<Affine> for f64 {
192 type Output = Affine;
193
194 #[inline]
195 fn mul(self, other: Affine) -> Affine {
196 Affine([
197 self * other.0[0],
198 self * other.0[1],
199 self * other.0[2],
200 self * other.0[3],
201 self * other.0[4],
202 self * other.0[5],
203 ])
204 }
205}
206
207#[derive(Clone, Copy, Default, PartialEq)]
209#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
210#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
211#[repr(C)]
212pub struct Point {
213 pub x: f64,
215 pub y: f64,
217}
218
219impl Point {
220 pub const ZERO: Point = Point::new(0., 0.);
222
223 pub const ORIGIN: Point = Point::new(0., 0.);
225
226 #[inline]
228 pub const fn new(x: f64, y: f64) -> Self {
229 Point { x, y }
230 }
231
232 #[inline]
234 pub const fn to_vec2(self) -> Vec2 {
235 Vec2::new(self.x, self.y)
236 }
237}
238
239impl From<(f64, f64)> for Point {
240 #[inline]
241 fn from(v: (f64, f64)) -> Point {
242 Point { x: v.0, y: v.1 }
243 }
244}
245
246impl From<Point> for (f64, f64) {
247 #[inline]
248 fn from(v: Point) -> (f64, f64) {
249 (v.x, v.y)
250 }
251}
252
253impl Add<Vec2> for Point {
254 type Output = Point;
255
256 #[inline]
257 fn add(self, other: Vec2) -> Self {
258 Point::new(self.x + other.x, self.y + other.y)
259 }
260}
261
262impl AddAssign<Vec2> for Point {
263 #[inline]
264 fn add_assign(&mut self, other: Vec2) {
265 *self = Point::new(self.x + other.x, self.y + other.y);
266 }
267}
268
269impl Sub<Vec2> for Point {
270 type Output = Point;
271
272 #[inline]
273 fn sub(self, other: Vec2) -> Self {
274 Point::new(self.x - other.x, self.y - other.y)
275 }
276}
277
278impl SubAssign<Vec2> for Point {
279 #[inline]
280 fn sub_assign(&mut self, other: Vec2) {
281 *self = Point::new(self.x - other.x, self.y - other.y);
282 }
283}
284
285impl Add<(f64, f64)> for Point {
286 type Output = Point;
287
288 #[inline]
289 fn add(self, (x, y): (f64, f64)) -> Self {
290 Point::new(self.x + x, self.y + y)
291 }
292}
293
294impl AddAssign<(f64, f64)> for Point {
295 #[inline]
296 fn add_assign(&mut self, (x, y): (f64, f64)) {
297 *self = Point::new(self.x + x, self.y + y);
298 }
299}
300
301impl Sub<(f64, f64)> for Point {
302 type Output = Point;
303
304 #[inline]
305 fn sub(self, (x, y): (f64, f64)) -> Self {
306 Point::new(self.x - x, self.y - y)
307 }
308}
309
310impl SubAssign<(f64, f64)> for Point {
311 #[inline]
312 fn sub_assign(&mut self, (x, y): (f64, f64)) {
313 *self = Point::new(self.x - x, self.y - y);
314 }
315}
316
317impl Sub<Point> for Point {
318 type Output = Vec2;
319
320 #[inline]
321 fn sub(self, other: Point) -> Vec2 {
322 Vec2::new(self.x - other.x, self.y - other.y)
323 }
324}
325
326impl fmt::Debug for Point {
327 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
328 write!(f, "({:?}, {:?})", self.x, self.y)
329 }
330}
331
332#[derive(Clone, Copy, Default, PartialEq)]
334#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
335#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
336#[repr(C)]
337pub struct Rect {
338 pub x0: f64,
340 pub y0: f64,
342 pub x1: f64,
344 pub y1: f64,
346}
347
348impl From<(Point, Point)> for Rect {
349 fn from(points: (Point, Point)) -> Rect {
350 Rect::from_points(points.0, points.1)
351 }
352}
353
354impl From<(Point, Size)> for Rect {
355 fn from(params: (Point, Size)) -> Rect {
356 Rect::from_origin_size(params.0, params.1)
357 }
358}
359
360impl Add<Vec2> for Rect {
361 type Output = Rect;
362
363 #[inline]
364 fn add(self, v: Vec2) -> Rect {
365 Rect::new(self.x0 + v.x, self.y0 + v.y, self.x1 + v.x, self.y1 + v.y)
366 }
367}
368
369impl Sub<Vec2> for Rect {
370 type Output = Rect;
371
372 #[inline]
373 fn sub(self, v: Vec2) -> Rect {
374 Rect::new(self.x0 - v.x, self.y0 - v.y, self.x1 - v.x, self.y1 - v.y)
375 }
376}
377
378impl fmt::Debug for Rect {
379 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
380 if f.alternate() {
381 write!(
382 f,
383 "Rect {{ origin: {:?}, size: {:?} }}",
384 self.origin(),
385 self.size()
386 )
387 } else {
388 write!(
389 f,
390 "Rect {{ x0: {:?}, y0: {:?}, x1: {:?}, y1: {:?} }}",
391 self.x0, self.y0, self.x1, self.y1
392 )
393 }
394 }
395}
396
397impl Rect {
398 pub const ZERO: Rect = Rect::new(0., 0., 0., 0.);
400
401 #[inline]
403 pub const fn new(x0: f64, y0: f64, x1: f64, y1: f64) -> Rect {
404 Rect { x0, y0, x1, y1 }
405 }
406
407 #[inline]
411 pub fn from_points(p0: impl Into<Point>, p1: impl Into<Point>) -> Rect {
412 let p0 = p0.into();
413 let p1 = p1.into();
414 Rect::new(p0.x, p0.y, p1.x, p1.y).abs()
415 }
416
417 #[inline]
421 pub fn from_origin_size(origin: impl Into<Point>, size: impl Into<Size>) -> Rect {
422 let origin = origin.into();
423 Rect::from_points(origin, origin + size.into().to_vec2())
424 }
425
426 #[inline]
428 pub fn with_origin(self, origin: impl Into<Point>) -> Rect {
429 Rect::from_origin_size(origin, self.size())
430 }
431
432 #[inline]
434 pub fn with_size(self, size: impl Into<Size>) -> Rect {
435 Rect::from_origin_size(self.origin(), size)
436 }
437
438 #[inline]
442 pub fn width(&self) -> f64 {
443 self.x1 - self.x0
444 }
445
446 #[inline]
450 pub fn height(&self) -> f64 {
451 self.y1 - self.y0
452 }
453
454 #[inline]
456 pub fn min_x(&self) -> f64 {
457 self.x0.min(self.x1)
458 }
459
460 #[inline]
462 pub fn max_x(&self) -> f64 {
463 self.x0.max(self.x1)
464 }
465
466 #[inline]
468 pub fn min_y(&self) -> f64 {
469 self.y0.min(self.y1)
470 }
471
472 #[inline]
474 pub fn max_y(&self) -> f64 {
475 self.y0.max(self.y1)
476 }
477
478 #[inline]
483 pub fn origin(&self) -> Point {
484 Point::new(self.x0, self.y0)
485 }
486
487 #[inline]
489 pub fn size(&self) -> Size {
490 Size::new(self.width(), self.height())
491 }
492
493 #[inline]
498 pub fn abs(&self) -> Rect {
499 let Rect { x0, y0, x1, y1 } = *self;
500 Rect::new(x0.min(x1), y0.min(y1), x0.max(x1), y0.max(y1))
501 }
502
503 #[inline]
505 pub fn area(&self) -> f64 {
506 self.width() * self.height()
507 }
508
509 #[inline]
513 pub fn is_empty(&self) -> bool {
514 self.area() == 0.0
515 }
516
517 #[inline]
519 pub fn contains(&self, point: Point) -> bool {
520 point.x >= self.x0 && point.x < self.x1 && point.y >= self.y0 && point.y < self.y1
521 }
522
523 #[inline]
527 pub fn union(&self, other: Rect) -> Rect {
528 Rect::new(
529 self.x0.min(other.x0),
530 self.y0.min(other.y0),
531 self.x1.max(other.x1),
532 self.y1.max(other.y1),
533 )
534 }
535
536 pub fn union_pt(&self, pt: Point) -> Rect {
544 Rect::new(
545 self.x0.min(pt.x),
546 self.y0.min(pt.y),
547 self.x1.max(pt.x),
548 self.y1.max(pt.y),
549 )
550 }
551
552 #[inline]
557 pub fn intersect(&self, other: Rect) -> Rect {
558 let x0 = self.x0.max(other.x0);
559 let y0 = self.y0.max(other.y0);
560 let x1 = self.x1.min(other.x1);
561 let y1 = self.y1.min(other.y1);
562 Rect::new(x0, y0, x1.max(x0), y1.max(y0))
563 }
564}
565
566#[derive(Clone, Copy, Default, PartialEq)]
568#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
569#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
570#[repr(C)]
571pub struct Size {
572 pub width: f64,
574 pub height: f64,
576}
577
578impl Size {
579 pub const ZERO: Size = Size::new(0., 0.);
581
582 #[inline]
584 pub const fn new(width: f64, height: f64) -> Self {
585 Size { width, height }
586 }
587
588 #[inline]
591 pub const fn to_vec2(self) -> Vec2 {
592 Vec2::new(self.width, self.height)
593 }
594}
595
596impl fmt::Debug for Size {
597 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
598 write!(f, "{:?}W×{:?}H", self.width, self.height)
599 }
600}
601
602impl MulAssign<f64> for Size {
603 #[inline]
604 fn mul_assign(&mut self, other: f64) {
605 *self = Size {
606 width: self.width * other,
607 height: self.height * other,
608 };
609 }
610}
611
612impl Mul<Size> for f64 {
613 type Output = Size;
614
615 #[inline]
616 fn mul(self, other: Size) -> Size {
617 other * self
618 }
619}
620
621impl Mul<f64> for Size {
622 type Output = Size;
623
624 #[inline]
625 fn mul(self, other: f64) -> Size {
626 Size {
627 width: self.width * other,
628 height: self.height * other,
629 }
630 }
631}
632
633impl DivAssign<f64> for Size {
634 #[inline]
635 fn div_assign(&mut self, other: f64) {
636 *self = Size {
637 width: self.width / other,
638 height: self.height / other,
639 };
640 }
641}
642
643impl Div<f64> for Size {
644 type Output = Size;
645
646 #[inline]
647 fn div(self, other: f64) -> Size {
648 Size {
649 width: self.width / other,
650 height: self.height / other,
651 }
652 }
653}
654
655impl Add<Size> for Size {
656 type Output = Size;
657 #[inline]
658 fn add(self, other: Size) -> Size {
659 Size {
660 width: self.width + other.width,
661 height: self.height + other.height,
662 }
663 }
664}
665
666impl AddAssign<Size> for Size {
667 #[inline]
668 fn add_assign(&mut self, other: Size) {
669 *self = *self + other;
670 }
671}
672
673impl Sub<Size> for Size {
674 type Output = Size;
675 #[inline]
676 fn sub(self, other: Size) -> Size {
677 Size {
678 width: self.width - other.width,
679 height: self.height - other.height,
680 }
681 }
682}
683
684impl SubAssign<Size> for Size {
685 #[inline]
686 fn sub_assign(&mut self, other: Size) {
687 *self = *self - other;
688 }
689}
690
691impl From<(f64, f64)> for Size {
692 #[inline]
693 fn from(v: (f64, f64)) -> Size {
694 Size {
695 width: v.0,
696 height: v.1,
697 }
698 }
699}
700
701impl From<Size> for (f64, f64) {
702 #[inline]
703 fn from(v: Size) -> (f64, f64) {
704 (v.width, v.height)
705 }
706}
707
708#[derive(Clone, Copy, Default, Debug, PartialEq)]
714#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
715#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
716#[repr(C)]
717pub struct Vec2 {
718 pub x: f64,
720 pub y: f64,
722}
723
724impl Vec2 {
725 pub const ZERO: Vec2 = Vec2::new(0., 0.);
727
728 #[inline]
730 pub const fn new(x: f64, y: f64) -> Vec2 {
731 Vec2 { x, y }
732 }
733
734 #[inline]
736 pub const fn to_point(self) -> Point {
737 Point::new(self.x, self.y)
738 }
739
740 #[inline]
742 pub const fn to_size(self) -> Size {
743 Size::new(self.x, self.y)
744 }
745}
746
747impl From<(f64, f64)> for Vec2 {
748 #[inline]
749 fn from(v: (f64, f64)) -> Vec2 {
750 Vec2 { x: v.0, y: v.1 }
751 }
752}
753
754impl From<Vec2> for (f64, f64) {
755 #[inline]
756 fn from(v: Vec2) -> (f64, f64) {
757 (v.x, v.y)
758 }
759}
760
761impl Add for Vec2 {
762 type Output = Vec2;
763
764 #[inline]
765 fn add(self, other: Vec2) -> Vec2 {
766 Vec2 {
767 x: self.x + other.x,
768 y: self.y + other.y,
769 }
770 }
771}
772
773impl AddAssign for Vec2 {
774 #[inline]
775 fn add_assign(&mut self, other: Vec2) {
776 *self = Vec2 {
777 x: self.x + other.x,
778 y: self.y + other.y,
779 }
780 }
781}
782
783impl Sub for Vec2 {
784 type Output = Vec2;
785
786 #[inline]
787 fn sub(self, other: Vec2) -> Vec2 {
788 Vec2 {
789 x: self.x - other.x,
790 y: self.y - other.y,
791 }
792 }
793}
794
795impl SubAssign for Vec2 {
796 #[inline]
797 fn sub_assign(&mut self, other: Vec2) {
798 *self = Vec2 {
799 x: self.x - other.x,
800 y: self.y - other.y,
801 }
802 }
803}
804
805impl Mul<f64> for Vec2 {
806 type Output = Vec2;
807
808 #[inline]
809 fn mul(self, other: f64) -> Vec2 {
810 Vec2 {
811 x: self.x * other,
812 y: self.y * other,
813 }
814 }
815}
816
817impl MulAssign<f64> for Vec2 {
818 #[inline]
819 fn mul_assign(&mut self, other: f64) {
820 *self = Vec2 {
821 x: self.x * other,
822 y: self.y * other,
823 };
824 }
825}
826
827impl Mul<Vec2> for f64 {
828 type Output = Vec2;
829
830 #[inline]
831 fn mul(self, other: Vec2) -> Vec2 {
832 other * self
833 }
834}
835
836impl Div<f64> for Vec2 {
837 type Output = Vec2;
838
839 #[inline]
843 #[allow(clippy::suspicious_arithmetic_impl)]
844 fn div(self, other: f64) -> Vec2 {
845 self * other.recip()
846 }
847}
848
849impl DivAssign<f64> for Vec2 {
850 #[inline]
851 fn div_assign(&mut self, other: f64) {
852 self.mul_assign(other.recip());
853 }
854}
855
856impl Neg for Vec2 {
857 type Output = Vec2;
858
859 #[inline]
860 fn neg(self) -> Vec2 {
861 Vec2 {
862 x: -self.x,
863 y: -self.y,
864 }
865 }
866}