chromatic/spaces/xyz/
mod.rs1use num_traits::Float;
6
7mod colour;
8mod convert;
9mod fmt;
10
11#[derive(Debug, Clone, Copy)]
13pub struct Xyz<T: Float + Send + Sync> {
14 x: T,
16 y: T,
18 z: T,
20}
21
22impl<T: Float + Send + Sync> Xyz<T> {
23 #[inline]
27 pub fn new(x: T, y: T, z: T) -> Self {
28 debug_assert!(x >= T::zero(), "X component should be non-negative.");
29 debug_assert!(y >= T::zero(), "Y component should be non-negative.");
30 debug_assert!(z >= T::zero(), "Z component should be non-negative.");
31 Self { x, y, z }
32 }
33
34 #[inline]
36 pub const fn x(&self) -> T {
37 self.x
38 }
39
40 #[inline]
42 pub const fn y(&self) -> T {
43 self.y
44 }
45
46 #[inline]
48 pub const fn z(&self) -> T {
49 self.z
50 }
51
52 #[inline]
54 pub fn set_x(&mut self, x: T) {
55 debug_assert!(x >= T::zero(), "X component should be non-negative.");
56 self.x = x;
57 }
58
59 #[inline]
61 pub fn set_y(&mut self, y: T) {
62 debug_assert!(y >= T::zero(), "Y component should be non-negative.");
63 self.y = y;
64 }
65
66 #[inline]
68 pub fn set_z(&mut self, z: T) {
69 debug_assert!(z >= T::zero(), "Z component should be non-negative.");
70 self.z = z;
71 }
72
73 #[must_use]
79 #[inline]
80 pub fn d65_reference_white() -> Self {
81 Self::new(T::from(0.95047).unwrap(), T::from(1.0).unwrap(), T::from(1.08883).unwrap())
82 }
83
84 #[must_use]
90 #[inline]
91 pub fn d50_reference_white() -> Self {
92 Self::new(T::from(0.96422).unwrap(), T::from(1.0).unwrap(), T::from(0.82521).unwrap())
93 }
94
95 #[inline]
98 pub fn relative_to_white(&self) -> (T, T, T) {
99 let white = Self::d65_reference_white();
100 (self.x / white.x, self.y / white.y, self.z / white.z)
101 }
102
103 #[inline]
106 pub fn distance(&self, other: &Self) -> T {
107 let dx = self.x - other.x;
108 let dy = self.y - other.y;
109 let dz = self.z - other.z;
110 (dx * dx + dy * dy + dz * dz).sqrt()
111 }
112}