1use crate::cast::*;
11use crate::dir::Directional;
12use crate::geom::{Coord, Offset, Rect, Size};
13use std::cmp::{Ordering, PartialOrd};
14use std::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign};
15
16#[repr(C)]
20#[derive(Clone, Copy, Debug, Default, PartialEq)]
21#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
22pub struct Quad {
23 pub a: Vec2,
24 pub b: Vec2,
25}
26
27impl Quad {
28 pub const ZERO: Quad = Quad::from_coords(Vec2::ZERO, Vec2::ZERO);
30
31 pub const INFINITY: Quad = Quad::from_coords(Vec2::NEG_INFINITY, Vec2::INFINITY);
33
34 pub const NAN: Quad = Quad::from_coords(Vec2::NAN, Vec2::NAN);
36
37 #[inline]
39 pub const fn from_coords(a: Vec2, b: Vec2) -> Self {
40 Quad { a, b }
41 }
42
43 #[inline]
45 pub fn from_pos_and_size(pos: Vec2, size: Vec2) -> Self {
46 Quad {
47 a: pos,
48 b: pos + size,
49 }
50 }
51
52 #[inline]
54 pub fn from_center(pos: Vec2, r: f32) -> Self {
55 let v = Vec2::splat(r);
56 Quad {
57 a: pos - v,
58 b: pos + v,
59 }
60 }
61
62 #[inline]
64 pub fn size(&self) -> Vec2 {
65 self.b - self.a
66 }
67
68 #[inline]
70 pub fn center(&self) -> Vec2 {
71 (self.a + self.b) * 0.5
72 }
73
74 #[inline]
76 pub fn ab(&self) -> Vec2 {
77 Vec2(self.a.0, self.b.1)
78 }
79
80 #[inline]
82 pub fn ba(&self) -> Vec2 {
83 Vec2(self.b.0, self.a.1)
84 }
85
86 #[inline]
88 #[must_use = "method does not modify self but returns a new value"]
89 pub fn shrink(&self, value: f32) -> Quad {
90 let a = self.a + value;
91 let b = self.b - value;
92 Quad { a, b }
93 }
94
95 #[inline]
97 #[must_use = "method does not modify self but returns a new value"]
98 pub fn grow(&self, value: f32) -> Quad {
99 let a = self.a - value;
100 let b = self.b + value;
101 Quad { a, b }
102 }
103
104 #[inline]
106 #[must_use = "method does not modify self but returns a new value"]
107 pub fn shrink_vec(&self, value: Vec2) -> Quad {
108 let a = self.a + value;
109 let b = self.b - value;
110 Quad { a, b }
111 }
112
113 pub fn intersection(&self, rhs: &Quad) -> Option<Quad> {
115 let a = Vec2(self.a.0.max(rhs.a.0), self.a.1.max(rhs.a.1));
116 let b = Vec2(self.b.0.min(rhs.b.0), self.b.1.min(rhs.b.1));
117 if a <= b { Some(Quad::from_coords(a, b)) } else { None }
118 }
119}
120
121impl AddAssign<Vec2> for Quad {
122 #[inline]
123 fn add_assign(&mut self, rhs: Vec2) {
124 self.a += rhs;
125 self.b += rhs;
126 }
127}
128
129impl SubAssign<Vec2> for Quad {
130 #[inline]
131 fn sub_assign(&mut self, rhs: Vec2) {
132 self.a -= rhs;
133 self.b -= rhs;
134 }
135}
136
137impl Add<Vec2> for Quad {
138 type Output = Quad;
139 #[inline]
140 fn add(mut self, rhs: Vec2) -> Self::Output {
141 self += rhs;
142 self
143 }
144}
145
146impl Sub<Vec2> for Quad {
147 type Output = Quad;
148 #[inline]
149 fn sub(mut self, rhs: Vec2) -> Self::Output {
150 self -= rhs;
151 self
152 }
153}
154
155impl Conv<Rect> for Quad {
156 #[inline]
157 fn try_conv(rect: Rect) -> Result<Self> {
158 let a = Vec2::try_conv(rect.pos)?;
159 let b = a + Vec2::try_conv(rect.size)?;
160 Ok(Quad { a, b })
161 }
162}
163
164#[repr(C)]
174#[derive(Clone, Copy, Debug, Default, PartialEq)]
175#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
176pub struct Vec2(pub f32, pub f32);
177
178#[repr(C)]
188#[derive(Clone, Copy, Debug, Default, PartialEq)]
189#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
190pub struct DVec2(pub f64, pub f64);
191
192macro_rules! impl_vec2 {
193 ($T:ident, $f:ty) => {
194 impl $T {
195 pub const ZERO: $T = $T::splat(0.0);
197
198 pub const ONE: $T = $T::splat(1.0);
200
201 pub const NEG_INFINITY: $T = $T::splat(<$f>::NEG_INFINITY);
203
204 pub const INFINITY: $T = $T::splat(<$f>::INFINITY);
206
207 pub const NAN: $T = $T::splat(<$f>::NAN);
209
210 #[inline]
212 pub const fn splat(value: $f) -> Self {
213 $T(value, value)
214 }
215
216 #[inline]
218 pub fn min_comp(self) -> $f {
219 self.0.min(self.1)
220 }
221
222 #[inline]
224 pub fn max_comp(self) -> $f {
225 self.0.max(self.1)
226 }
227
228 #[inline]
230 #[must_use = "method does not modify self but returns a new value"]
231 pub fn min(self, other: Self) -> Self {
232 $T(self.0.min(other.0), self.1.min(other.1))
233 }
234
235 #[inline]
237 #[must_use = "method does not modify self but returns a new value"]
238 pub fn max(self, other: Self) -> Self {
239 $T(self.0.max(other.0), self.1.max(other.1))
240 }
241
242 #[inline]
254 #[must_use = "method does not modify self but returns a new value"]
255 pub fn clamp(mut self, min: Self, max: Self) -> Self {
256 assert!(min <= max);
257 if self < min {
258 self = min;
259 }
260 if self > max {
261 self = max;
262 }
263 self
264 }
265
266 #[inline]
268 #[must_use = "method does not modify self but returns a new value"]
269 pub fn abs(self) -> Self {
270 $T(self.0.abs(), self.1.abs())
271 }
272
273 #[inline]
275 #[must_use = "method does not modify self but returns a new value"]
276 pub fn floor(self) -> Self {
277 $T(self.0.floor(), self.1.floor())
278 }
279
280 #[inline]
282 #[must_use = "method does not modify self but returns a new value"]
283 pub fn ceil(self) -> Self {
284 $T(self.0.ceil(), self.1.ceil())
285 }
286
287 #[inline]
289 #[must_use = "method does not modify self but returns a new value"]
290 pub fn round(self) -> Self {
291 $T(self.0.round(), self.1.round())
292 }
293
294 #[inline]
296 #[must_use = "method does not modify self but returns a new value"]
297 pub fn trunc(self) -> Self {
298 $T(self.0.trunc(), self.1.trunc())
299 }
300
301 #[inline]
303 #[must_use = "method does not modify self but returns a new value"]
304 pub fn fract(self) -> Self {
305 $T(self.0.fract(), self.1.fract())
306 }
307
308 #[inline]
310 #[must_use = "method does not modify self but returns a new value"]
311 pub fn sign(self) -> Self {
312 let one: $f = 1.0;
313 $T(one.copysign(self.0), one.copysign(self.1))
314 }
315 #[inline]
317 #[must_use = "method does not modify self but returns a new value"]
318 pub fn complex_mul(self, rhs: Self) -> Self {
319 $T(
320 self.0 * rhs.0 - self.1 * rhs.1,
321 self.0 * rhs.1 + self.1 * rhs.0,
322 )
323 }
324
325 #[inline]
327 #[must_use = "method does not modify self but returns a new value"]
328 pub fn complex_div(self, rhs: Self) -> Self {
329 self.complex_mul(rhs.complex_inv())
330 }
331
332 #[inline]
336 #[must_use = "method does not modify self but returns a new value"]
337 pub fn complex_inv(self) -> Self {
338 let ssi = 1.0 / self.sum_square();
339 $T(self.0 * ssi, -self.1 * ssi)
340 }
341
342 #[inline]
344 pub fn sum(self) -> $f {
345 self.0 + self.1
346 }
347
348 #[inline]
350 pub fn sum_square(self) -> $f {
351 self.0 * self.0 + self.1 * self.1
352 }
353
354 #[inline]
356 pub fn distance_l1(self) -> $f {
357 self.0.abs() + self.1.abs()
358 }
359
360 #[inline]
362 pub fn distance_l2(self) -> $f {
363 self.sum_square().sqrt()
364 }
365
366 #[inline]
368 pub fn distance_l_inf(self) -> $f {
369 self.0.abs().max(self.1.abs())
370 }
371
372 #[inline]
377 pub fn extract<D: Directional>(self, dir: D) -> $f {
378 match dir.is_vertical() {
379 false => self.0,
380 true => self.1,
381 }
382 }
383
384 #[inline]
386 pub fn is_finite(self) -> bool {
387 self.0.is_finite() && self.1.is_finite()
388 }
389
390 #[inline]
392 pub fn is_normal(self) -> bool {
393 self.0.is_normal() && self.1.is_normal()
394 }
395 }
396
397 impl Neg for $T {
398 type Output = $T;
399 #[inline]
400 fn neg(self) -> Self::Output {
401 $T(-self.0, -self.1)
402 }
403 }
404
405 impl Add<$T> for $T {
406 type Output = $T;
407 #[inline]
408 fn add(self, rhs: $T) -> Self::Output {
409 $T(self.0 + rhs.0, self.1 + rhs.1)
410 }
411 }
412
413 impl Add<$f> for $T {
414 type Output = $T;
415 #[inline]
416 fn add(self, rhs: $f) -> Self::Output {
417 $T(self.0 + rhs, self.1 + rhs)
418 }
419 }
420
421 impl AddAssign<$T> for $T {
422 #[inline]
423 fn add_assign(&mut self, rhs: $T) {
424 self.0 += rhs.0;
425 self.1 += rhs.1;
426 }
427 }
428
429 impl AddAssign<$f> for $T {
430 #[inline]
431 fn add_assign(&mut self, rhs: $f) {
432 self.0 += rhs;
433 self.1 += rhs;
434 }
435 }
436
437 impl Sub<$T> for $T {
438 type Output = $T;
439 #[inline]
440 fn sub(self, rhs: $T) -> Self::Output {
441 $T(self.0 - rhs.0, self.1 - rhs.1)
442 }
443 }
444
445 impl Sub<$f> for $T {
446 type Output = $T;
447 #[inline]
448 fn sub(self, rhs: $f) -> Self::Output {
449 $T(self.0 - rhs, self.1 - rhs)
450 }
451 }
452
453 impl SubAssign<$T> for $T {
454 #[inline]
455 fn sub_assign(&mut self, rhs: $T) {
456 self.0 -= rhs.0;
457 self.1 -= rhs.1;
458 }
459 }
460
461 impl SubAssign<$f> for $T {
462 #[inline]
463 fn sub_assign(&mut self, rhs: $f) {
464 self.0 -= rhs;
465 self.1 -= rhs;
466 }
467 }
468
469 impl Mul<$T> for $T {
470 type Output = $T;
471 #[inline]
472 fn mul(self, rhs: $T) -> Self::Output {
473 $T(self.0 * rhs.0, self.1 * rhs.1)
474 }
475 }
476
477 impl MulAssign<$T> for $T {
478 #[inline]
479 fn mul_assign(&mut self, rhs: $T) {
480 self.0 *= rhs.0;
481 self.1 *= rhs.1;
482 }
483 }
484
485 impl Mul<$f> for $T {
486 type Output = $T;
487 #[inline]
488 fn mul(self, rhs: $f) -> Self::Output {
489 $T(self.0 * rhs, self.1 * rhs)
490 }
491 }
492
493 impl MulAssign<$f> for $T {
494 #[inline]
495 fn mul_assign(&mut self, rhs: $f) {
496 self.0 *= rhs;
497 self.1 *= rhs;
498 }
499 }
500
501 impl Div<$T> for $T {
502 type Output = $T;
503 #[inline]
504 fn div(self, rhs: $T) -> Self::Output {
505 $T(self.0 / rhs.0, self.1 / rhs.1)
506 }
507 }
508
509 impl Div<$f> for $T {
510 type Output = $T;
511 #[inline]
512 fn div(self, rhs: $f) -> Self::Output {
513 $T(self.0 / rhs, self.1 / rhs)
514 }
515 }
516
517 impl DivAssign<$f> for $T {
518 #[inline]
519 fn div_assign(&mut self, rhs: $f) {
520 self.0 /= rhs;
521 self.1 /= rhs;
522 }
523 }
524
525 impl PartialOrd for $T {
526 fn partial_cmp(&self, rhs: &Self) -> Option<Ordering> {
527 if self == rhs {
528 Some(Ordering::Equal)
529 } else if self.0 < rhs.0 && self.1 < rhs.1 {
530 Some(Ordering::Less)
531 } else if self.0 > rhs.0 && self.1 > rhs.1 {
532 Some(Ordering::Greater)
533 } else {
534 None
535 }
536 }
537
538 #[inline]
539 fn lt(&self, rhs: &Self) -> bool {
540 self.0 < rhs.0 && self.1 < rhs.1
541 }
542
543 #[inline]
544 fn le(&self, rhs: &Self) -> bool {
545 self.0 <= rhs.0 && self.1 <= rhs.1
546 }
547
548 #[inline]
549 fn ge(&self, rhs: &Self) -> bool {
550 self.0 >= rhs.0 && self.1 >= rhs.1
551 }
552
553 #[inline]
554 fn gt(&self, rhs: &Self) -> bool {
555 self.0 > rhs.0 && self.1 > rhs.1
556 }
557 }
558
559 impl PartialEq<Coord> for $T {
560 fn eq(&self, rhs: &Coord) -> bool {
561 DVec2::from(*self) == DVec2::conv(*rhs)
562 }
563 }
564
565 impl PartialOrd<Coord> for $T {
566 fn partial_cmp(&self, rhs: &Coord) -> Option<Ordering> {
567 DVec2::from(*self).partial_cmp(&DVec2::conv(*rhs))
568 }
569
570 #[inline]
571 fn lt(&self, rhs: &Coord) -> bool {
572 DVec2::from(*self) < DVec2::conv(*rhs)
573 }
574
575 #[inline]
576 fn le(&self, rhs: &Coord) -> bool {
577 DVec2::from(*self) <= DVec2::conv(*rhs)
578 }
579
580 #[inline]
581 fn ge(&self, rhs: &Coord) -> bool {
582 DVec2::from(*self) >= DVec2::conv(*rhs)
583 }
584
585 #[inline]
586 fn gt(&self, rhs: &Coord) -> bool {
587 DVec2::from(*self) > DVec2::conv(*rhs)
588 }
589 }
590
591 impl From<($f, $f)> for $T {
592 #[inline]
593 fn from(arg: ($f, $f)) -> Self {
594 $T(arg.0, arg.1)
595 }
596 }
597 impl Conv<($f, $f)> for $T {
598 #[inline]
599 fn conv(arg: ($f, $f)) -> Self {
600 $T(arg.0, arg.1)
601 }
602 #[inline]
603 fn try_conv(v: ($f, $f)) -> Result<Self> {
604 Ok(Self::conv(v))
605 }
606 }
607
608 impl From<$T> for ($f, $f) {
609 #[inline]
610 fn from(v: $T) -> Self {
611 (v.0, v.1)
612 }
613 }
614 impl Conv<$T> for ($f, $f) {
615 #[inline]
616 fn conv(v: $T) -> Self {
617 (v.0, v.1)
618 }
619 #[inline]
620 fn try_conv(v: $T) -> Result<Self> {
621 Ok(Self::conv(v))
622 }
623 }
624
625 impl From<winit::dpi::PhysicalPosition<$f>> for $T {
626 #[inline]
627 fn from(pos: winit::dpi::PhysicalPosition<$f>) -> Self {
628 $T(pos.x, pos.y)
629 }
630 }
631
632 impl From<winit::dpi::PhysicalSize<$f>> for $T {
633 #[inline]
634 fn from(size: winit::dpi::PhysicalSize<$f>) -> Self {
635 $T(size.width, size.height)
636 }
637 }
638 };
639}
640
641impl From<kas_text::Vec2> for Vec2 {
642 #[inline]
643 fn from(size: kas_text::Vec2) -> Self {
644 Vec2(size.0, size.1)
645 }
646}
647impl Conv<kas_text::Vec2> for Vec2 {
648 #[inline]
649 fn conv(size: kas_text::Vec2) -> Self {
650 Vec2(size.0, size.1)
651 }
652 #[inline]
653 fn try_conv(v: kas_text::Vec2) -> Result<Self> {
654 Ok(Self::conv(v))
655 }
656}
657
658impl From<Vec2> for kas_text::Vec2 {
659 #[inline]
660 fn from(size: Vec2) -> kas_text::Vec2 {
661 kas_text::Vec2(size.0, size.1)
662 }
663}
664impl Conv<Vec2> for kas_text::Vec2 {
665 #[inline]
666 fn conv(size: Vec2) -> kas_text::Vec2 {
667 kas_text::Vec2(size.0, size.1)
668 }
669 #[inline]
670 fn try_conv(v: Vec2) -> Result<Self> {
671 Ok(Self::conv(v))
672 }
673}
674
675impl From<Vec2> for DVec2 {
676 #[inline]
677 fn from(v: Vec2) -> DVec2 {
678 DVec2(v.0.into(), v.1.into())
679 }
680}
681impl Conv<Vec2> for DVec2 {
682 #[inline]
683 fn try_conv(v: Vec2) -> Result<DVec2> {
684 Ok(DVec2(v.0.into(), v.1.into()))
685 }
686}
687impl ConvApprox<DVec2> for Vec2 {
688 fn try_conv_approx(size: DVec2) -> Result<Vec2> {
689 Ok(Vec2(size.0.try_cast_approx()?, size.1.try_cast_approx()?))
690 }
691}
692
693impl_vec2!(Vec2, f32);
694impl_vec2!(DVec2, f64);
695
696macro_rules! impl_conv_vec2 {
697 ($S:ty, $T:ty) => {
698 impl Conv<$S> for $T {
699 #[inline]
700 fn try_conv(arg: $S) -> Result<Self> {
701 Ok(Self(arg.0.try_cast()?, arg.1.try_cast()?))
702 }
703 }
704
705 impl ConvApprox<$T> for $S {
706 #[inline]
707 fn try_conv_approx(arg: $T) -> Result<Self> {
708 Ok(Self(arg.0.try_cast_approx()?, arg.1.try_cast_approx()?))
709 }
710 }
711
712 impl ConvFloat<$T> for $S {
713 #[inline]
714 fn try_conv_trunc(x: $T) -> Result<Self> {
715 Ok(Self(i32::try_conv_trunc(x.0)?, i32::try_conv_trunc(x.1)?))
716 }
717 #[inline]
718 fn try_conv_nearest(x: $T) -> Result<Self> {
719 Ok(Self(
720 i32::try_conv_nearest(x.0)?,
721 i32::try_conv_nearest(x.1)?,
722 ))
723 }
724 #[inline]
725 fn try_conv_floor(x: $T) -> Result<Self> {
726 Ok(Self(i32::try_conv_floor(x.0)?, i32::try_conv_floor(x.1)?))
727 }
728 #[inline]
729 fn try_conv_ceil(x: $T) -> Result<Self> {
730 Ok(Self(i32::try_conv_ceil(x.0)?, i32::try_conv_ceil(x.1)?))
731 }
732 }
733 };
734}
735
736impl_conv_vec2!(Coord, Vec2);
737impl_conv_vec2!(Size, Vec2);
738impl_conv_vec2!(Offset, Vec2);
739impl_conv_vec2!(Coord, DVec2);
740impl_conv_vec2!(Size, DVec2);
741impl_conv_vec2!(Offset, DVec2);
742
743#[repr(C)]
747#[derive(Clone, Copy, Debug, Default, PartialEq)]
748#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
749pub struct Vec3(pub f32, pub f32, pub f32);
750
751impl Vec3 {
752 #[inline]
754 pub fn from2(v: Vec2, z: f32) -> Self {
755 Vec3(v.0, v.1, z)
756 }
757}