172 lines
3.8 KiB
Rust
172 lines
3.8 KiB
Rust
use std::ops::{Add, AddAssign, Div, DivAssign, Index, IndexMut, Mul, MulAssign, Sub, SubAssign};
|
|
|
|
use std::fmt;
|
|
use std::fmt::Display;
|
|
#[derive(Clone, Copy)]
|
|
pub struct Vec3 {
|
|
e: [f64; 3],
|
|
}
|
|
|
|
pub type Point3 = Vec3;
|
|
pub type Color = Vec3;
|
|
|
|
impl Vec3 {
|
|
pub fn new(e0: f64, e1: f64, e2: f64) -> Vec3 {
|
|
Vec3 { e: [e0, e1, e2] }
|
|
}
|
|
|
|
pub fn x(self) -> f64 {
|
|
self[0]
|
|
}
|
|
|
|
pub fn y(self) -> f64 {
|
|
self[1]
|
|
}
|
|
|
|
pub fn z(self) -> f64 {
|
|
self[2]
|
|
}
|
|
|
|
pub fn dot(self, other: Vec3) -> f64 {
|
|
self[0] * other[0] + self[1] * other[1] + self[2] * other[2]
|
|
}
|
|
|
|
pub fn length(self) -> f64 {
|
|
self.dot(self).sqrt()
|
|
}
|
|
pub fn length_squared(self) -> f64 {
|
|
self.dot(self)
|
|
}
|
|
|
|
pub fn cross(self, other: Vec3) -> Vec3 {
|
|
Vec3 {
|
|
e: [
|
|
self[1] * other[2] - self[2] * other[1],
|
|
self[2] * other[0] - self[0] * other[2],
|
|
self[0] * other[1] - self[1] * other[0],
|
|
],
|
|
}
|
|
}
|
|
|
|
pub fn normalized(self) -> Vec3 {
|
|
self / self.length()
|
|
}
|
|
|
|
/*pub fn format_color(self) -> String {
|
|
format!(
|
|
"{} {} {}",
|
|
(255.999 * self[0]) as u64,
|
|
(255.999 * self[1]) as u64,
|
|
(255.999 * self[2]) as u64
|
|
)
|
|
}*/
|
|
pub fn format_color(self, samples_per_pixel: u64) -> String {
|
|
let ir = (256.0 * (self[0] / (samples_per_pixel as f64)).clamp(0.0, 0.999)) as u64;
|
|
let ig = (256.0 * (self[1] / (samples_per_pixel as f64)).clamp(0.0, 0.999)) as u64;
|
|
let ib = (256.0 * (self[2] / (samples_per_pixel as f64)).clamp(0.0, 0.999)) as u64;
|
|
|
|
format!("{} {} {}", ir, ig, ib)
|
|
}
|
|
}
|
|
|
|
impl Index<usize> for Vec3 {
|
|
type Output = f64;
|
|
|
|
fn index(&self, index: usize) -> &f64 {
|
|
&self.e[index]
|
|
}
|
|
}
|
|
|
|
impl IndexMut<usize> for Vec3 {
|
|
fn index_mut(&mut self, index: usize) -> &mut f64 {
|
|
&mut self.e[index]
|
|
}
|
|
}
|
|
|
|
impl Add for Vec3 {
|
|
type Output = Vec3;
|
|
|
|
fn add(self, other: Vec3) -> Vec3 {
|
|
Vec3 {
|
|
e: [self[0] + other[0], self[1] + other[1], self[2] + other[2]],
|
|
}
|
|
}
|
|
}
|
|
|
|
impl AddAssign for Vec3 {
|
|
fn add_assign(&mut self, other: Vec3) -> () {
|
|
*self = Vec3 {
|
|
e: [self[0] + other[0], self[1] + other[1], self[2] + other[2]],
|
|
};
|
|
}
|
|
}
|
|
|
|
impl Sub for Vec3 {
|
|
type Output = Vec3;
|
|
|
|
fn sub(self, other: Vec3) -> Vec3 {
|
|
Vec3 {
|
|
e: [self[0] - other[0], self[1] - other[1], self[2] - other[2]],
|
|
}
|
|
}
|
|
}
|
|
|
|
impl SubAssign for Vec3 {
|
|
fn sub_assign(&mut self, other: Vec3) -> () {
|
|
*self = Vec3 {
|
|
e: [self[0] - other[0], self[1] - other[1], self[2] - other[2]],
|
|
};
|
|
}
|
|
}
|
|
|
|
impl Mul<f64> for Vec3 {
|
|
type Output = Vec3;
|
|
|
|
fn mul(self, other: f64) -> Vec3 {
|
|
Vec3 {
|
|
e: [self[0] * other, self[1] * other, self[2] * other],
|
|
}
|
|
}
|
|
}
|
|
|
|
impl MulAssign<f64> for Vec3 {
|
|
fn mul_assign(&mut self, other: f64) -> () {
|
|
*self = Vec3 {
|
|
e: [self[0] * other, self[1] * other, self[2] * other],
|
|
};
|
|
}
|
|
}
|
|
|
|
impl Mul<Vec3> for f64 {
|
|
type Output = Vec3;
|
|
|
|
fn mul(self, other: Vec3) -> Vec3 {
|
|
Vec3 {
|
|
e: [self * other[0], self * other[1], self * other[2]],
|
|
}
|
|
}
|
|
}
|
|
|
|
impl Div<f64> for Vec3 {
|
|
type Output = Vec3;
|
|
|
|
fn div(self, other: f64) -> Vec3 {
|
|
Vec3 {
|
|
e: [self[0] / other, self[1] / other, self[2] / other],
|
|
}
|
|
}
|
|
}
|
|
|
|
impl DivAssign<f64> for Vec3 {
|
|
fn div_assign(&mut self, other: f64) -> () {
|
|
*self = Vec3 {
|
|
e: [self[0] / other, self[1] / other, self[2] / other],
|
|
};
|
|
}
|
|
}
|
|
impl Display for Vec3 {
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
write!(f, "({}, {}, {})", self[0], self[1], self[2])
|
|
}
|
|
}
|