1use std::{
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]
79 pub fn rotate(th: f64) -> Affine {
80 let (s, c) = th.sin_cos();
81 Affine([c, s, -s, c, 0.0, 0.0])
82 }
83
84 #[inline]
86 pub fn translate<V: Into<Vec2>>(p: V) -> Affine {
87 let p = p.into();
88 Affine([1.0, 0.0, 0.0, 1.0, p.x, p.y])
89 }
90
91 pub fn map_unit_square(rect: Rect) -> Affine {
96 Affine([rect.width(), 0., 0., rect.height(), rect.x0, rect.y0])
97 }
98
99 #[inline]
101 pub fn as_coeffs(self) -> [f64; 6] {
102 self.0
103 }
104
105 pub fn determinant(self) -> f64 {
107 self.0[0] * self.0[3] - self.0[1] * self.0[2]
108 }
109
110 pub fn inverse(self) -> Affine {
114 let inv_det = self.determinant().recip();
115 Affine([
116 inv_det * self.0[3],
117 -inv_det * self.0[1],
118 -inv_det * self.0[2],
119 inv_det * self.0[0],
120 inv_det * (self.0[2] * self.0[5] - self.0[3] * self.0[4]),
121 inv_det * (self.0[1] * self.0[4] - self.0[0] * self.0[5]),
122 ])
123 }
124
125 pub fn transform_rect_bbox(self, rect: Rect) -> Rect {
133 let p00 = self * Point::new(rect.x0, rect.y0);
134 let p01 = self * Point::new(rect.x0, rect.y1);
135 let p10 = self * Point::new(rect.x1, rect.y0);
136 let p11 = self * Point::new(rect.x1, rect.y1);
137 Rect::from_points(p00, p01).union(Rect::from_points(p10, p11))
138 }
139
140 #[inline]
142 pub fn is_finite(&self) -> bool {
143 self.0[0].is_finite()
144 && self.0[1].is_finite()
145 && self.0[2].is_finite()
146 && self.0[3].is_finite()
147 && self.0[4].is_finite()
148 && self.0[5].is_finite()
149 }
150
151 #[inline]
153 pub fn is_nan(&self) -> bool {
154 self.0[0].is_nan()
155 || self.0[1].is_nan()
156 || self.0[2].is_nan()
157 || self.0[3].is_nan()
158 || self.0[4].is_nan()
159 || self.0[5].is_nan()
160 }
161}
162
163impl Default for Affine {
164 #[inline]
165 fn default() -> Affine {
166 Affine::IDENTITY
167 }
168}
169
170impl Mul<Point> for Affine {
171 type Output = Point;
172
173 #[inline]
174 fn mul(self, other: Point) -> Point {
175 Point::new(
176 self.0[0] * other.x + self.0[2] * other.y + self.0[4],
177 self.0[1] * other.x + self.0[3] * other.y + self.0[5],
178 )
179 }
180}
181
182impl Mul for Affine {
183 type Output = Affine;
184
185 #[inline]
186 fn mul(self, other: Affine) -> Affine {
187 Affine([
188 self.0[0] * other.0[0] + self.0[2] * other.0[1],
189 self.0[1] * other.0[0] + self.0[3] * other.0[1],
190 self.0[0] * other.0[2] + self.0[2] * other.0[3],
191 self.0[1] * other.0[2] + self.0[3] * other.0[3],
192 self.0[0] * other.0[4] + self.0[2] * other.0[5] + self.0[4],
193 self.0[1] * other.0[4] + self.0[3] * other.0[5] + self.0[5],
194 ])
195 }
196}
197
198impl MulAssign for Affine {
199 #[inline]
200 fn mul_assign(&mut self, other: Affine) {
201 *self = self.mul(other);
202 }
203}
204
205impl Mul<Affine> for f64 {
206 type Output = Affine;
207
208 #[inline]
209 fn mul(self, other: Affine) -> Affine {
210 Affine([
211 self * other.0[0],
212 self * other.0[1],
213 self * other.0[2],
214 self * other.0[3],
215 self * other.0[4],
216 self * other.0[5],
217 ])
218 }
219}
220
221#[derive(Clone, Copy, Default, PartialEq)]
223#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
224#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
225#[repr(C)]
226pub struct Point {
227 pub x: f64,
229 pub y: f64,
231}
232
233impl Point {
234 pub const ZERO: Point = Point::new(0., 0.);
236
237 pub const ORIGIN: Point = Point::new(0., 0.);
239
240 #[inline]
242 pub const fn new(x: f64, y: f64) -> Self {
243 Point { x, y }
244 }
245
246 #[inline]
248 pub const fn to_vec2(self) -> Vec2 {
249 Vec2::new(self.x, self.y)
250 }
251}
252
253impl From<(f64, f64)> for Point {
254 #[inline]
255 fn from(v: (f64, f64)) -> Point {
256 Point { x: v.0, y: v.1 }
257 }
258}
259
260impl From<Point> for (f64, f64) {
261 #[inline]
262 fn from(v: Point) -> (f64, f64) {
263 (v.x, v.y)
264 }
265}
266
267impl Add<Vec2> for Point {
268 type Output = Point;
269
270 #[inline]
271 fn add(self, other: Vec2) -> Self {
272 Point::new(self.x + other.x, self.y + other.y)
273 }
274}
275
276impl AddAssign<Vec2> for Point {
277 #[inline]
278 fn add_assign(&mut self, other: Vec2) {
279 *self = Point::new(self.x + other.x, self.y + other.y);
280 }
281}
282
283impl Sub<Vec2> for Point {
284 type Output = Point;
285
286 #[inline]
287 fn sub(self, other: Vec2) -> Self {
288 Point::new(self.x - other.x, self.y - other.y)
289 }
290}
291
292impl SubAssign<Vec2> for Point {
293 #[inline]
294 fn sub_assign(&mut self, other: Vec2) {
295 *self = Point::new(self.x - other.x, self.y - other.y);
296 }
297}
298
299impl Add<(f64, f64)> for Point {
300 type Output = Point;
301
302 #[inline]
303 fn add(self, (x, y): (f64, f64)) -> Self {
304 Point::new(self.x + x, self.y + y)
305 }
306}
307
308impl AddAssign<(f64, f64)> for Point {
309 #[inline]
310 fn add_assign(&mut self, (x, y): (f64, f64)) {
311 *self = Point::new(self.x + x, self.y + y);
312 }
313}
314
315impl Sub<(f64, f64)> for Point {
316 type Output = Point;
317
318 #[inline]
319 fn sub(self, (x, y): (f64, f64)) -> Self {
320 Point::new(self.x - x, self.y - y)
321 }
322}
323
324impl SubAssign<(f64, f64)> for Point {
325 #[inline]
326 fn sub_assign(&mut self, (x, y): (f64, f64)) {
327 *self = Point::new(self.x - x, self.y - y);
328 }
329}
330
331impl Sub<Point> for Point {
332 type Output = Vec2;
333
334 #[inline]
335 fn sub(self, other: Point) -> Vec2 {
336 Vec2::new(self.x - other.x, self.y - other.y)
337 }
338}
339
340impl fmt::Debug for Point {
341 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
342 write!(f, "({:?}, {:?})", self.x, self.y)
343 }
344}
345
346#[derive(Clone, Copy, Default, PartialEq)]
348#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
349#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
350#[repr(C)]
351pub struct Rect {
352 pub x0: f64,
354 pub y0: f64,
356 pub x1: f64,
358 pub y1: f64,
360}
361
362impl From<(Point, Point)> for Rect {
363 fn from(points: (Point, Point)) -> Rect {
364 Rect::from_points(points.0, points.1)
365 }
366}
367
368impl From<(Point, Size)> for Rect {
369 fn from(params: (Point, Size)) -> Rect {
370 Rect::from_origin_size(params.0, params.1)
371 }
372}
373
374impl Add<Vec2> for Rect {
375 type Output = Rect;
376
377 #[inline]
378 fn add(self, v: Vec2) -> Rect {
379 Rect::new(self.x0 + v.x, self.y0 + v.y, self.x1 + v.x, self.y1 + v.y)
380 }
381}
382
383impl Sub<Vec2> for Rect {
384 type Output = Rect;
385
386 #[inline]
387 fn sub(self, v: Vec2) -> Rect {
388 Rect::new(self.x0 - v.x, self.y0 - v.y, self.x1 - v.x, self.y1 - v.y)
389 }
390}
391
392impl fmt::Debug for Rect {
393 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
394 if f.alternate() {
395 write!(
396 f,
397 "Rect {{ origin: {:?}, size: {:?} }}",
398 self.origin(),
399 self.size()
400 )
401 } else {
402 write!(
403 f,
404 "Rect {{ x0: {:?}, y0: {:?}, x1: {:?}, y1: {:?} }}",
405 self.x0, self.y0, self.x1, self.y1
406 )
407 }
408 }
409}
410
411impl Rect {
412 pub const ZERO: Rect = Rect::new(0., 0., 0., 0.);
414
415 #[inline]
417 pub const fn new(x0: f64, y0: f64, x1: f64, y1: f64) -> Rect {
418 Rect { x0, y0, x1, y1 }
419 }
420
421 #[inline]
425 pub fn from_points(p0: impl Into<Point>, p1: impl Into<Point>) -> Rect {
426 let p0 = p0.into();
427 let p1 = p1.into();
428 Rect::new(p0.x, p0.y, p1.x, p1.y).abs()
429 }
430
431 #[inline]
435 pub fn from_origin_size(origin: impl Into<Point>, size: impl Into<Size>) -> Rect {
436 let origin = origin.into();
437 Rect::from_points(origin, origin + size.into().to_vec2())
438 }
439
440 #[inline]
442 pub fn with_origin(self, origin: impl Into<Point>) -> Rect {
443 Rect::from_origin_size(origin, self.size())
444 }
445
446 #[inline]
448 pub fn with_size(self, size: impl Into<Size>) -> Rect {
449 Rect::from_origin_size(self.origin(), size)
450 }
451
452 #[inline]
456 pub fn width(&self) -> f64 {
457 self.x1 - self.x0
458 }
459
460 #[inline]
464 pub fn height(&self) -> f64 {
465 self.y1 - self.y0
466 }
467
468 #[inline]
470 pub fn min_x(&self) -> f64 {
471 self.x0.min(self.x1)
472 }
473
474 #[inline]
476 pub fn max_x(&self) -> f64 {
477 self.x0.max(self.x1)
478 }
479
480 #[inline]
482 pub fn min_y(&self) -> f64 {
483 self.y0.min(self.y1)
484 }
485
486 #[inline]
488 pub fn max_y(&self) -> f64 {
489 self.y0.max(self.y1)
490 }
491
492 #[inline]
497 pub fn origin(&self) -> Point {
498 Point::new(self.x0, self.y0)
499 }
500
501 #[inline]
503 pub fn size(&self) -> Size {
504 Size::new(self.width(), self.height())
505 }
506
507 #[inline]
512 pub fn abs(&self) -> Rect {
513 let Rect { x0, y0, x1, y1 } = *self;
514 Rect::new(x0.min(x1), y0.min(y1), x0.max(x1), y0.max(y1))
515 }
516
517 #[inline]
519 pub fn area(&self) -> f64 {
520 self.width() * self.height()
521 }
522
523 #[inline]
527 pub fn is_empty(&self) -> bool {
528 self.area() == 0.0
529 }
530
531 #[inline]
533 pub fn contains(&self, point: Point) -> bool {
534 point.x >= self.x0 && point.x < self.x1 && point.y >= self.y0 && point.y < self.y1
535 }
536
537 #[inline]
541 pub fn union(&self, other: Rect) -> Rect {
542 Rect::new(
543 self.x0.min(other.x0),
544 self.y0.min(other.y0),
545 self.x1.max(other.x1),
546 self.y1.max(other.y1),
547 )
548 }
549
550 pub fn union_pt(&self, pt: Point) -> Rect {
558 Rect::new(
559 self.x0.min(pt.x),
560 self.y0.min(pt.y),
561 self.x1.max(pt.x),
562 self.y1.max(pt.y),
563 )
564 }
565
566 #[inline]
571 pub fn intersect(&self, other: Rect) -> Rect {
572 let x0 = self.x0.max(other.x0);
573 let y0 = self.y0.max(other.y0);
574 let x1 = self.x1.min(other.x1);
575 let y1 = self.y1.min(other.y1);
576 Rect::new(x0, y0, x1.max(x0), y1.max(y0))
577 }
578}
579
580#[derive(Clone, Copy, Default, PartialEq)]
582#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
583#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
584#[repr(C)]
585pub struct Size {
586 pub width: f64,
588 pub height: f64,
590}
591
592impl Size {
593 pub const ZERO: Size = Size::new(0., 0.);
595
596 #[inline]
598 pub const fn new(width: f64, height: f64) -> Self {
599 Size { width, height }
600 }
601
602 #[inline]
605 pub const fn to_vec2(self) -> Vec2 {
606 Vec2::new(self.width, self.height)
607 }
608}
609
610impl fmt::Debug for Size {
611 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
612 write!(f, "{:?}W×{:?}H", self.width, self.height)
613 }
614}
615
616impl MulAssign<f64> for Size {
617 #[inline]
618 fn mul_assign(&mut self, other: f64) {
619 *self = Size {
620 width: self.width * other,
621 height: self.height * other,
622 };
623 }
624}
625
626impl Mul<Size> for f64 {
627 type Output = Size;
628
629 #[inline]
630 fn mul(self, other: Size) -> Size {
631 other * self
632 }
633}
634
635impl Mul<f64> for Size {
636 type Output = Size;
637
638 #[inline]
639 fn mul(self, other: f64) -> Size {
640 Size {
641 width: self.width * other,
642 height: self.height * other,
643 }
644 }
645}
646
647impl DivAssign<f64> for Size {
648 #[inline]
649 fn div_assign(&mut self, other: f64) {
650 *self = Size {
651 width: self.width / other,
652 height: self.height / other,
653 };
654 }
655}
656
657impl Div<f64> for Size {
658 type Output = Size;
659
660 #[inline]
661 fn div(self, other: f64) -> Size {
662 Size {
663 width: self.width / other,
664 height: self.height / other,
665 }
666 }
667}
668
669impl Add<Size> for Size {
670 type Output = Size;
671 #[inline]
672 fn add(self, other: Size) -> Size {
673 Size {
674 width: self.width + other.width,
675 height: self.height + other.height,
676 }
677 }
678}
679
680impl AddAssign<Size> for Size {
681 #[inline]
682 fn add_assign(&mut self, other: Size) {
683 *self = *self + other;
684 }
685}
686
687impl Sub<Size> for Size {
688 type Output = Size;
689 #[inline]
690 fn sub(self, other: Size) -> Size {
691 Size {
692 width: self.width - other.width,
693 height: self.height - other.height,
694 }
695 }
696}
697
698impl SubAssign<Size> for Size {
699 #[inline]
700 fn sub_assign(&mut self, other: Size) {
701 *self = *self - other;
702 }
703}
704
705impl From<(f64, f64)> for Size {
706 #[inline]
707 fn from(v: (f64, f64)) -> Size {
708 Size {
709 width: v.0,
710 height: v.1,
711 }
712 }
713}
714
715impl From<Size> for (f64, f64) {
716 #[inline]
717 fn from(v: Size) -> (f64, f64) {
718 (v.width, v.height)
719 }
720}
721
722#[derive(Clone, Copy, Default, Debug, PartialEq)]
728#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
729#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
730#[repr(C)]
731pub struct Vec2 {
732 pub x: f64,
734 pub y: f64,
736}
737
738impl Vec2 {
739 pub const ZERO: Vec2 = Vec2::new(0., 0.);
741
742 #[inline]
744 pub const fn new(x: f64, y: f64) -> Vec2 {
745 Vec2 { x, y }
746 }
747
748 #[inline]
750 pub const fn to_point(self) -> Point {
751 Point::new(self.x, self.y)
752 }
753
754 #[inline]
756 pub const fn to_size(self) -> Size {
757 Size::new(self.x, self.y)
758 }
759}
760
761impl From<(f64, f64)> for Vec2 {
762 #[inline]
763 fn from(v: (f64, f64)) -> Vec2 {
764 Vec2 { x: v.0, y: v.1 }
765 }
766}
767
768impl From<Vec2> for (f64, f64) {
769 #[inline]
770 fn from(v: Vec2) -> (f64, f64) {
771 (v.x, v.y)
772 }
773}
774
775impl Add for Vec2 {
776 type Output = Vec2;
777
778 #[inline]
779 fn add(self, other: Vec2) -> Vec2 {
780 Vec2 {
781 x: self.x + other.x,
782 y: self.y + other.y,
783 }
784 }
785}
786
787impl AddAssign for Vec2 {
788 #[inline]
789 fn add_assign(&mut self, other: Vec2) {
790 *self = Vec2 {
791 x: self.x + other.x,
792 y: self.y + other.y,
793 }
794 }
795}
796
797impl Sub for Vec2 {
798 type Output = Vec2;
799
800 #[inline]
801 fn sub(self, other: Vec2) -> Vec2 {
802 Vec2 {
803 x: self.x - other.x,
804 y: self.y - other.y,
805 }
806 }
807}
808
809impl SubAssign for Vec2 {
810 #[inline]
811 fn sub_assign(&mut self, other: Vec2) {
812 *self = Vec2 {
813 x: self.x - other.x,
814 y: self.y - other.y,
815 }
816 }
817}
818
819impl Mul<f64> for Vec2 {
820 type Output = Vec2;
821
822 #[inline]
823 fn mul(self, other: f64) -> Vec2 {
824 Vec2 {
825 x: self.x * other,
826 y: self.y * other,
827 }
828 }
829}
830
831impl MulAssign<f64> for Vec2 {
832 #[inline]
833 fn mul_assign(&mut self, other: f64) {
834 *self = Vec2 {
835 x: self.x * other,
836 y: self.y * other,
837 };
838 }
839}
840
841impl Mul<Vec2> for f64 {
842 type Output = Vec2;
843
844 #[inline]
845 fn mul(self, other: Vec2) -> Vec2 {
846 other * self
847 }
848}
849
850impl Div<f64> for Vec2 {
851 type Output = Vec2;
852
853 #[inline]
857 #[allow(clippy::suspicious_arithmetic_impl)]
858 fn div(self, other: f64) -> Vec2 {
859 self * other.recip()
860 }
861}
862
863impl DivAssign<f64> for Vec2 {
864 #[inline]
865 fn div_assign(&mut self, other: f64) {
866 self.mul_assign(other.recip());
867 }
868}
869
870impl Neg for Vec2 {
871 type Output = Vec2;
872
873 #[inline]
874 fn neg(self) -> Vec2 {
875 Vec2 {
876 x: -self.x,
877 y: -self.y,
878 }
879 }
880}