aboutsummaryrefslogtreecommitdiff
path: root/src/core
diff options
context:
space:
mode:
Diffstat (limited to 'src/core')
-rw-r--r--src/core/bound.rs114
-rw-r--r--src/core/mod.rs11
-rw-r--r--src/core/ray.rs6
-rw-r--r--src/core/spectrum.rs35
-rw-r--r--src/core/vector2.rs110
-rw-r--r--src/core/vector3.rs47
6 files changed, 323 insertions, 0 deletions
diff --git a/src/core/bound.rs b/src/core/bound.rs
new file mode 100644
index 0000000..ea9d990
--- /dev/null
+++ b/src/core/bound.rs
@@ -0,0 +1,114 @@
+use crate::{Number, Float};
+use super::vector2::Vector2;
+use crate::core;
+
+#[derive(Clone)]
+pub struct Bound2<T: Number> {
+ pub min: Vector2<T>,
+ pub max: Vector2<T>
+}
+
+pub type Bound2i = Bound2<i32>;
+pub type Bound2f = Bound2<Float>;
+
+fn min<T: Number> (a: T, b: T) -> T {
+ if b < a {
+ return b;
+ }
+ a
+}
+
+fn max<T: Number> (a: T, b: T) -> T {
+ if b > a {
+ return b;
+ }
+ a
+}
+
+impl<T: Number> Bound2<T> {
+ pub fn new(p0: &Vector2<T>, p1: &Vector2<T>) -> Self {
+ let min = Vector2::new_xy(min(p0.x, p1.x), min(p0.y, p1.y));
+ let max = Vector2::new_xy(max(p0.x, p1.x), max(p0.y, p1.y));
+
+ Self { min, max }
+ }
+
+ pub fn new_xyxy(x1: T, y1: T, x2: T, y2: T) -> Self {
+ Self::new(
+ &Vector2::new_xy(x1, y1),
+ &Vector2::new_xy(x2, y2),
+ )
+ }
+
+ pub fn diagonal(&self) -> Vector2<T> {
+ self.max - self.min
+ }
+
+ pub fn area(&self) -> T {
+ let diag = self.diagonal();
+ return diag.x * diag.y;
+ }
+
+ pub fn width(&self) -> T {
+ self.diagonal().x
+ }
+}
+
+impl From<&Bound2i> for Bound2f {
+ fn from(b: &Bound2i) -> Self {
+ Self {
+ min: core::Vector2f::from(b.min),
+ max: core::Vector2f::from(b.max),
+ }
+ }
+}
+
+impl From<&Bound2f> for Bound2i {
+ fn from(b: &Bound2f) -> Self {
+ Self {
+ min: core::Vector2i::from(b.min),
+ max: core::Vector2i::from(b.max),
+ }
+ }
+}
+
+pub fn intersect<T: Number>(a: &Bound2<T>, b: &Bound2<T>) -> Bound2<T> {
+ Bound2::new(
+ &Vector2::new_xy(max(a.min.x, b.min.x), max(a.min.y, b.min.y)),
+ &Vector2::new_xy(min(a.max.x, b.max.x), min(a.max.y, b.max.y)),
+ )
+}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+
+ fn create_test() -> Bound2<i32> {
+ Bound2::new(
+ &Vector2::new_xy(1, 2),
+ &Vector2::new_xy(10, 3)
+ )
+ }
+
+ #[test]
+ fn area() {
+ let b = create_test();
+
+ assert!(b.area() == 9);
+ }
+
+ #[test]
+ fn intersect_test() {
+ let b1 = Bound2i::new_xyxy(10, 10, 20, 20);
+ let b2 = Bound2i::new_xyxy(2, 11, 22, 17);
+
+ let b = intersect(&b1, &b2);
+
+ assert!(
+ b.min.x == 10 &&
+ b.min.y == 11 &&
+ b.max.x == 20 &&
+ b.max.y == 17
+ )
+ }
+}
diff --git a/src/core/mod.rs b/src/core/mod.rs
new file mode 100644
index 0000000..938a16e
--- /dev/null
+++ b/src/core/mod.rs
@@ -0,0 +1,11 @@
+pub mod vector2;
+pub mod vector3;
+pub mod bound;
+pub mod spectrum;
+mod ray;
+
+pub use vector2::{Vector2i, Vector2f};
+pub use vector3::Vector3f;
+pub use bound::{Bound2i, Bound2f};
+pub use spectrum::Spectrum;
+pub use ray::Ray;
diff --git a/src/core/ray.rs b/src/core/ray.rs
new file mode 100644
index 0000000..7d73b93
--- /dev/null
+++ b/src/core/ray.rs
@@ -0,0 +1,6 @@
+use crate::core::Vector3f;
+
+pub struct Ray {
+ origin: Vector3f,
+ direction: Vector3f,
+}
diff --git a/src/core/spectrum.rs b/src/core/spectrum.rs
new file mode 100644
index 0000000..604c8c0
--- /dev/null
+++ b/src/core/spectrum.rs
@@ -0,0 +1,35 @@
+use crate::Float;
+use std::ops;
+
+// TODO implement SampledSpectrum instead for nicer images
+
+#[derive(Clone, Default)]
+pub struct Spectrum {
+ c: [Float; 3],
+}
+
+impl Spectrum {
+ fn new_rgb(r: Float, g: Float, b: Float) -> Spectrum {
+ Spectrum { c: [r, g, b] }
+ }
+}
+
+impl std::ops::Mul<Float> for &Spectrum {
+ type Output = Spectrum;
+
+ fn mul(self, op: Float) -> Self::Output {
+ Self::Output::new_rgb(
+ self.c[0] * op,
+ self.c[1] * op,
+ self.c[2] * op,
+ )
+ }
+}
+
+impl std::ops::AddAssign<&Self> for Spectrum {
+ fn add_assign(&mut self, op: &Self) {
+ self.c[0] += op.c[0];
+ self.c[1] += op.c[1];
+ self.c[2] += op.c[2];
+ }
+}
diff --git a/src/core/vector2.rs b/src/core/vector2.rs
new file mode 100644
index 0000000..ac70947
--- /dev/null
+++ b/src/core/vector2.rs
@@ -0,0 +1,110 @@
+use crate::{Float, Number};
+use std::ops::{Sub, Add};
+
+#[derive(Clone, Copy)]
+pub struct Vector2<T: Number> {
+ pub x: T,
+ pub y: T,
+}
+
+pub type Vector2f = Vector2<Float>;
+pub type Vector2i = Vector2<i32>;
+
+impl<T: Number> Vector2<T> {
+ pub fn new(initial: T) -> Vector2<T> {
+ Vector2 { x: initial, y: initial }
+ }
+
+ pub fn new_xy(x: T, y: T) -> Vector2<T> {
+ Vector2 { x, y }
+ }
+}
+
+impl<T: Number> Sub for Vector2<T> {
+ type Output = Self;
+ fn sub(self, op: Self) -> Self::Output {
+ Self::new_xy(
+ self.x - op.x,
+ self.y - op.y,
+ )
+ }
+}
+
+impl<T: Number> Add for Vector2<T> {
+ type Output = Self;
+ fn add(self, op: Self) -> Self::Output {
+ Self::new_xy(
+ self.x + op.x,
+ self.y + op.y,
+ )
+ }
+}
+
+impl Vector2f {
+ pub fn ceil(&self) -> Self {
+ Self::new_xy(
+ self.x.ceil(),
+ self.y.ceil()
+ )
+ }
+
+ pub fn floor(&self) -> Self {
+ Self::new_xy(
+ self.x.ceil(),
+ self.y.ceil()
+ )
+ }
+}
+
+impl From<Vector2i> for Vector2f {
+ fn from(v: Vector2i) -> Self {
+ Self {
+ x: v.x as Float,
+ y: v.y as Float,
+ }
+ }
+}
+
+impl From<Vector2f> for Vector2i {
+ fn from(v: Vector2f) -> Self {
+ Self {
+ x: v.x as i32,
+ y: v.y as i32,
+ }
+ }
+}
+
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+
+ #[test]
+ fn new_vec2() {
+ let v = Vector2::new_xy(2.0, 10.0);
+
+ assert!(v.x == 2.0 && v.y == 10.0);
+
+ let v = Vector2::new(3);
+
+ assert!(v.x == 3 && v.y == 3);
+ }
+
+ #[test]
+ fn sub_vec2() {
+ let v1 = Vector2::new_xy(10, 11);
+ let v2 = Vector2::new_xy(2, 3);
+
+ let v3 = v1-v2;
+ assert!(v3.x == 8 && v3.y == 8);
+ }
+
+ #[test]
+ fn add_vec2() {
+ let v1 = Vector2::new_xy(10, 11);
+ let v2 = Vector2::new_xy(2, 3);
+
+ let v3 = v1+v2;
+ assert!(v3.x == 12 && v3.y == 14);
+ }
+}
diff --git a/src/core/vector3.rs b/src/core/vector3.rs
new file mode 100644
index 0000000..da09ceb
--- /dev/null
+++ b/src/core/vector3.rs
@@ -0,0 +1,47 @@
+use crate::{Float, Number};
+use std::ops::{Sub, Add};
+
+#[derive(Clone, Copy)]
+pub struct Vector3<T: Number> {
+ pub x: T,
+ pub y: T,
+ pub z: T,
+}
+
+pub type Vector3f = Vector3<Float>;
+
+impl<T: Number> Vector3<T> {
+ pub fn new(initial: T) -> Vector3<T> {
+ Vector3 {
+ x: initial,
+ y: initial,
+ z: initial,
+ }
+ }
+
+ pub fn new_xy(x: T, y: T, z: T) -> Vector3<T> {
+ Vector3 { x, y, z}
+ }
+}
+
+impl<T: Number> Sub for Vector3<T> {
+ type Output = Self;
+ fn sub(self, op: Self) -> Self::Output {
+ Self::new_xy(
+ self.x - op.x,
+ self.y - op.y,
+ self.z - op.z,
+ )
+ }
+}
+
+impl<T: Number> Add for Vector3<T> {
+ type Output = Self;
+ fn add(self, op: Self) -> Self::Output {
+ Self::new_xy(
+ self.x + op.x,
+ self.y + op.y,
+ self.z + op.z,
+ )
+ }
+}