pub struct Coord {
pub x: f64,
pub y: f64,
pub z: f64,
}
Expand description
A point in 3D space. Supports many common arithmetic operations on points.
Coord
has three axes, denoted x
, y
, and z
. These are not any different in any method of
Coord
, so the distinction between them is completely conventional. In Scarlet, any Color
that converts to and from a Coord
will match its components with these axes in the order of the
letters in its name: for example, CIELABColor
maps to a coordinate such that l
is on the
x-axis, a
is on the y-axis, and b
is on the z-axis.
Examples
Basic Operations
let point_1 = Coord{x: 1., y: 8., z: 7.};
let point_2 = Coord{x: 7., y: 2., z: 3.};
// Add two points together to do componentwise addition.
let sum = point_1 + point_2; // the point (8, 10, 10)
// Subtract two points the same way.
let diff = point_1 - point_2; // the point (-6, 6, 4)
// There is no multiplication of two points, because there are many different ways to conceptualize
// multiplying two points and Scarlet doesn't need it. Instead, it supports scalar multiplication
// and division. This has the unfortunate side effect of not allowing multiplication one way.
let prod = point_1 * 2u8; // the point (2, 16, 14)
// switching the above operands' order would cause an error!
let quot = point_1 / 2.; // the point (0.5, 4, 3.5)
Fields§
§x: f64
The first axis.
y: f64
The second axis.
z: f64
The third axis.
Implementations§
source§impl Coord
impl Coord
sourcepub fn midpoint(&self, other: &Coord) -> Coord
pub fn midpoint(&self, other: &Coord) -> Coord
The midpoint between two 3D points: returns a new Coord.
Example
let point1 = Coord{x: 0.25, y: 0., z: 1.};
let point2 = Coord{x: 0.75, y: 1., z: 1.};
let mid = point1.midpoint(&point2);
assert!((mid.x - 0.5).abs() <= 1e-10);
assert!((mid.y - 0.5).abs() <= 1e-10);
assert!((mid.z - 1.).abs() <= 1e-10);
sourcepub fn weighted_midpoint(&self, other: &Coord, weight: f64) -> Coord
pub fn weighted_midpoint(&self, other: &Coord, weight: f64) -> Coord
The weighted midpoint: like the midpoint, but with weighted averages instead of the arithmetic mean. Very strange things may happen if the weight is not between 0 and 1. Note that a small weight moves values further away from the first point (the one calling the method), while a larger weight moves values away from the second point (the one being passed in).
Example
let point1 = Coord{x: 0.2, y: 0., z: 1.};
let point2 = Coord{x: 1., y: 0.8, z: 1.};
let mid = point1.weighted_midpoint(&point2, 0.25);
// note how this is not 0.6 because the weight has shifted it towards the second point
assert!((mid.x - 0.8).abs() <= 1e-10);
assert!((mid.y - 0.6).abs() <= 1e-10);
assert!((mid.z - 1.).abs() <= 1e-10);
sourcepub fn euclidean_distance(&self, other: &Coord) -> f64
pub fn euclidean_distance(&self, other: &Coord) -> f64
The Euclidean difference between two 3D points, defined as the square root of the sum of
squares of differences in each axis.
It’s very tempting to use this is as an analogue for perceptual difference between two colors,
but this should generally be avoided. The reason is that projection into 3D space does not
necessarily make distance a good analogue of perceptual difference. A very clear example would
be the two HSVColor
points (360., 1., 1.) and (0., 1., 1.), which are the same point even
though their difference is 360, or examples with very low luminance: (275., 0., 0.,) and
(300., 0.4, 0.) represent the exact same color as well. Even in additive primary spaces like
RGB, this is usually a bad way of getting color distance: for example, humans are very good at
distinguishing between blues compared to greens, so two greens with the same Euclidean
distance as two blues will look much closer. If you want a method of determining how different
two colors look, use the color::distance
method, which provides the current industry and
scientific standard for doing so.
Example
let point1 = Coord{x: 0., y: 0., z: -1.};
let point2 = Coord{x: 2., y: 3., z: 5.};
let dist = point1.euclidean_distance(&point2);
assert!((dist - 7.).abs() <= 1e-10);
sourcepub fn average(self, others: &[Coord]) -> Coord
pub fn average(self, others: &[Coord]) -> Coord
Gets the arithmetic mean of self
, alongside other coordinates.
Example
let point1 = Coord{x: 0., y: 0., z: 1.};
let others = vec![Coord{x: 1., y: 1., z: 1.}, Coord{x: 2., y: 1., z: 1.}];
let mean = point1.average(&others);
assert!((mean.x - 1.).abs() <= 1e-10);
assert!((mean.y - 2. / 3.).abs() <= 1e-10);
assert!((mean.z - 1.).abs() <= 1e-10);
Trait Implementations§
source§impl<'de> Deserialize<'de> for Coord
impl<'de> Deserialize<'de> for Coord
source§fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where __D: Deserializer<'de>,
source§impl From<AdobeRGBColor> for Coord
impl From<AdobeRGBColor> for Coord
source§fn from(val: AdobeRGBColor) -> Self
fn from(val: AdobeRGBColor) -> Self
source§impl From<CIELABColor> for Coord
impl From<CIELABColor> for Coord
source§fn from(val: CIELABColor) -> Self
fn from(val: CIELABColor) -> Self
source§impl From<CIELCHColor> for Coord
impl From<CIELCHColor> for Coord
source§fn from(val: CIELCHColor) -> Self
fn from(val: CIELCHColor) -> Self
source§impl From<CIELCHuvColor> for Coord
impl From<CIELCHuvColor> for Coord
source§fn from(val: CIELCHuvColor) -> Self
fn from(val: CIELCHuvColor) -> Self
source§impl From<CIELUVColor> for Coord
impl From<CIELUVColor> for Coord
source§fn from(val: CIELUVColor) -> Self
fn from(val: CIELUVColor) -> Self
source§impl From<Coord> for AdobeRGBColor
impl From<Coord> for AdobeRGBColor
source§fn from(c: Coord) -> AdobeRGBColor
fn from(c: Coord) -> AdobeRGBColor
source§impl From<Coord> for CIELABColor
impl From<Coord> for CIELABColor
source§fn from(c: Coord) -> CIELABColor
fn from(c: Coord) -> CIELABColor
source§impl From<Coord> for CIELCHColor
impl From<Coord> for CIELCHColor
source§fn from(c: Coord) -> CIELCHColor
fn from(c: Coord) -> CIELCHColor
source§impl From<Coord> for CIELCHuvColor
impl From<Coord> for CIELCHuvColor
source§fn from(c: Coord) -> CIELCHuvColor
fn from(c: Coord) -> CIELCHuvColor
source§impl From<Coord> for CIELUVColor
impl From<Coord> for CIELUVColor
source§fn from(c: Coord) -> CIELUVColor
fn from(c: Coord) -> CIELUVColor
source§impl From<Coord> for ROMMRGBColor
impl From<Coord> for ROMMRGBColor
source§fn from(c: Coord) -> ROMMRGBColor
fn from(c: Coord) -> ROMMRGBColor
source§impl From<ROMMRGBColor> for Coord
impl From<ROMMRGBColor> for Coord
source§fn from(val: ROMMRGBColor) -> Self
fn from(val: ROMMRGBColor) -> Self
source§impl PartialEq<Coord> for Coord
impl PartialEq<Coord> for Coord
source§impl Sub<Coord> for Coord
impl Sub<Coord> for Coord
This is a perfect analogue to numbers: for any Coords c1, c2, and c3 with the same type, c1 + c2 = c3 implies c3 - c2 = c1 and c3 - c1 = c2, down to floating point error if that exists.
impl Copy for Coord
impl StructuralPartialEq for Coord
Auto Trait Implementations§
impl RefUnwindSafe for Coord
impl Send for Coord
impl Sync for Coord
impl Unpin for Coord
impl UnwindSafe for Coord
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
§impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
impl<SS, SP> SupersetOf<SS> for SPwhere SS: SubsetOf<SP>,
§fn to_subset(&self) -> Option<SS>
fn to_subset(&self) -> Option<SS>
self
from the equivalent element of its
superset. Read more§fn is_in_subset(&self) -> bool
fn is_in_subset(&self) -> bool
self
is actually part of its subset T
(and can be converted to it).§fn to_subset_unchecked(&self) -> SS
fn to_subset_unchecked(&self) -> SS
self.to_subset
but without any property checks. Always succeeds.§fn from_subset(element: &SS) -> SP
fn from_subset(element: &SS) -> SP
self
to the equivalent element of its superset.