math_utils/types/
frame.rs1#[cfg(feature = "derive_serdes")]
4use serde::{Deserialize, Serialize};
5
6use crate::geometry;
7use super::*;
8
9type LinearBasis2 <S> = NonZero2 <S>;
10
11#[cfg_attr(feature = "derive_serdes", derive(Serialize, Deserialize))]
12#[derive(Clone, Copy, Debug, Eq, PartialEq)]
13pub struct PlanarBasis2 <S> (Matrix2 <S>);
14
15type LinearBasis3 <S> = NonZero3 <S>;
16
17#[cfg_attr(feature = "derive_serdes", derive(Serialize, Deserialize))]
18#[derive(Clone, Copy, Debug, Eq, PartialEq)]
19pub struct PlanarBasis3 <S> ([NonZero3 <S>; 2]);
20
21#[cfg_attr(feature = "derive_serdes", derive(Serialize, Deserialize))]
22#[derive(Clone, Copy, Debug, Eq, PartialEq)]
23pub struct EntireBasis3 <S> (Matrix3 <S>);
24
25#[cfg_attr(feature = "derive_serdes", derive(Serialize, Deserialize))]
27#[derive(Clone, Copy, Debug, Eq, PartialEq)]
28pub struct Line2 <S> {
29 pub origin : Point2 <S>,
30 pub basis : LinearBasis2 <S>
31}
32
33#[cfg_attr(feature = "derive_serdes", derive(Serialize, Deserialize))]
35#[derive(Clone, Copy, Debug, Eq, PartialEq)]
36pub struct Plane2 <S> {
37 pub origin : Point2 <S>,
38 pub basis : PlanarBasis2 <S>
39}
40
41#[cfg_attr(feature = "derive_serdes", derive(Serialize, Deserialize))]
43#[derive(Clone, Copy, Debug, Eq, PartialEq)]
44pub struct Line3 <S> {
45 pub origin : Point3 <S>,
46 pub basis : LinearBasis3 <S>
47}
48
49#[cfg_attr(feature = "derive_serdes", derive(Serialize, Deserialize))]
51#[derive(Clone, Copy, Debug, Eq, PartialEq)]
52pub struct Plane3 <S> {
53 pub origin : Point3 <S>,
54 pub basis : PlanarBasis3 <S>
55}
56
57#[cfg_attr(feature = "derive_serdes", derive(Serialize, Deserialize))]
59#[derive(Clone, Copy, Debug, Eq, PartialEq)]
60pub struct Space3 <S> {
61 pub origin : Point3 <S>,
62 pub basis : EntireBasis3 <S>
63}
64
65impl <S : Ring> Line2 <S> {
66 pub fn point (&self, coordinate : S) -> Point2 <S> {
67 self.origin + *self.basis * coordinate
68 }
69}
70impl <S : OrderedRing> From <geometry::Line2 <S>> for Line2 <S> {
71 fn from (line : geometry::Line2 <S>) -> Self {
72 line.affine_line()
73 }
74}
75impl <S : OrderedRing> From <geometry::Ray2 <S>> for Line2 <S> {
76 fn from (ray : geometry::Ray2 <S>) -> Self {
77 ray.affine_line()
78 }
79}
80impl <S : OrderedRing> From <geometry::Segment2 <S>> for Line2 <S> {
81 fn from (segment : geometry::Segment2 <S>) -> Self {
82 segment.affine_line()
83 }
84}
85
86impl <S : Ring> Plane2 <S> {
87 pub fn point (&self, coordinates : Vector2 <S>) -> Point2 <S> {
88 self.origin + *self.basis * coordinates
89 }
90}
91impl <S : OrderedField> From <geometry::Triangle2 <S>> for Plane2 <S> {
92 fn from (triangle : geometry::Triangle2 <S>) -> Self {
93 triangle.affine_plane()
94 }
95}
96
97impl <S : Ring> Line3 <S> {
98 pub fn point (&self, coordinate : S) -> Point3 <S> {
99 self.origin + *self.basis * coordinate
100 }
101}
102impl <S : OrderedRing> From <geometry::Line3 <S>> for Line3 <S> {
103 fn from (line : geometry::Line3 <S>) -> Self {
104 line.affine_line()
105 }
106}
107impl <S : OrderedRing> From <geometry::Ray3 <S>> for Line3 <S> {
108 fn from (ray : geometry::Ray3 <S>) -> Self {
109 ray.affine_line()
110 }
111}
112impl <S : OrderedRing> From <geometry::Segment3 <S>> for Line3 <S> {
113 fn from (segment : geometry::Segment3 <S>) -> Self {
114 segment.affine_line()
115 }
116}
117
118impl <S : Ring> Plane3 <S> {
119 pub fn point (&self, coordinates : Vector2 <S>) -> Point3 <S> {
120 self.origin + *self.basis[0] * coordinates.x + *self.basis[1] * coordinates.y
121 }
122}
123impl <S : OrderedField> From <geometry::Triangle3 <S>> for Plane3 <S> {
124 fn from (triangle : geometry::Triangle3 <S>) -> Self {
125 triangle.affine_plane()
126 }
127}
128
129impl <S> Space3 <S> {
130 pub fn point (&self, coordinates : Vector3 <S>) -> Point3 <S> where S : Ring {
131 self.origin + *self.basis * coordinates
132 }
133}
134
135impl <S : Field> PlanarBasis2 <S> {
136 pub fn new (basis : Matrix2 <S>) -> Option <Self> {
138 if LinearIso::is_invertible (basis) {
139 Some (PlanarBasis2 (basis))
140 } else {
141 None
142 }
143 }
144}
145impl <S> std::ops::Deref for PlanarBasis2 <S> {
146 type Target = Matrix2 <S>;
147 fn deref (&self) -> &Self::Target {
148 &self.0
149 }
150}
151
152impl <S : OrderedRing> PlanarBasis3 <S> {
153 pub fn new (basis : [NonZero3 <S>; 2]) -> Option <Self> {
165 if *basis[0].cross (*basis[1]).self_dot() != S::zero() {
166 Some (PlanarBasis3 (basis))
167 } else {
168 None
169 }
170 }
171}
172impl <S> std::ops::Deref for PlanarBasis3 <S> {
173 type Target = [NonZero3 <S>; 2];
174 fn deref (&self) -> &Self::Target {
175 &self.0
176 }
177}
178
179impl <S : Field> EntireBasis3 <S> {
180 pub fn new (basis : Matrix3 <S>) -> Option <Self> {
182 if LinearIso::is_invertible (basis) {
183 Some (EntireBasis3 (basis))
184 } else {
185 None
186 }
187 }
188}
189impl <S> std::ops::Deref for EntireBasis3 <S> {
190 type Target = Matrix3 <S>;
191 fn deref (&self) -> &Self::Target {
192 &self.0
193 }
194}