ft: 10: metals

This commit is contained in:
2026-04-16 14:04:55 +02:00
parent e8f84b590b
commit b756cc394a
12 changed files with 199 additions and 41 deletions

View File

@@ -1,11 +1,11 @@
use core::f32::math::sqrt;
use is_close::default;
use rand::RngExt;
use std::{
fmt::Display,
ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign},
};
use rand::RngExt;
#[derive(Copy, Clone)]
pub struct Vec3 {
r: f32,
@@ -16,11 +16,11 @@ pub struct Vec3 {
pub type Colour = Vec3;
impl Vec3 {
pub fn new(r: f32, g: f32, b: f32) -> Vec3 {
pub fn new(r: f32, g: f32, b: f32) -> Self {
Self { r: r, g: g, b: b }
}
pub fn nil() -> Vec3 {
pub fn nil() -> Self {
Self {
r: 0.,
g: 0.,
@@ -28,26 +28,26 @@ impl Vec3 {
}
}
pub fn random() -> Vec3 {
pub fn random() -> Self {
let mut rng = rand::rng();
Vec3 {
Self {
r: rng.random_range(-1.0..1.),
g: rng.random_range(-1.0..1.),
b: rng.random_range(-1.0..1.),
}
}
pub fn random_unit() -> Vec3 {
pub fn random_unit() -> Self {
loop {
let v = Vec3::random();
let v = Self::random();
if v.length_squared() <= 1. {
return v / v.length();
}
}
}
pub fn random_unit_hemisphere(n: &Vec3) -> Vec3 {
let v = Vec3::random_unit();
pub fn random_unit_hemisphere(n: &Self) -> Self {
let v = Self::random_unit();
if n.dot(&v) > 0.0 {
v
} else {
@@ -75,12 +75,12 @@ impl Vec3 {
(self.r * self.r + self.g * self.g + self.b * self.b) as f32
}
pub fn dot(&self, other: &Vec3) -> f32 {
pub fn dot(&self, other: &Self) -> f32 {
self.r * other.r + self.g * other.g + self.b * other.b
}
pub fn cross(&self, other: &Vec3) -> Vec3 {
Vec3 {
pub fn cross(&self, other: &Self) -> Self {
Self {
r: self.g * other.b - self.b * other.g,
g: self.b * other.r - self.r * other.b,
b: self.r * other.g - self.g * other.r,
@@ -91,10 +91,20 @@ impl Vec3 {
self /= self.length();
}
pub fn get_unit(self) -> Vec3 {
pub fn get_unit(self) -> Self {
self / self.length()
}
pub fn near_zero(&self) -> bool {
default().is_close(self.r, 0.)
&& default().is_close(self.g, 0.)
&& default().is_close(self.b, 0.)
}
pub fn reflect(&self, o: &Vec3) -> Vec3 {
*self - 2. * self.dot(o) * o
}
pub fn output(self) -> image::Rgb<u8> {
// gamma correction
let r = if self.r > 0. {
@@ -120,8 +130,8 @@ impl Vec3 {
image::Rgb([ir, ig, ib])
}
pub fn clone(&self) -> Vec3 {
Vec3 {
pub fn clone(&self) -> Self {
Self {
r: self.r,
g: self.g,
b: self.b,
@@ -289,6 +299,18 @@ impl Mul<Vec3> for f32 {
}
}
impl Mul<&Vec3> for f32 {
type Output = Vec3;
fn mul(self, rhs: &Vec3) -> Self::Output {
Vec3 {
r: rhs.r * self,
g: rhs.g * self,
b: rhs.b * self,
}
}
}
impl MulAssign<Vec3> for Vec3 {
fn mul_assign(&mut self, rhs: Self) {
*self = Self {