glam/f64/
dmat2.rs

1// Generated from mat.rs.tera template. Edit the template, not the generated file.
2
3use crate::{f64::math, swizzles::*, DMat3, DVec2, Mat2};
4use core::fmt;
5use core::iter::{Product, Sum};
6use core::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign};
7
8/// Creates a 2x2 matrix from two column vectors.
9#[inline(always)]
10#[must_use]
11pub const fn dmat2(x_axis: DVec2, y_axis: DVec2) -> DMat2 {
12    DMat2::from_cols(x_axis, y_axis)
13}
14
15/// A 2x2 column major matrix.
16#[derive(Clone, Copy)]
17#[cfg_attr(
18    all(feature = "bytemuck", not(target_arch = "spirv")),
19    derive(bytemuck::Pod, bytemuck::Zeroable)
20)]
21#[cfg_attr(feature = "cuda", repr(align(16)))]
22#[repr(C)]
23pub struct DMat2 {
24    pub x_axis: DVec2,
25    pub y_axis: DVec2,
26}
27
28impl DMat2 {
29    /// A 2x2 matrix with all elements set to `0.0`.
30    pub const ZERO: Self = Self::from_cols(DVec2::ZERO, DVec2::ZERO);
31
32    /// A 2x2 identity matrix, where all diagonal elements are `1`, and all off-diagonal elements are `0`.
33    pub const IDENTITY: Self = Self::from_cols(DVec2::X, DVec2::Y);
34
35    /// All NAN:s.
36    pub const NAN: Self = Self::from_cols(DVec2::NAN, DVec2::NAN);
37
38    #[allow(clippy::too_many_arguments)]
39    #[inline(always)]
40    #[must_use]
41    const fn new(m00: f64, m01: f64, m10: f64, m11: f64) -> Self {
42        Self {
43            x_axis: DVec2::new(m00, m01),
44            y_axis: DVec2::new(m10, m11),
45        }
46    }
47
48    /// Creates a 2x2 matrix from two column vectors.
49    #[inline(always)]
50    #[must_use]
51    pub const fn from_cols(x_axis: DVec2, y_axis: DVec2) -> Self {
52        Self { x_axis, y_axis }
53    }
54
55    /// Creates a 2x2 matrix from a `[f64; 4]` array stored in column major order.
56    /// If your data is stored in row major you will need to `transpose` the returned
57    /// matrix.
58    #[inline]
59    #[must_use]
60    pub const fn from_cols_array(m: &[f64; 4]) -> Self {
61        Self::new(m[0], m[1], m[2], m[3])
62    }
63
64    /// Creates a `[f64; 4]` array storing data in column major order.
65    /// If you require data in row major order `transpose` the matrix first.
66    #[inline]
67    #[must_use]
68    pub const fn to_cols_array(&self) -> [f64; 4] {
69        [self.x_axis.x, self.x_axis.y, self.y_axis.x, self.y_axis.y]
70    }
71
72    /// Creates a 2x2 matrix from a `[[f64; 2]; 2]` 2D array stored in column major order.
73    /// If your data is in row major order you will need to `transpose` the returned
74    /// matrix.
75    #[inline]
76    #[must_use]
77    pub const fn from_cols_array_2d(m: &[[f64; 2]; 2]) -> Self {
78        Self::from_cols(DVec2::from_array(m[0]), DVec2::from_array(m[1]))
79    }
80
81    /// Creates a `[[f64; 2]; 2]` 2D array storing data in column major order.
82    /// If you require data in row major order `transpose` the matrix first.
83    #[inline]
84    #[must_use]
85    pub const fn to_cols_array_2d(&self) -> [[f64; 2]; 2] {
86        [self.x_axis.to_array(), self.y_axis.to_array()]
87    }
88
89    /// Creates a 2x2 matrix with its diagonal set to `diagonal` and all other entries set to 0.
90    #[doc(alias = "scale")]
91    #[inline]
92    #[must_use]
93    pub const fn from_diagonal(diagonal: DVec2) -> Self {
94        Self::new(diagonal.x, 0.0, 0.0, diagonal.y)
95    }
96
97    /// Creates a 2x2 matrix containing the combining non-uniform `scale` and rotation of
98    /// `angle` (in radians).
99    #[inline]
100    #[must_use]
101    pub fn from_scale_angle(scale: DVec2, angle: f64) -> Self {
102        let (sin, cos) = math::sin_cos(angle);
103        Self::new(cos * scale.x, sin * scale.x, -sin * scale.y, cos * scale.y)
104    }
105
106    /// Creates a 2x2 matrix containing a rotation of `angle` (in radians).
107    #[inline]
108    #[must_use]
109    pub fn from_angle(angle: f64) -> Self {
110        let (sin, cos) = math::sin_cos(angle);
111        Self::new(cos, sin, -sin, cos)
112    }
113
114    /// Creates a 2x2 matrix from a 3x3 matrix, discarding the 2nd row and column.
115    #[inline]
116    #[must_use]
117    pub fn from_mat3(m: DMat3) -> Self {
118        Self::from_cols(m.x_axis.xy(), m.y_axis.xy())
119    }
120
121    /// Creates a 2x2 matrix from the minor of the given 3x3 matrix, discarding the `i`th column
122    /// and `j`th row.
123    ///
124    /// # Panics
125    ///
126    /// Panics if `i` or `j` is greater than 2.
127    #[inline]
128    #[must_use]
129    pub fn from_mat3_minor(m: DMat3, i: usize, j: usize) -> Self {
130        match (i, j) {
131            (0, 0) => Self::from_cols(m.y_axis.yz(), m.z_axis.yz()),
132            (0, 1) => Self::from_cols(m.y_axis.xz(), m.z_axis.xz()),
133            (0, 2) => Self::from_cols(m.y_axis.xy(), m.z_axis.xy()),
134            (1, 0) => Self::from_cols(m.x_axis.yz(), m.z_axis.yz()),
135            (1, 1) => Self::from_cols(m.x_axis.xz(), m.z_axis.xz()),
136            (1, 2) => Self::from_cols(m.x_axis.xy(), m.z_axis.xy()),
137            (2, 0) => Self::from_cols(m.x_axis.yz(), m.y_axis.yz()),
138            (2, 1) => Self::from_cols(m.x_axis.xz(), m.y_axis.xz()),
139            (2, 2) => Self::from_cols(m.x_axis.xy(), m.y_axis.xy()),
140            _ => panic!("index out of bounds"),
141        }
142    }
143
144    /// Creates a 2x2 matrix from the first 4 values in `slice`.
145    ///
146    /// # Panics
147    ///
148    /// Panics if `slice` is less than 4 elements long.
149    #[inline]
150    #[must_use]
151    pub const fn from_cols_slice(slice: &[f64]) -> Self {
152        Self::new(slice[0], slice[1], slice[2], slice[3])
153    }
154
155    /// Writes the columns of `self` to the first 4 elements in `slice`.
156    ///
157    /// # Panics
158    ///
159    /// Panics if `slice` is less than 4 elements long.
160    #[inline]
161    pub fn write_cols_to_slice(self, slice: &mut [f64]) {
162        slice[0] = self.x_axis.x;
163        slice[1] = self.x_axis.y;
164        slice[2] = self.y_axis.x;
165        slice[3] = self.y_axis.y;
166    }
167
168    /// Returns the matrix column for the given `index`.
169    ///
170    /// # Panics
171    ///
172    /// Panics if `index` is greater than 1.
173    #[inline]
174    #[must_use]
175    pub fn col(&self, index: usize) -> DVec2 {
176        match index {
177            0 => self.x_axis,
178            1 => self.y_axis,
179            _ => panic!("index out of bounds"),
180        }
181    }
182
183    /// Returns a mutable reference to the matrix column for the given `index`.
184    ///
185    /// # Panics
186    ///
187    /// Panics if `index` is greater than 1.
188    #[inline]
189    pub fn col_mut(&mut self, index: usize) -> &mut DVec2 {
190        match index {
191            0 => &mut self.x_axis,
192            1 => &mut self.y_axis,
193            _ => panic!("index out of bounds"),
194        }
195    }
196
197    /// Returns the matrix row for the given `index`.
198    ///
199    /// # Panics
200    ///
201    /// Panics if `index` is greater than 1.
202    #[inline]
203    #[must_use]
204    pub fn row(&self, index: usize) -> DVec2 {
205        match index {
206            0 => DVec2::new(self.x_axis.x, self.y_axis.x),
207            1 => DVec2::new(self.x_axis.y, self.y_axis.y),
208            _ => panic!("index out of bounds"),
209        }
210    }
211
212    /// Returns `true` if, and only if, all elements are finite.
213    /// If any element is either `NaN`, positive or negative infinity, this will return `false`.
214    #[inline]
215    #[must_use]
216    pub fn is_finite(&self) -> bool {
217        self.x_axis.is_finite() && self.y_axis.is_finite()
218    }
219
220    /// Returns `true` if any elements are `NaN`.
221    #[inline]
222    #[must_use]
223    pub fn is_nan(&self) -> bool {
224        self.x_axis.is_nan() || self.y_axis.is_nan()
225    }
226
227    /// Returns the transpose of `self`.
228    #[inline]
229    #[must_use]
230    pub fn transpose(&self) -> Self {
231        Self {
232            x_axis: DVec2::new(self.x_axis.x, self.y_axis.x),
233            y_axis: DVec2::new(self.x_axis.y, self.y_axis.y),
234        }
235    }
236
237    /// Returns the determinant of `self`.
238    #[inline]
239    #[must_use]
240    pub fn determinant(&self) -> f64 {
241        self.x_axis.x * self.y_axis.y - self.x_axis.y * self.y_axis.x
242    }
243
244    /// Returns the inverse of `self`.
245    ///
246    /// If the matrix is not invertible the returned matrix will be invalid.
247    ///
248    /// # Panics
249    ///
250    /// Will panic if the determinant of `self` is zero when `glam_assert` is enabled.
251    #[inline]
252    #[must_use]
253    pub fn inverse(&self) -> Self {
254        let inv_det = {
255            let det = self.determinant();
256            glam_assert!(det != 0.0);
257            det.recip()
258        };
259        Self::new(
260            self.y_axis.y * inv_det,
261            self.x_axis.y * -inv_det,
262            self.y_axis.x * -inv_det,
263            self.x_axis.x * inv_det,
264        )
265    }
266
267    /// Transforms a 2D vector.
268    #[inline]
269    #[must_use]
270    pub fn mul_vec2(&self, rhs: DVec2) -> DVec2 {
271        #[allow(clippy::suspicious_operation_groupings)]
272        DVec2::new(
273            (self.x_axis.x * rhs.x) + (self.y_axis.x * rhs.y),
274            (self.x_axis.y * rhs.x) + (self.y_axis.y * rhs.y),
275        )
276    }
277
278    /// Multiplies two 2x2 matrices.
279    #[inline]
280    #[must_use]
281    pub fn mul_mat2(&self, rhs: &Self) -> Self {
282        self.mul(rhs)
283    }
284
285    /// Adds two 2x2 matrices.
286    #[inline]
287    #[must_use]
288    pub fn add_mat2(&self, rhs: &Self) -> Self {
289        self.add(rhs)
290    }
291
292    /// Subtracts two 2x2 matrices.
293    #[inline]
294    #[must_use]
295    pub fn sub_mat2(&self, rhs: &Self) -> Self {
296        self.sub(rhs)
297    }
298
299    /// Multiplies a 2x2 matrix by a scalar.
300    #[inline]
301    #[must_use]
302    pub fn mul_scalar(&self, rhs: f64) -> Self {
303        Self::from_cols(self.x_axis.mul(rhs), self.y_axis.mul(rhs))
304    }
305
306    /// Divides a 2x2 matrix by a scalar.
307    #[inline]
308    #[must_use]
309    pub fn div_scalar(&self, rhs: f64) -> Self {
310        let rhs = DVec2::splat(rhs);
311        Self::from_cols(self.x_axis.div(rhs), self.y_axis.div(rhs))
312    }
313
314    /// Returns true if the absolute difference of all elements between `self` and `rhs`
315    /// is less than or equal to `max_abs_diff`.
316    ///
317    /// This can be used to compare if two matrices contain similar elements. It works best
318    /// when comparing with a known value. The `max_abs_diff` that should be used used
319    /// depends on the values being compared against.
320    ///
321    /// For more see
322    /// [comparing floating point numbers](https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/).
323    #[inline]
324    #[must_use]
325    pub fn abs_diff_eq(&self, rhs: Self, max_abs_diff: f64) -> bool {
326        self.x_axis.abs_diff_eq(rhs.x_axis, max_abs_diff)
327            && self.y_axis.abs_diff_eq(rhs.y_axis, max_abs_diff)
328    }
329
330    /// Takes the absolute value of each element in `self`
331    #[inline]
332    #[must_use]
333    pub fn abs(&self) -> Self {
334        Self::from_cols(self.x_axis.abs(), self.y_axis.abs())
335    }
336
337    #[inline]
338    pub fn as_mat2(&self) -> Mat2 {
339        Mat2::from_cols(self.x_axis.as_vec2(), self.y_axis.as_vec2())
340    }
341}
342
343impl Default for DMat2 {
344    #[inline]
345    fn default() -> Self {
346        Self::IDENTITY
347    }
348}
349
350impl Add for DMat2 {
351    type Output = Self;
352    #[inline]
353    fn add(self, rhs: Self) -> Self {
354        Self::from_cols(self.x_axis.add(rhs.x_axis), self.y_axis.add(rhs.y_axis))
355    }
356}
357
358impl Add<&Self> for DMat2 {
359    type Output = Self;
360    #[inline]
361    fn add(self, rhs: &Self) -> Self {
362        self.add(*rhs)
363    }
364}
365
366impl Add<&DMat2> for &DMat2 {
367    type Output = DMat2;
368    #[inline]
369    fn add(self, rhs: &DMat2) -> DMat2 {
370        (*self).add(*rhs)
371    }
372}
373
374impl Add<DMat2> for &DMat2 {
375    type Output = DMat2;
376    #[inline]
377    fn add(self, rhs: DMat2) -> DMat2 {
378        (*self).add(rhs)
379    }
380}
381
382impl AddAssign for DMat2 {
383    #[inline]
384    fn add_assign(&mut self, rhs: Self) {
385        *self = self.add(rhs);
386    }
387}
388
389impl AddAssign<&Self> for DMat2 {
390    #[inline]
391    fn add_assign(&mut self, rhs: &Self) {
392        self.add_assign(*rhs);
393    }
394}
395
396impl Sub for DMat2 {
397    type Output = Self;
398    #[inline]
399    fn sub(self, rhs: Self) -> Self {
400        Self::from_cols(self.x_axis.sub(rhs.x_axis), self.y_axis.sub(rhs.y_axis))
401    }
402}
403
404impl Sub<&Self> for DMat2 {
405    type Output = Self;
406    #[inline]
407    fn sub(self, rhs: &Self) -> Self {
408        self.sub(*rhs)
409    }
410}
411
412impl Sub<&DMat2> for &DMat2 {
413    type Output = DMat2;
414    #[inline]
415    fn sub(self, rhs: &DMat2) -> DMat2 {
416        (*self).sub(*rhs)
417    }
418}
419
420impl Sub<DMat2> for &DMat2 {
421    type Output = DMat2;
422    #[inline]
423    fn sub(self, rhs: DMat2) -> DMat2 {
424        (*self).sub(rhs)
425    }
426}
427
428impl SubAssign for DMat2 {
429    #[inline]
430    fn sub_assign(&mut self, rhs: Self) {
431        *self = self.sub(rhs);
432    }
433}
434
435impl SubAssign<&Self> for DMat2 {
436    #[inline]
437    fn sub_assign(&mut self, rhs: &Self) {
438        self.sub_assign(*rhs);
439    }
440}
441
442impl Neg for DMat2 {
443    type Output = Self;
444    #[inline]
445    fn neg(self) -> Self::Output {
446        Self::from_cols(self.x_axis.neg(), self.y_axis.neg())
447    }
448}
449
450impl Neg for &DMat2 {
451    type Output = DMat2;
452    #[inline]
453    fn neg(self) -> DMat2 {
454        (*self).neg()
455    }
456}
457
458impl Mul for DMat2 {
459    type Output = Self;
460    #[inline]
461    fn mul(self, rhs: Self) -> Self {
462        Self::from_cols(self.mul(rhs.x_axis), self.mul(rhs.y_axis))
463    }
464}
465
466impl Mul<&Self> for DMat2 {
467    type Output = Self;
468    #[inline]
469    fn mul(self, rhs: &Self) -> Self {
470        self.mul(*rhs)
471    }
472}
473
474impl Mul<&DMat2> for &DMat2 {
475    type Output = DMat2;
476    #[inline]
477    fn mul(self, rhs: &DMat2) -> DMat2 {
478        (*self).mul(*rhs)
479    }
480}
481
482impl Mul<DMat2> for &DMat2 {
483    type Output = DMat2;
484    #[inline]
485    fn mul(self, rhs: DMat2) -> DMat2 {
486        (*self).mul(rhs)
487    }
488}
489
490impl MulAssign for DMat2 {
491    #[inline]
492    fn mul_assign(&mut self, rhs: Self) {
493        *self = self.mul(rhs);
494    }
495}
496
497impl MulAssign<&Self> for DMat2 {
498    #[inline]
499    fn mul_assign(&mut self, rhs: &Self) {
500        self.mul_assign(*rhs);
501    }
502}
503
504impl Mul<DVec2> for DMat2 {
505    type Output = DVec2;
506    #[inline]
507    fn mul(self, rhs: DVec2) -> Self::Output {
508        self.mul_vec2(rhs)
509    }
510}
511
512impl Mul<&DVec2> for DMat2 {
513    type Output = DVec2;
514    #[inline]
515    fn mul(self, rhs: &DVec2) -> DVec2 {
516        self.mul(*rhs)
517    }
518}
519
520impl Mul<&DVec2> for &DMat2 {
521    type Output = DVec2;
522    #[inline]
523    fn mul(self, rhs: &DVec2) -> DVec2 {
524        (*self).mul(*rhs)
525    }
526}
527
528impl Mul<DVec2> for &DMat2 {
529    type Output = DVec2;
530    #[inline]
531    fn mul(self, rhs: DVec2) -> DVec2 {
532        (*self).mul(rhs)
533    }
534}
535
536impl Mul<DMat2> for f64 {
537    type Output = DMat2;
538    #[inline]
539    fn mul(self, rhs: DMat2) -> Self::Output {
540        rhs.mul_scalar(self)
541    }
542}
543
544impl Mul<&DMat2> for f64 {
545    type Output = DMat2;
546    #[inline]
547    fn mul(self, rhs: &DMat2) -> DMat2 {
548        self.mul(*rhs)
549    }
550}
551
552impl Mul<&DMat2> for &f64 {
553    type Output = DMat2;
554    #[inline]
555    fn mul(self, rhs: &DMat2) -> DMat2 {
556        (*self).mul(*rhs)
557    }
558}
559
560impl Mul<DMat2> for &f64 {
561    type Output = DMat2;
562    #[inline]
563    fn mul(self, rhs: DMat2) -> DMat2 {
564        (*self).mul(rhs)
565    }
566}
567
568impl Mul<f64> for DMat2 {
569    type Output = Self;
570    #[inline]
571    fn mul(self, rhs: f64) -> Self {
572        self.mul_scalar(rhs)
573    }
574}
575
576impl Mul<&f64> for DMat2 {
577    type Output = Self;
578    #[inline]
579    fn mul(self, rhs: &f64) -> Self {
580        self.mul(*rhs)
581    }
582}
583
584impl Mul<&f64> for &DMat2 {
585    type Output = DMat2;
586    #[inline]
587    fn mul(self, rhs: &f64) -> DMat2 {
588        (*self).mul(*rhs)
589    }
590}
591
592impl Mul<f64> for &DMat2 {
593    type Output = DMat2;
594    #[inline]
595    fn mul(self, rhs: f64) -> DMat2 {
596        (*self).mul(rhs)
597    }
598}
599
600impl MulAssign<f64> for DMat2 {
601    #[inline]
602    fn mul_assign(&mut self, rhs: f64) {
603        *self = self.mul(rhs);
604    }
605}
606
607impl MulAssign<&f64> for DMat2 {
608    #[inline]
609    fn mul_assign(&mut self, rhs: &f64) {
610        self.mul_assign(*rhs);
611    }
612}
613
614impl Div<DMat2> for f64 {
615    type Output = DMat2;
616    #[inline]
617    fn div(self, rhs: DMat2) -> Self::Output {
618        rhs.div_scalar(self)
619    }
620}
621
622impl Div<&DMat2> for f64 {
623    type Output = DMat2;
624    #[inline]
625    fn div(self, rhs: &DMat2) -> DMat2 {
626        self.div(*rhs)
627    }
628}
629
630impl Div<&DMat2> for &f64 {
631    type Output = DMat2;
632    #[inline]
633    fn div(self, rhs: &DMat2) -> DMat2 {
634        (*self).div(*rhs)
635    }
636}
637
638impl Div<DMat2> for &f64 {
639    type Output = DMat2;
640    #[inline]
641    fn div(self, rhs: DMat2) -> DMat2 {
642        (*self).div(rhs)
643    }
644}
645
646impl Div<f64> for DMat2 {
647    type Output = Self;
648    #[inline]
649    fn div(self, rhs: f64) -> Self {
650        self.div_scalar(rhs)
651    }
652}
653
654impl Div<&f64> for DMat2 {
655    type Output = Self;
656    #[inline]
657    fn div(self, rhs: &f64) -> Self {
658        self.div(*rhs)
659    }
660}
661
662impl Div<&f64> for &DMat2 {
663    type Output = DMat2;
664    #[inline]
665    fn div(self, rhs: &f64) -> DMat2 {
666        (*self).div(*rhs)
667    }
668}
669
670impl Div<f64> for &DMat2 {
671    type Output = DMat2;
672    #[inline]
673    fn div(self, rhs: f64) -> DMat2 {
674        (*self).div(rhs)
675    }
676}
677
678impl DivAssign<f64> for DMat2 {
679    #[inline]
680    fn div_assign(&mut self, rhs: f64) {
681        *self = self.div(rhs);
682    }
683}
684
685impl DivAssign<&f64> for DMat2 {
686    #[inline]
687    fn div_assign(&mut self, rhs: &f64) {
688        self.div_assign(*rhs);
689    }
690}
691
692impl Sum<Self> for DMat2 {
693    fn sum<I>(iter: I) -> Self
694    where
695        I: Iterator<Item = Self>,
696    {
697        iter.fold(Self::ZERO, Self::add)
698    }
699}
700
701impl<'a> Sum<&'a Self> for DMat2 {
702    fn sum<I>(iter: I) -> Self
703    where
704        I: Iterator<Item = &'a Self>,
705    {
706        iter.fold(Self::ZERO, |a, &b| Self::add(a, b))
707    }
708}
709
710impl Product for DMat2 {
711    fn product<I>(iter: I) -> Self
712    where
713        I: Iterator<Item = Self>,
714    {
715        iter.fold(Self::IDENTITY, Self::mul)
716    }
717}
718
719impl<'a> Product<&'a Self> for DMat2 {
720    fn product<I>(iter: I) -> Self
721    where
722        I: Iterator<Item = &'a Self>,
723    {
724        iter.fold(Self::IDENTITY, |a, &b| Self::mul(a, b))
725    }
726}
727
728impl PartialEq for DMat2 {
729    #[inline]
730    fn eq(&self, rhs: &Self) -> bool {
731        self.x_axis.eq(&rhs.x_axis) && self.y_axis.eq(&rhs.y_axis)
732    }
733}
734
735#[cfg(not(target_arch = "spirv"))]
736impl AsRef<[f64; 4]> for DMat2 {
737    #[inline]
738    fn as_ref(&self) -> &[f64; 4] {
739        unsafe { &*(self as *const Self as *const [f64; 4]) }
740    }
741}
742
743#[cfg(not(target_arch = "spirv"))]
744impl AsMut<[f64; 4]> for DMat2 {
745    #[inline]
746    fn as_mut(&mut self) -> &mut [f64; 4] {
747        unsafe { &mut *(self as *mut Self as *mut [f64; 4]) }
748    }
749}
750
751impl fmt::Debug for DMat2 {
752    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
753        fmt.debug_struct(stringify!(DMat2))
754            .field("x_axis", &self.x_axis)
755            .field("y_axis", &self.y_axis)
756            .finish()
757    }
758}
759
760impl fmt::Display for DMat2 {
761    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
762        if let Some(p) = f.precision() {
763            write!(f, "[{:.*}, {:.*}]", p, self.x_axis, p, self.y_axis)
764        } else {
765            write!(f, "[{}, {}]", self.x_axis, self.y_axis)
766        }
767    }
768}