use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize, JsonSchema)]
pub struct Point3 {
pub x: f64,
pub y: f64,
pub z: f64,
}
impl Point3 {
pub fn new(x: f64, y: f64, z: f64) -> Self {
Point3 { x, y, z }
}
pub fn distance(self, other: Point3) -> f64 {
self.distance_squared(other).sqrt()
}
pub fn distance_squared(self, other: Point3) -> f64 {
(self.x - other.x).powi(2) + (self.y - other.y).powi(2) + (self.z - other.z).powi(2)
}
pub fn vector_from(self, origin: Point3) -> Vector3 {
Vector3::new(self.x - origin.x, self.y - origin.y, self.z - origin.z)
}
#[must_use]
pub fn translated(self, vector: Vector3, scale: f64) -> Point3 {
Point3::new(
self.x + scale * vector.x,
self.y + scale * vector.y,
self.z + scale * vector.z,
)
}
}
#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize, JsonSchema)]
pub struct Vector3 {
pub x: f64,
pub y: f64,
pub z: f64,
}
impl Vector3 {
pub fn new(x: f64, y: f64, z: f64) -> Self {
Vector3 { x, y, z }
}
pub fn norm(&self) -> f64 {
(self.x * self.x + self.y * self.y + self.z * self.z).sqrt()
}
pub fn dot(self, other: Vector3) -> f64 {
self.x * other.x + self.y * other.y + self.z * other.z
}
#[must_use]
pub fn cross(self, other: Vector3) -> Vector3 {
Vector3::new(
self.y * other.z - self.z * other.y,
self.z * other.x - self.x * other.z,
self.x * other.y - self.y * other.x,
)
}
#[must_use]
pub fn scale(self, factor: f64) -> Vector3 {
Vector3::new(self.x * factor, self.y * factor, self.z * factor)
}
#[must_use]
pub fn unit(self) -> Option<Vector3> {
let length = self.norm();
(length > f64::EPSILON)
.then(|| Vector3::new(self.x / length, self.y / length, self.z / length))
}
}
impl std::ops::Add for Vector3 {
type Output = Vector3;
fn add(self, other: Vector3) -> Vector3 {
Vector3::new(self.x + other.x, self.y + other.y, self.z + other.z)
}
}
impl std::ops::Sub for Vector3 {
type Output = Vector3;
fn sub(self, other: Vector3) -> Vector3 {
Vector3::new(self.x - other.x, self.y - other.y, self.z - other.z)
}
}
#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize, JsonSchema)]
pub struct Point2 {
pub u: f64,
pub v: f64,
}
impl Point2 {
pub fn new(u: f64, v: f64) -> Self {
Point2 { u, v }
}
}
#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize, JsonSchema)]
pub struct Aabb {
pub min: Point3,
pub max: Point3,
}