Add rotate

master
max.nuding 2022-07-11 07:33:25 +02:00
parent f5f46a7a0b
commit c6b0fb59ae
Failed to extract signature
1 changed files with 86 additions and 0 deletions

86
src/rotate_y.rs Normal file
View File

@ -0,0 +1,86 @@
use crate::hittable::{HitRecord, Hittable};
use crate::{Aabb, Point3, Ray, Vec3};
pub struct RotateY<H: Hittable> {
hittable: H,
sin_theta: f64,
cos_theta: f64,
bounding_box: Option<Aabb>
}
impl<H: Hittable> RotateY<H> {
pub fn new(hittable: H, degrees: f64) -> Self {
let radians = degrees.to_radians();
let sin_theta = radians.sin();
let cos_theta = radians.cos();
let mut bounding_box = hittable.bounding_box(0.0, 1.0);
if let Some(bbox) = bounding_box {
let mut min = Point3::new(f64::INFINITY, f64::INFINITY, f64::INFINITY);
let mut max = Point3::new(f64::NEG_INFINITY, f64::NEG_INFINITY, f64::NEG_INFINITY);
for i in 0..2 {
for j in 0..2 {
for k in 0..2 {
let x = (i as f64)*bbox.maximum.x() + ((1 - i) as f64)*bbox.minimum.x();
let y = (i as f64)*bbox.maximum.y() + ((1 - j) as f64)*bbox.minimum.y();
let z = (i as f64)*bbox.maximum.z() + ((1 - k) as f64)*bbox.minimum.z();
let x = cos_theta * x + sin_theta * z;
let z = -sin_theta * x + cos_theta * z;
let tester = Vec3::new(x, y, z);
for c in 0..3 {
min[c] = min[c].min(tester[c]);
max[c] = max[c].max(tester[c]);
}
}
}
}
bounding_box = Some(Aabb {
minimum: min,
maximum: max
});
}
Self { hittable, sin_theta, cos_theta, bounding_box }
}
}
impl<H: Hittable> Hittable for RotateY<H> {
fn hit(&self, ray: &Ray, t_min: f64, t_max: f64) -> Option<HitRecord> {
let mut origin = ray.origin();
let mut direction = ray.direction();
origin[0] = self.cos_theta * ray.origin()[0] - self.sin_theta*ray.origin()[2];
origin[2] = self.sin_theta * ray.origin()[0] + self.cos_theta*ray.origin()[2];
direction[0] = self.cos_theta * ray.direction()[0] - self.sin_theta*ray.direction()[2];
direction[2] = self.sin_theta * ray.direction()[0] + self.cos_theta*ray.direction()[2];
let rotated = Ray::new(origin, direction, ray.time());
match self.hittable.hit(&rotated, t_min, t_max) {
Some(rec) => {
let mut p = rec.point;
let mut normal = rec.normal;
p[0] = self.cos_theta*rec.point[0] + self.sin_theta * rec.point[2];
p[2] = -self.sin_theta*rec.point[0] + self.cos_theta * rec.point[2];
normal[0] = self.cos_theta*rec.normal[0] + self.sin_theta * rec.normal[2];
normal[2] = -self.sin_theta*rec.normal[0] + self.cos_theta * rec.normal[2];
let mut new_rec = HitRecord {
point: p,
normal,
t: rec.t,
u: rec.u,
v: rec.v,
front_face: rec.front_face,
material: rec.material,
};
new_rec.normalized(&rotated);
Some(new_rec)
},
_ => None
}
}
fn bounding_box(&self, _time0: f64, _time1: f64) -> Option<Aabb> {
self.bounding_box
}
}