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