Compare commits
No commits in common. "bd899e3a2ef3f1e2ae995efb032900b875e81241" and "a2aa13288691961e5ebced4941997ffa2213a8da" have entirely different histories.
bd899e3a2e
...
a2aa132886
|
@ -49,5 +49,5 @@ fn main() {
|
||||||
let ppm = PPM::from(canvas);
|
let ppm = PPM::from(canvas);
|
||||||
|
|
||||||
let mut file = File::create("projectile.ppm").unwrap();
|
let mut file = File::create("projectile.ppm").unwrap();
|
||||||
let _ = file.write(ppm.as_bytes());
|
file.write(ppm.as_bytes()).unwrap();
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,8 @@ fn join_to_line_limit(data: impl IntoIterator<Item = String>) -> Vec<String> {
|
||||||
let mut lines = vec![];
|
let mut lines = vec![];
|
||||||
|
|
||||||
let mut line = String::new();
|
let mut line = String::new();
|
||||||
for element in data {
|
let mut iter = data.into_iter();
|
||||||
|
while let Some(element) = iter.next() {
|
||||||
if line.is_empty() {
|
if line.is_empty() {
|
||||||
line = line + &element;
|
line = line + &element;
|
||||||
} else if line.len() + 1 + element.len() < 70 {
|
} else if line.len() + 1 + element.len() < 70 {
|
||||||
|
|
|
@ -189,31 +189,4 @@ mod tests {
|
||||||
let p = Point::new(2., 3., 4.);
|
let p = Point::new(2., 3., 4.);
|
||||||
assert_eq!(transform * p, Point::new(2., 3., 7.));
|
assert_eq!(transform * p, Point::new(2., 3., 7.));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn individual_transformations_are_applied_in_sequence() {
|
|
||||||
let p = Point::new(1., 0., 1.);
|
|
||||||
let rotation = rotation_x(PI / 2.);
|
|
||||||
let scale = scaling(5., 5., 5.);
|
|
||||||
let translate = translation(10., 5., 7.);
|
|
||||||
|
|
||||||
let p2 = rotation * p;
|
|
||||||
assert_eq!(p2, Point::new(1., -1., 0.));
|
|
||||||
|
|
||||||
let p3 = scale * p2;
|
|
||||||
assert_eq!(p3, Point::new(5., -5., 0.));
|
|
||||||
|
|
||||||
let p4 = translate * p3;
|
|
||||||
assert_eq!(p4, Point::new(15., 0., 7.));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn chained_translations() {
|
|
||||||
let p = Point::new(1., 0., 1.);
|
|
||||||
let rotation = rotation_x(PI / 2.);
|
|
||||||
let scale = scaling(5., 5., 5.);
|
|
||||||
let translate = translation(10., 5., 7.);
|
|
||||||
let tr = translate * scale * rotation;
|
|
||||||
assert_eq!(tr * p, Point::new(15., 0., 7.));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,7 +29,7 @@ impl Canvas {
|
||||||
&self.pixels[self.addr(y, x)]
|
&self.pixels[self.addr(y, x)]
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn pixel_mut(&mut self, x: usize, y: usize) -> &mut Color {
|
pub fn pixel_mut<'a>(&'a mut self, x: usize, y: usize) -> &'a mut Color {
|
||||||
let addr = self.addr(y, x);
|
let addr = self.addr(y, x);
|
||||||
&mut self.pixels[addr]
|
&mut self.pixels[addr]
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,4 @@
|
||||||
use std::cmp::Ordering;
|
use crate::types::{eq_f64, Tuple, Point, Vector};
|
||||||
|
|
||||||
use crate::types::{eq_f64, Point, Tuple, Vector};
|
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct Matrix {
|
pub struct Matrix {
|
||||||
|
@ -29,7 +27,7 @@ impl Matrix {
|
||||||
self.values[self.addr(row, column)]
|
self.values[self.addr(row, column)]
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn cell_mut(&mut self, row: usize, column: usize) -> &mut f64 {
|
pub fn cell_mut<'a>(&'a mut self, row: usize, column: usize) -> &'a mut f64 {
|
||||||
let addr = self.addr(row, column);
|
let addr = self.addr(row, column);
|
||||||
&mut self.values[addr]
|
&mut self.values[addr]
|
||||||
}
|
}
|
||||||
|
@ -94,15 +92,19 @@ impl Matrix {
|
||||||
|
|
||||||
for r in 0..self.size {
|
for r in 0..self.size {
|
||||||
for c in 0..self.size {
|
for c in 0..self.size {
|
||||||
let dest_r = match r.cmp(&row) {
|
let dest_r = if r < row {
|
||||||
Ordering::Less => r,
|
r
|
||||||
Ordering::Greater => r - 1,
|
} else if r > row {
|
||||||
Ordering::Equal => continue,
|
r - 1
|
||||||
|
} else {
|
||||||
|
continue;
|
||||||
};
|
};
|
||||||
let dest_c = match c.cmp(&column) {
|
let dest_c = if c < column {
|
||||||
Ordering::Less => c,
|
c
|
||||||
Ordering::Greater => c - 1,
|
} else if c > column {
|
||||||
Ordering::Equal => continue,
|
c - 1
|
||||||
|
} else {
|
||||||
|
continue;
|
||||||
};
|
};
|
||||||
*m.cell_mut(dest_r, dest_c) = self.cell(r, c);
|
*m.cell_mut(dest_r, dest_c) = self.cell(r, c);
|
||||||
}
|
}
|
||||||
|
@ -196,8 +198,8 @@ impl std::ops::Mul<Tuple> for Matrix {
|
||||||
|
|
||||||
let mut t = [0.; 4];
|
let mut t = [0.; 4];
|
||||||
|
|
||||||
for (row, item) in t.iter_mut().enumerate() {
|
for row in 0..4 {
|
||||||
*item = self.cell(row, 0) * rside.0
|
t[row] = self.cell(row, 0) * rside.0
|
||||||
+ self.cell(row, 1) * rside.1
|
+ self.cell(row, 1) * rside.1
|
||||||
+ self.cell(row, 2) * rside.2
|
+ self.cell(row, 2) * rside.2
|
||||||
+ self.cell(row, 3) * rside.3;
|
+ self.cell(row, 3) * rside.3;
|
||||||
|
|
|
@ -6,7 +6,7 @@ pub struct Tuple(
|
||||||
pub f64, // y or green
|
pub f64, // y or green
|
||||||
pub f64, // z or blue
|
pub f64, // z or blue
|
||||||
pub f64, // w, the flag which
|
pub f64, // w, the flag which
|
||||||
// indicates point vs vec, or alpha
|
// indicates point vs vec, or alpha
|
||||||
);
|
);
|
||||||
|
|
||||||
impl Tuple {
|
impl Tuple {
|
||||||
|
@ -44,7 +44,12 @@ impl std::ops::Sub for Tuple {
|
||||||
impl std::ops::Neg for Tuple {
|
impl std::ops::Neg for Tuple {
|
||||||
type Output = Tuple;
|
type Output = Tuple;
|
||||||
fn neg(self) -> Self::Output {
|
fn neg(self) -> Self::Output {
|
||||||
Tuple(-self.0, -self.1, -self.2, -self.3)
|
return Self::Output {
|
||||||
|
0: -self.0,
|
||||||
|
1: -self.1,
|
||||||
|
2: -self.2,
|
||||||
|
3: -self.3,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue