mirror of https://github.com/hannobraun/Fornjot
Merge pull request #221 from hannobraun/coords
Make math code more convenient to use
This commit is contained in:
commit
4ae6e66137
|
@ -45,13 +45,9 @@ impl Camera {
|
||||||
//
|
//
|
||||||
// To do that, first compute the model's highest point, as well as
|
// To do that, first compute the model's highest point, as well as
|
||||||
// the furthest point from the origin, in x and y.
|
// the furthest point from the origin, in x and y.
|
||||||
let highest_point = aabb.max.z();
|
let highest_point = aabb.max.z;
|
||||||
let furthest_point = [
|
let furthest_point =
|
||||||
aabb.min.x().abs(),
|
[aabb.min.x.abs(), aabb.max.x, aabb.min.y.abs(), aabb.max.y]
|
||||||
aabb.max.x(),
|
|
||||||
aabb.min.y().abs(),
|
|
||||||
aabb.max.y(),
|
|
||||||
]
|
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.reduce(Scalar::max)
|
.reduce(Scalar::max)
|
||||||
// `reduce` can only return `None`, if there are no items in
|
// `reduce` can only return `None`, if there are no items in
|
||||||
|
@ -74,7 +70,7 @@ impl Camera {
|
||||||
|
|
||||||
let initial_offset = {
|
let initial_offset = {
|
||||||
let mut offset = aabb.center();
|
let mut offset = aabb.center();
|
||||||
*offset.z_mut() = Scalar::ZERO;
|
offset.z = Scalar::ZERO;
|
||||||
-offset
|
-offset
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -84,8 +80,8 @@ impl Camera {
|
||||||
|
|
||||||
rotation: Transform::identity(),
|
rotation: Transform::identity(),
|
||||||
translation: Translation::from([
|
translation: Translation::from([
|
||||||
initial_offset.x().into_f64(),
|
initial_offset.x.into_f64(),
|
||||||
initial_offset.y().into_f64(),
|
initial_offset.y.into_f64(),
|
||||||
-initial_distance.into_f64(),
|
-initial_distance.into_f64(),
|
||||||
]),
|
]),
|
||||||
}
|
}
|
||||||
|
|
|
@ -90,22 +90,22 @@ impl Approximation {
|
||||||
// As this is a cycle, neighboring edges are going to share vertices.
|
// As this is a cycle, neighboring edges are going to share vertices.
|
||||||
// Let's remove all those duplicates.
|
// Let's remove all those duplicates.
|
||||||
points.sort_by(|a, b| {
|
points.sort_by(|a, b| {
|
||||||
if a.x() < b.x() {
|
if a.x < b.x {
|
||||||
return Ordering::Less;
|
return Ordering::Less;
|
||||||
}
|
}
|
||||||
if a.x() > b.x() {
|
if a.x > b.x {
|
||||||
return Ordering::Greater;
|
return Ordering::Greater;
|
||||||
}
|
}
|
||||||
if a.y() < b.y() {
|
if a.y < b.y {
|
||||||
return Ordering::Less;
|
return Ordering::Less;
|
||||||
}
|
}
|
||||||
if a.y() > b.y() {
|
if a.y > b.y {
|
||||||
return Ordering::Greater;
|
return Ordering::Greater;
|
||||||
}
|
}
|
||||||
if a.z() < b.z() {
|
if a.z < b.z {
|
||||||
return Ordering::Less;
|
return Ordering::Less;
|
||||||
}
|
}
|
||||||
if a.z() > b.z() {
|
if a.z > b.z {
|
||||||
return Ordering::Greater;
|
return Ordering::Greater;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -48,7 +48,7 @@ impl Circle {
|
||||||
/// error.
|
/// error.
|
||||||
pub fn point_model_to_curve(&self, point: &Point<3>) -> Point<1> {
|
pub fn point_model_to_curve(&self, point: &Point<3>) -> Point<1> {
|
||||||
let v = point - self.center;
|
let v = point - self.center;
|
||||||
let atan = Scalar::atan2(v.y(), v.x());
|
let atan = Scalar::atan2(v.y, v.x);
|
||||||
let coord = if atan >= Scalar::ZERO {
|
let coord = if atan >= Scalar::ZERO {
|
||||||
atan
|
atan
|
||||||
} else {
|
} else {
|
||||||
|
@ -59,13 +59,13 @@ impl Circle {
|
||||||
|
|
||||||
/// Convert a point on the curve into model coordinates
|
/// Convert a point on the curve into model coordinates
|
||||||
pub fn point_curve_to_model(&self, point: &Point<1>) -> Point<3> {
|
pub fn point_curve_to_model(&self, point: &Point<1>) -> Point<3> {
|
||||||
self.center + self.vector_curve_to_model(&point.coords())
|
self.center + self.vector_curve_to_model(&point.coords)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Convert a vector on the curve into model coordinates
|
/// Convert a vector on the curve into model coordinates
|
||||||
pub fn vector_curve_to_model(&self, point: &Vector<1>) -> Vector<3> {
|
pub fn vector_curve_to_model(&self, vector: &Vector<1>) -> Vector<3> {
|
||||||
let radius = self.radius.magnitude();
|
let radius = self.radius.magnitude();
|
||||||
let angle = point.t();
|
let angle = vector.t;
|
||||||
|
|
||||||
let (sin, cos) = angle.sin_cos();
|
let (sin, cos) = angle.sin_cos();
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
use approx::AbsDiffEq;
|
|
||||||
|
|
||||||
use crate::math::{Point, Transform, Vector};
|
use crate::math::{Point, Transform, Vector};
|
||||||
|
|
||||||
/// A line, defined by a point and a vector
|
/// A line, defined by a point and a vector
|
||||||
|
@ -50,17 +48,17 @@ impl Line {
|
||||||
|
|
||||||
/// Convert a point on the curve into model coordinates
|
/// Convert a point on the curve into model coordinates
|
||||||
pub fn point_curve_to_model(&self, point: &Point<1>) -> Point<3> {
|
pub fn point_curve_to_model(&self, point: &Point<1>) -> Point<3> {
|
||||||
self.origin + self.vector_curve_to_model(&point.coords())
|
self.origin + self.vector_curve_to_model(&point.coords)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Convert a vector on the curve into model coordinates
|
/// Convert a vector on the curve into model coordinates
|
||||||
pub fn vector_curve_to_model(&self, point: &Vector<1>) -> Vector<3> {
|
pub fn vector_curve_to_model(&self, vector: &Vector<1>) -> Vector<3> {
|
||||||
self.direction * point.t()
|
self.direction * vector.t
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AbsDiffEq for Line {
|
impl approx::AbsDiffEq for Line {
|
||||||
type Epsilon = <f64 as AbsDiffEq>::Epsilon;
|
type Epsilon = <f64 as approx::AbsDiffEq>::Epsilon;
|
||||||
|
|
||||||
fn default_epsilon() -> Self::Epsilon {
|
fn default_epsilon() -> Self::Epsilon {
|
||||||
f64::default_epsilon()
|
f64::default_epsilon()
|
||||||
|
|
|
@ -24,7 +24,7 @@ impl Swept {
|
||||||
|
|
||||||
/// Convert a point in model coordinates to surface coordinates
|
/// Convert a point in model coordinates to surface coordinates
|
||||||
pub fn point_model_to_surface(&self, point: &Point<3>) -> Point<2> {
|
pub fn point_model_to_surface(&self, point: &Point<3>) -> Point<2> {
|
||||||
let u = self.curve.point_model_to_curve(point).t();
|
let u = self.curve.point_model_to_curve(point).t;
|
||||||
let v = (point - self.curve.origin()).dot(&self.path.normalize())
|
let v = (point - self.curve.origin()).dot(&self.path.normalize())
|
||||||
/ self.path.magnitude();
|
/ self.path.magnitude();
|
||||||
|
|
||||||
|
@ -33,13 +33,12 @@ impl Swept {
|
||||||
|
|
||||||
/// Convert a point in surface coordinates to model coordinates
|
/// Convert a point in surface coordinates to model coordinates
|
||||||
pub fn point_surface_to_model(&self, point: &Point<2>) -> Point<3> {
|
pub fn point_surface_to_model(&self, point: &Point<2>) -> Point<3> {
|
||||||
self.curve.point_curve_to_model(&point.to_t()) + self.path * point.v()
|
self.curve.point_curve_to_model(&point.to_t()) + self.path * point.v
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Convert a vector in surface coordinates to model coordinates
|
/// Convert a vector in surface coordinates to model coordinates
|
||||||
pub fn vector_surface_to_model(&self, vector: &Vector<2>) -> Vector<3> {
|
pub fn vector_surface_to_model(&self, vector: &Vector<2>) -> Vector<3> {
|
||||||
self.curve.vector_curve_to_model(&vector.to_t())
|
self.curve.vector_curve_to_model(&vector.to_t()) + self.path * vector.v
|
||||||
+ self.path * vector.v()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,7 @@ use crate::{
|
||||||
impl Shape for fj::Sweep {
|
impl Shape for fj::Sweep {
|
||||||
fn bounding_volume(&self) -> Aabb<3> {
|
fn bounding_volume(&self) -> Aabb<3> {
|
||||||
let mut aabb = self.shape.bounding_volume();
|
let mut aabb = self.shape.bounding_volume();
|
||||||
*aabb.max.z_mut() = self.length.into();
|
aabb.max.z = self.length.into();
|
||||||
aabb
|
aabb
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -40,8 +40,8 @@ impl HasPosition for SurfacePoint {
|
||||||
|
|
||||||
fn position(&self) -> spade::Point2<Self::Scalar> {
|
fn position(&self) -> spade::Point2<Self::Scalar> {
|
||||||
spade::Point2 {
|
spade::Point2 {
|
||||||
x: self.value.u(),
|
x: self.value.u,
|
||||||
y: self.value.v(),
|
y: self.value.v,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
use super::Scalar;
|
||||||
|
|
||||||
|
/// 1-dimensional curve coordinates
|
||||||
|
#[repr(C)]
|
||||||
|
pub struct T {
|
||||||
|
pub t: Scalar,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 2-dimensional surface coordinates
|
||||||
|
#[repr(C)]
|
||||||
|
pub struct Uv {
|
||||||
|
pub u: Scalar,
|
||||||
|
pub v: Scalar,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 3-dimensional model coordinates
|
||||||
|
#[repr(C)]
|
||||||
|
pub struct Xyz {
|
||||||
|
pub x: Scalar,
|
||||||
|
pub y: Scalar,
|
||||||
|
pub z: Scalar,
|
||||||
|
}
|
|
@ -1,4 +1,5 @@
|
||||||
pub mod aabb;
|
pub mod aabb;
|
||||||
|
pub mod coordinates;
|
||||||
pub mod point;
|
pub mod point;
|
||||||
pub mod scalar;
|
pub mod scalar;
|
||||||
pub mod segment;
|
pub mod segment;
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
use std::ops;
|
use std::ops;
|
||||||
|
|
||||||
use approx::AbsDiffEq;
|
use super::{
|
||||||
|
coordinates::{Uv, Xyz, T},
|
||||||
use super::{Scalar, Vector};
|
Scalar, Vector,
|
||||||
|
};
|
||||||
|
|
||||||
/// An n-dimensional point
|
/// An n-dimensional point
|
||||||
///
|
///
|
||||||
|
@ -13,7 +14,9 @@ use super::{Scalar, Vector};
|
||||||
/// The goal of this type is to eventually implement `Eq` and `Hash`, making it
|
/// The goal of this type is to eventually implement `Eq` and `Hash`, making it
|
||||||
/// easier to work with vectors. This is a work in progress.
|
/// easier to work with vectors. This is a work in progress.
|
||||||
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, Ord, PartialOrd)]
|
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, Ord, PartialOrd)]
|
||||||
pub struct Point<const D: usize>([Scalar; D]);
|
pub struct Point<const D: usize> {
|
||||||
|
pub coords: Vector<D>,
|
||||||
|
}
|
||||||
|
|
||||||
impl<const D: usize> Point<D> {
|
impl<const D: usize> Point<D> {
|
||||||
/// Construct a `Point` at the origin of the coordinate system
|
/// Construct a `Point` at the origin of the coordinate system
|
||||||
|
@ -23,74 +26,80 @@ impl<const D: usize> Point<D> {
|
||||||
|
|
||||||
/// Construct a `Point` from an array
|
/// Construct a `Point` from an array
|
||||||
pub fn from_array(array: [f64; D]) -> Self {
|
pub fn from_array(array: [f64; D]) -> Self {
|
||||||
Self(array.map(Scalar::from_f64))
|
Self {
|
||||||
|
coords: array.map(Scalar::from_f64).into(),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Construct a `Point` from an nalgebra vector
|
/// Construct a `Point` from an nalgebra vector
|
||||||
pub fn from_na(point: nalgebra::Point<f64, D>) -> Self {
|
pub fn from_na(point: nalgebra::Point<f64, D>) -> Self {
|
||||||
Self(point.coords.data.0[0].map(Scalar::from_f64))
|
Self {
|
||||||
|
coords: point.coords.into(),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Convert the point into an nalgebra point
|
/// Convert the point into an nalgebra point
|
||||||
pub fn to_na(&self) -> nalgebra::Point<f64, D> {
|
pub fn to_na(&self) -> nalgebra::Point<f64, D> {
|
||||||
self.0.map(Scalar::into_f64).into()
|
nalgebra::Point {
|
||||||
|
coords: self.coords.into(),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Convert to a 1-dimensional point
|
/// Convert to a 1-dimensional point
|
||||||
pub fn to_t(&self) -> Point<1> {
|
pub fn to_t(&self) -> Point<1> {
|
||||||
Point([self.0[0]])
|
Point {
|
||||||
|
coords: self.coords.to_t(),
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Access a mutable reference to the point's z coordinate
|
|
||||||
pub fn z_mut(&mut self) -> &mut Scalar {
|
|
||||||
&mut self.0[2]
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Access the point's coordinates as a vector
|
|
||||||
pub fn coords(&self) -> Vector<D> {
|
|
||||||
Vector::from(self.0)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Point<1> {
|
impl ops::Deref for Point<1> {
|
||||||
/// Access the curve point's t coordinate
|
type Target = T;
|
||||||
pub fn t(&self) -> Scalar {
|
|
||||||
self.0[0]
|
fn deref(&self) -> &Self::Target {
|
||||||
|
self.coords.deref()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Point<2> {
|
impl ops::Deref for Point<2> {
|
||||||
/// Access the point's x coordinate
|
type Target = Uv;
|
||||||
pub fn u(&self) -> Scalar {
|
|
||||||
self.0[0]
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Access the point's y coordinate
|
fn deref(&self) -> &Self::Target {
|
||||||
pub fn v(&self) -> Scalar {
|
self.coords.deref()
|
||||||
self.0[1]
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Point<3> {
|
impl ops::Deref for Point<3> {
|
||||||
/// Access the point's x coordinate
|
type Target = Xyz;
|
||||||
pub fn x(&self) -> Scalar {
|
|
||||||
self.0[0]
|
fn deref(&self) -> &Self::Target {
|
||||||
|
self.coords.deref()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Access the point's y coordinate
|
impl ops::DerefMut for Point<1> {
|
||||||
pub fn y(&self) -> Scalar {
|
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||||
self.0[1]
|
self.coords.deref_mut()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Access the point's z coordinate
|
impl ops::DerefMut for Point<2> {
|
||||||
pub fn z(&self) -> Scalar {
|
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||||
self.0[2]
|
self.coords.deref_mut()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ops::DerefMut for Point<3> {
|
||||||
|
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||||
|
self.coords.deref_mut()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<const D: usize> From<[Scalar; D]> for Point<D> {
|
impl<const D: usize> From<[Scalar; D]> for Point<D> {
|
||||||
fn from(array: [Scalar; D]) -> Self {
|
fn from(array: [Scalar; D]) -> Self {
|
||||||
Self(array)
|
Self {
|
||||||
|
coords: array.into(),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -108,13 +117,13 @@ impl<const D: usize> From<nalgebra::Point<f64, D>> for Point<D> {
|
||||||
|
|
||||||
impl<const D: usize> From<Point<D>> for [f32; D] {
|
impl<const D: usize> From<Point<D>> for [f32; D] {
|
||||||
fn from(point: Point<D>) -> Self {
|
fn from(point: Point<D>) -> Self {
|
||||||
point.0.map(|scalar| scalar.into_f32())
|
point.coords.into()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<const D: usize> From<Point<D>> for [f64; D] {
|
impl<const D: usize> From<Point<D>> for [f64; D] {
|
||||||
fn from(point: Point<D>) -> Self {
|
fn from(point: Point<D>) -> Self {
|
||||||
point.0.map(|scalar| scalar.into_f64())
|
point.coords.into()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -158,14 +167,14 @@ impl<const D: usize> ops::Mul<f64> for Point<D> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<const D: usize> AbsDiffEq for Point<D> {
|
impl<const D: usize> approx::AbsDiffEq for Point<D> {
|
||||||
type Epsilon = <f64 as AbsDiffEq>::Epsilon;
|
type Epsilon = <Vector<D> as approx::AbsDiffEq>::Epsilon;
|
||||||
|
|
||||||
fn default_epsilon() -> Self::Epsilon {
|
fn default_epsilon() -> Self::Epsilon {
|
||||||
f64::default_epsilon()
|
f64::default_epsilon()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn abs_diff_eq(&self, other: &Self, epsilon: Self::Epsilon) -> bool {
|
fn abs_diff_eq(&self, other: &Self, epsilon: Self::Epsilon) -> bool {
|
||||||
self.0.abs_diff_eq(&other.0, epsilon)
|
self.coords.abs_diff_eq(&other.coords, epsilon)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
use std::{cmp, f64::consts::PI, hash::Hash, ops};
|
use std::{cmp, f64::consts::PI, hash::Hash, ops};
|
||||||
|
|
||||||
use approx::AbsDiffEq;
|
|
||||||
|
|
||||||
/// A rational, finite scalar value
|
/// A rational, finite scalar value
|
||||||
///
|
///
|
||||||
/// This is a wrapper around `f64`. On construction, it checks that the `f64`
|
/// This is a wrapper around `f64`. On construction, it checks that the `f64`
|
||||||
|
@ -272,8 +270,8 @@ impl num_traits::Signed for Scalar {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AbsDiffEq for Scalar {
|
impl approx::AbsDiffEq for Scalar {
|
||||||
type Epsilon = <f64 as AbsDiffEq>::Epsilon;
|
type Epsilon = <f64 as approx::AbsDiffEq>::Epsilon;
|
||||||
|
|
||||||
fn default_epsilon() -> Self::Epsilon {
|
fn default_epsilon() -> Self::Epsilon {
|
||||||
f64::default_epsilon()
|
f64::default_epsilon()
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
use std::ops;
|
use std::ops;
|
||||||
|
|
||||||
use approx::AbsDiffEq;
|
use super::{
|
||||||
|
coordinates::{Uv, Xyz, T},
|
||||||
use super::Scalar;
|
Scalar,
|
||||||
|
};
|
||||||
|
|
||||||
/// An n-dimensional vector
|
/// An n-dimensional vector
|
||||||
///
|
///
|
||||||
|
@ -13,7 +14,7 @@ use super::Scalar;
|
||||||
/// The goal of this type is to eventually implement `Eq` and `Hash`, making it
|
/// The goal of this type is to eventually implement `Eq` and `Hash`, making it
|
||||||
/// easier to work with vectors. This is a work in progress.
|
/// easier to work with vectors. This is a work in progress.
|
||||||
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, Ord, PartialOrd)]
|
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, Ord, PartialOrd)]
|
||||||
pub struct Vector<const D: usize>([Scalar; D]);
|
pub struct Vector<const D: usize>(pub [Scalar; D]);
|
||||||
|
|
||||||
impl<const D: usize> Vector<D> {
|
impl<const D: usize> Vector<D> {
|
||||||
/// Construct a `Vector` from an array
|
/// Construct a `Vector` from an array
|
||||||
|
@ -62,44 +63,83 @@ impl<const D: usize> Vector<D> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Vector<1> {
|
|
||||||
/// Access the curve vector's t coordinate
|
|
||||||
pub fn t(&self) -> Scalar {
|
|
||||||
self.0[0]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Vector<2> {
|
impl Vector<2> {
|
||||||
/// Access the surface vector's u coordinate
|
|
||||||
pub fn u(&self) -> Scalar {
|
|
||||||
self.0[0]
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Access the surface vector's v coordinate
|
|
||||||
pub fn v(&self) -> Scalar {
|
|
||||||
self.0[1]
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Extend a 2-dimensional vector into a 3-dimensional one
|
/// Extend a 2-dimensional vector into a 3-dimensional one
|
||||||
pub fn to_xyz(&self, z: Scalar) -> Vector<3> {
|
pub fn to_xyz(&self, z: Scalar) -> Vector<3> {
|
||||||
Vector::from([self.u(), self.v(), z])
|
Vector::from([self.u, self.v, z])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Vector<3> {
|
impl Vector<3> {
|
||||||
/// Access the vector's x coordinate
|
|
||||||
pub fn x(&self) -> Scalar {
|
|
||||||
self.0[0]
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Access the vector's y coordinate
|
|
||||||
pub fn y(&self) -> Scalar {
|
|
||||||
self.0[1]
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Construct a new vector from this vector's x and y components
|
/// Construct a new vector from this vector's x and y components
|
||||||
pub fn xy(&self) -> Vector<2> {
|
pub fn xy(&self) -> Vector<2> {
|
||||||
Vector::from([self.x(), self.y()])
|
Vector::from([self.x, self.y])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ops::Deref for Vector<1> {
|
||||||
|
type Target = T;
|
||||||
|
|
||||||
|
fn deref(&self) -> &Self::Target {
|
||||||
|
let ptr = self.0.as_ptr() as *const Self::Target;
|
||||||
|
|
||||||
|
// This is sound. We've created this pointer from a valid instance, that
|
||||||
|
// has the same size and layout as the target.
|
||||||
|
unsafe { &*ptr }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ops::Deref for Vector<2> {
|
||||||
|
type Target = Uv;
|
||||||
|
|
||||||
|
fn deref(&self) -> &Self::Target {
|
||||||
|
let ptr = self.0.as_ptr() as *const Self::Target;
|
||||||
|
|
||||||
|
// This is sound. We've created this pointer from a valid instance, that
|
||||||
|
// has the same size and layout as the target.
|
||||||
|
unsafe { &*ptr }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ops::Deref for Vector<3> {
|
||||||
|
type Target = Xyz;
|
||||||
|
|
||||||
|
fn deref(&self) -> &Self::Target {
|
||||||
|
let ptr = self.0.as_ptr() as *const Self::Target;
|
||||||
|
|
||||||
|
// This is sound. We've created this pointer from a valid instance, that
|
||||||
|
// has the same size and layout as the target.
|
||||||
|
unsafe { &*ptr }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ops::DerefMut for Vector<1> {
|
||||||
|
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||||
|
let ptr = self.0.as_mut_ptr() as *mut Self::Target;
|
||||||
|
|
||||||
|
// This is sound. We've created this pointer from a valid instance, that
|
||||||
|
// has the same size and layout as the target.
|
||||||
|
unsafe { &mut *ptr }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ops::DerefMut for Vector<2> {
|
||||||
|
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||||
|
let ptr = self.0.as_mut_ptr() as *mut Self::Target;
|
||||||
|
|
||||||
|
// This is sound. We've created this pointer from a valid instance, that
|
||||||
|
// has the same size and layout as the target.
|
||||||
|
unsafe { &mut *ptr }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ops::DerefMut for Vector<3> {
|
||||||
|
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||||
|
let ptr = self.0.as_mut_ptr() as *mut Self::Target;
|
||||||
|
|
||||||
|
// This is sound. We've created this pointer from a valid instance, that
|
||||||
|
// has the same size and layout as the target.
|
||||||
|
unsafe { &mut *ptr }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -127,6 +167,18 @@ impl<const D: usize> From<Vector<D>> for [f32; D] {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<const D: usize> From<Vector<D>> for [f64; D] {
|
||||||
|
fn from(vector: Vector<D>) -> Self {
|
||||||
|
vector.0.map(|scalar| scalar.into_f64())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<const D: usize> From<Vector<D>> for nalgebra::SVector<f64, D> {
|
||||||
|
fn from(vector: Vector<D>) -> Self {
|
||||||
|
vector.to_na()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<const D: usize> ops::Add<Self> for Vector<D> {
|
impl<const D: usize> ops::Add<Self> for Vector<D> {
|
||||||
type Output = Self;
|
type Output = Self;
|
||||||
|
|
||||||
|
@ -151,8 +203,8 @@ impl<const D: usize> ops::Div<Scalar> for Vector<D> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<const D: usize> AbsDiffEq for Vector<D> {
|
impl<const D: usize> approx::AbsDiffEq for Vector<D> {
|
||||||
type Epsilon = <f64 as AbsDiffEq>::Epsilon;
|
type Epsilon = <Scalar as approx::AbsDiffEq>::Epsilon;
|
||||||
|
|
||||||
fn default_epsilon() -> Self::Epsilon {
|
fn default_epsilon() -> Self::Epsilon {
|
||||||
f64::default_epsilon()
|
f64::default_epsilon()
|
||||||
|
|
Loading…
Reference in New Issue