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