pbrt/core/geometry.rs
1// Copyright 2018 Google LLC
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     https://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15//! Types and utilities for dealing with 2D and 3D, integer and float data types.
16use std::fmt;
17use std::ops::Add;
18use std::ops::Div;
19use std::ops::Mul;
20use std::ops::Sub;
21
22use crate::float;
23use crate::Float;
24
25mod bounds;
26pub use crate::core::geometry::bounds::Bounds2;
27pub use crate::core::geometry::bounds::Bounds2f;
28pub use crate::core::geometry::bounds::Bounds2i;
29pub use crate::core::geometry::bounds::Bounds3;
30pub use crate::core::geometry::bounds::Bounds3f;
31pub use crate::core::geometry::bounds::Bounds3i;
32
33mod normal;
34pub use crate::core::geometry::normal::Normal3;
35pub use crate::core::geometry::normal::Normal3f;
36
37mod point;
38pub use crate::core::geometry::point::Point2;
39pub use crate::core::geometry::point::Point2f;
40pub use crate::core::geometry::point::Point2i;
41pub use crate::core::geometry::point::Point3;
42pub use crate::core::geometry::point::Point3f;
43pub use crate::core::geometry::point::Point3i;
44
45mod vector;
46pub use crate::core::geometry::vector::Vector2;
47pub use crate::core::geometry::vector::Vector2f;
48pub use crate::core::geometry::vector::Vector2i;
49pub use crate::core::geometry::vector::Vector3f;
50pub use crate::core::geometry::vector::Vector3i;
51
52/// Trait for ensuring methods present on only `{float}` or `{integer}` types have appropriate
53/// implementations as necessary for this crate.
54pub trait Number
55where
56    Self: std::marker::Sized
57        + Copy
58        + fmt::Display
59        + std::cmp::PartialOrd
60        + Add<Output = Self>
61        + Div<Output = Self>
62        + Mul<Output = Self>
63        + Sub<Output = Self>,
64{
65    /// Returns true if this value is NaN.
66    /// # Examples
67    /// ```
68    /// use pbrt::core::geometry::Number;
69    /// use pbrt::float::NAN;
70    /// use pbrt::Float;
71    ///
72    /// let i: isize = 1;
73    /// let f1: Float = 1.;
74    /// let f2 = NAN;
75    /// assert_eq!(Number::is_nan(f1), false);
76    /// assert_eq!(Number::is_nan(f2), true);
77    /// assert_eq!(Number::is_nan(i), false);
78    /// ```
79    fn is_nan(self) -> bool;
80
81    /// Returns the smallest value this type can hold.
82    ///
83    /// # Examples
84    /// ```
85    /// use pbrt::core::geometry::Number;
86    /// use pbrt::Float;
87    ///
88    /// #[cfg(not(feature = "float-as-double"))]
89    /// assert_eq!(<Float as Number>::min_value(), -3.4028235e+38);
90    /// #[cfg(feature = "float-as-double")]
91    /// assert_eq!(<Float as Number>::min_value(), -1.7976931348623157e+308);
92    /// assert_eq!(<isize as Number>::min_value(), -9223372036854775808);
93    /// ```
94    fn min_value() -> Self;
95
96    /// Returns the largest value this type can hold.
97    ///
98    /// # Examples
99    /// ```
100    /// use pbrt::core::geometry::Number;
101    /// use pbrt::Float;
102    ///
103    /// #[cfg(not(feature = "float-as-double"))]
104    /// assert_eq!(<Float as Number>::max_value(), 3.4028235e+38);
105    /// #[cfg(feature = "float-as-double")]
106    /// assert_eq!(<Float as Number>::max_value(), 1.7976931348623157e+308);
107    /// assert_eq!(<isize as Number>::max_value(), 9223372036854775807);
108    /// ```
109    fn max_value() -> Self;
110
111    /// Returns the maximum of self or other.  No special care is taken for NaN and infinity.
112    ///
113    /// # Examples
114    /// ```
115    /// use pbrt::core::geometry::Number;
116    /// use pbrt::Float;
117    ///
118    /// let x: Float = 1.;
119    /// let y: Float = 2.;
120    ///
121    /// assert_eq!(Number::max(x, y), y);
122    /// assert_eq!(Number::max(x, y), y);
123    ///
124    /// let a: isize = 1;
125    /// let b: isize = 2;
126    ///
127    /// assert_eq!(Number::max(a, b), b);
128    /// assert_eq!(Number::max(a, b), b);
129    ///
130    /// fn bigger<T>(m: T, n: T) -> T
131    /// where
132    ///     T: Number,
133    /// {
134    ///     m.max(n)
135    /// }
136    /// assert_eq!(bigger(a, b), b)
137    /// ```
138    fn max(self, other: Self) -> Self;
139
140    /// Returns the minimum of self or other.  No special care is taken for NaN and infinity.
141    ///
142    /// # Examples
143    /// ```
144    /// use pbrt::core::geometry::Number;
145    /// use pbrt::Float;
146    ///
147    /// let x: Float = 1.;
148    /// let y: Float = 2.;
149    ///
150    /// assert_eq!(Number::min(x, y), x);
151    /// assert_eq!(Number::min(x, y), x);
152    ///
153    /// let a: isize = 1;
154    /// let b: isize = 2;
155    ///
156    /// assert_eq!(Number::min(a, b), a);
157    /// assert_eq!(Number::min(a, b), a);
158    ///
159    /// fn smaller<T>(m: T, n: T) -> T
160    /// where
161    ///     T: Number,
162    /// {
163    ///     m.min(n)
164    /// }
165    /// assert_eq!(smaller(a, b), a)
166    /// ```
167    fn min(self, other: Self) -> Self;
168}
169
170impl Number for Float {
171    fn is_nan(self) -> bool {
172        self.is_nan()
173    }
174    fn min_value() -> Self {
175        float::MIN
176    }
177    fn max_value() -> Self {
178        float::MAX
179    }
180    fn max(self, other: Self) -> Self {
181        if self > other {
182            self
183        } else {
184            other
185        }
186    }
187    fn min(self, other: Self) -> Self {
188        if self < other {
189            self
190        } else {
191            other
192        }
193    }
194}
195
196impl Number for isize {
197    fn is_nan(self) -> bool {
198        false
199    }
200    fn min_value() -> Self {
201        std::isize::MIN
202    }
203    fn max_value() -> Self {
204        std::isize::MAX
205    }
206    fn max(self, other: Self) -> Self {
207        if self > other {
208            self
209        } else {
210            other
211        }
212    }
213    fn min(self, other: Self) -> Self {
214        if self < other {
215            self
216        } else {
217            other
218        }
219    }
220}