summaryrefslogtreecommitdiff
path: root/racer-tracer/src/vec3.rs
diff options
context:
space:
mode:
authorSakarias Johansson <sakarias.johansson@goodbyekansas.com>2023-01-06 22:59:27 +0100
committerSakarias Johansson <sakarias.johansson@goodbyekansas.com>2023-01-06 22:59:27 +0100
commit928b4191bf5a0d27da6d680ccaade7f94860359e (patch)
treeb2c1e301c1c5c7b5d8cb9a92cc9d4c925e54a7b9 /racer-tracer/src/vec3.rs
parent372bc5b09c50cf2440e8f7762dd260cefd7bba7f (diff)
downloadracer-tracer-928b4191bf5a0d27da6d680ccaade7f94860359e.tar.gz
racer-tracer-928b4191bf5a0d27da6d680ccaade7f94860359e.tar.xz
racer-tracer-928b4191bf5a0d27da6d680ccaade7f94860359e.zip
☁ Add sky
Diffstat (limited to 'racer-tracer/src/vec3.rs')
-rw-r--r--racer-tracer/src/vec3.rs204
1 files changed, 204 insertions, 0 deletions
diff --git a/racer-tracer/src/vec3.rs b/racer-tracer/src/vec3.rs
new file mode 100644
index 0000000..47df292
--- /dev/null
+++ b/racer-tracer/src/vec3.rs
@@ -0,0 +1,204 @@
+use std::{fmt, ops};
+
+#[derive(Default, Clone, Copy)]
+pub struct Vec3 {
+ data: [f64; 3],
+}
+
+impl Vec3 {
+ pub fn new(x: f64, y: f64, z: f64) -> Vec3 {
+ Vec3 { data: [x, y, z] }
+ }
+
+ pub fn x(&self) -> &f64 {
+ &self.data[0]
+ }
+
+ pub fn y(&self) -> &f64 {
+ &self.data[1]
+ }
+
+ pub fn z(&self) -> &f64 {
+ &self.data[2]
+ }
+
+ pub fn length(&self) -> f64 {
+ f64::sqrt(self.length_squared())
+ }
+
+ pub fn length_squared(&self) -> f64 {
+ self.data[0] * self.data[0] + self.data[1] * self.data[1] + self.data[2] * self.data[2]
+ }
+
+ pub fn dot(&self, v: &Vec3) -> f64 {
+ dot(self, v)
+ }
+
+ pub fn cross(&self, v: &Vec3) -> Vec3 {
+ cross(self, v)
+ }
+
+ pub fn unit_vector(&self) -> Vec3 {
+ unit_vector(self)
+ }
+
+ pub fn as_color(&self) -> u32 {
+ let red: u32 = (self.data[0] * 255.0) as u32;
+ let green: u32 = (self.data[1] * 255.0) as u32;
+ let blue: u32 = (self.data[2] * 255.0) as u32;
+ ((red as u32) << 16) | ((green as u32) << 8) | blue as u32
+ }
+}
+
+pub fn dot(v1: &Vec3, v2: &Vec3) -> f64 {
+ v1.data[0] * v2.data[0] + v1.data[1] * v2.data[1] + v1.data[2] * v2.data[2]
+}
+
+pub fn cross(v1: &Vec3, v2: &Vec3) -> Vec3 {
+ Vec3::new(
+ v1.data[1] * v2.data[2] - v1.data[2] * v2.data[1],
+ v1.data[2] * v2.data[0] - v1.data[0] * v2.data[2],
+ v1.data[0] * v2.data[1] - v1.data[1] * v2.data[0],
+ )
+}
+
+pub fn unit_vector(v: &Vec3) -> Vec3 {
+ v / v.length()
+}
+
+impl ops::Add<Vec3> for Vec3 {
+ type Output = Vec3;
+
+ fn add(self, rhs: Vec3) -> Self::Output {
+ Vec3::new(
+ self.data[0] + rhs.data[0],
+ self.data[1] + rhs.data[1],
+ self.data[2] + rhs.data[2],
+ )
+ }
+}
+
+impl ops::AddAssign<Vec3> for Vec3 {
+ fn add_assign(&mut self, rhs: Vec3) {
+ self.data[0] += rhs.data[0];
+ self.data[1] += rhs.data[1];
+ self.data[2] += rhs.data[2];
+ }
+}
+
+impl ops::Sub<Vec3> for Vec3 {
+ type Output = Vec3;
+
+ fn sub(self, rhs: Vec3) -> Self::Output {
+ Vec3::new(
+ rhs.data[0] - self.data[0],
+ rhs.data[1] - self.data[1],
+ rhs.data[2] - self.data[2],
+ )
+ }
+}
+
+impl ops::SubAssign for Vec3 {
+ fn sub_assign(&mut self, rhs: Self) {
+ self.data[0] -= rhs.data[0];
+ self.data[1] -= rhs.data[1];
+ self.data[2] -= rhs.data[2];
+ }
+}
+
+impl ops::Div<f64> for Vec3 {
+ type Output = Vec3;
+
+ fn div(self, rhs: f64) -> Self::Output {
+ (1.0 / rhs) * self
+ }
+}
+
+impl ops::Div<&Vec3> for f64 {
+ type Output = Vec3;
+
+ fn div(self, rhs: &Vec3) -> Self::Output {
+ (1.0 / self) * rhs
+ }
+}
+
+impl ops::Div<f64> for &Vec3 {
+ type Output = Vec3;
+
+ fn div(self, rhs: f64) -> Self::Output {
+ (1.0 / rhs) * self
+ }
+}
+
+impl ops::DivAssign<f64> for Vec3 {
+ fn div_assign(&mut self, rhs: f64) {
+ let t = 1.0 / rhs;
+ self.data[0] *= t;
+ self.data[1] *= t;
+ self.data[2] *= t;
+ }
+}
+
+impl ops::Mul<f64> for Vec3 {
+ type Output = Vec3;
+
+ fn mul(self, rhs: f64) -> Self::Output {
+ Vec3::new(self.data[0] * rhs, self.data[1] * rhs, self.data[2] * rhs)
+ }
+}
+
+impl ops::Mul<&Vec3> for f64 {
+ type Output = Vec3;
+
+ fn mul(self, rhs: &Vec3) -> Self::Output {
+ Vec3::new(rhs.data[0] * self, rhs.data[1] * self, rhs.data[2] * self)
+ }
+}
+
+impl ops::Mul<Vec3> for Vec3 {
+ type Output = Vec3;
+
+ fn mul(self, rhs: Vec3) -> Self::Output {
+ Vec3::new(
+ self.data[0] * rhs.data[0],
+ self.data[1] * rhs.data[1],
+ self.data[2] * rhs.data[2],
+ )
+ }
+}
+
+impl ops::Mul<Vec3> for f64 {
+ type Output = Vec3;
+
+ fn mul(self, rhs: Vec3) -> Self::Output {
+ rhs * self
+ }
+}
+
+impl ops::MulAssign<f64> for Vec3 {
+ fn mul_assign(&mut self, rhs: f64) {
+ self.data[0] *= rhs;
+ self.data[1] *= rhs;
+ self.data[2] *= rhs;
+ }
+}
+
+impl ops::Neg for Vec3 {
+ type Output = Vec3;
+
+ fn neg(self) -> Self::Output {
+ Vec3::new(-self.data[0], -self.data[1], -self.data[2])
+ }
+}
+
+impl fmt::Display for Vec3 {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ f.write_str(
+ format!(
+ "x: {}, y: {}, z: {}",
+ self.data[0], self.data[1], self.data[2]
+ )
+ .as_str(),
+ )
+ }
+}