Shape

Trait Shape 

Source
pub trait Shape {
    // Required methods
    fn transform(&self) -> &Matrix;
    fn set_transform(&mut self, transform: Matrix);
    fn transform_inverse(&self) -> &Matrix;
    fn material(&self) -> &Material;
    fn set_material(&mut self, material: Material);
    fn local_intersect(&self, ray: &Ray) -> Vec<Intersection>;
    fn local_normal_at(&self, point: Tuple) -> Tuple;

    // Provided methods
    fn intersect(&self, ray: &Ray) -> Vec<Intersection> { ... }
    fn normal_at(&self, point: Tuple) -> Tuple { ... }
}
Expand description

Represents a 3D shape with all methods to be able to render it, as well as methods for transforming it, and giving it a material.

Shape::transform should return the shape’s transform. Shape::set_transform should set it’s transform. Shape::transform_inverse should return the shape’s transform’s inverse.

Shape::material should return the shape’s material. Shape::set_material should set it’s material.

Shape::local_intersect should return a list of all intersections ray makes with the implementation of Shape. The list should be sorted according to the distances (t value) of the intersections. Intersections behind ray should also be in the list, but with a negative distance. This means they are at the front of the list. The intersections should be in local space. This means they should be calculated as if the shape where not transformed. The calculations for the transformation happen in Shape::intersect, which should not be overwritten.

Shape::local_normal_at should return the surface normal of shape at point. The caller is responsible for making sure point is on the surface the shape. The resulting vector should be normalized. The normal should be in local space. This means they should be calculated as if the shape where not transformed. The calculations for the transformation happen in Shape::normal_at, which should not be overwritten.

Required Methods§

Source

fn transform(&self) -> &Matrix

Source

fn set_transform(&mut self, transform: Matrix)

Source

fn transform_inverse(&self) -> &Matrix

Source

fn material(&self) -> &Material

Source

fn set_material(&mut self, material: Material)

Source

fn local_intersect(&self, ray: &Ray) -> Vec<Intersection>

Source

fn local_normal_at(&self, point: Tuple) -> Tuple

Provided Methods§

Source

fn intersect(&self, ray: &Ray) -> Vec<Intersection>

Examples found in repository?
examples/sphere.rs (line 45)
14fn main() -> Result<(), Box<dyn std::error::Error>> {
15    let ray_origin = Tuple::point(0.0, 0.0, -5.0);
16    let wall_z = 10.0;
17    let wall_size = 7.0;
18
19    let canvas_pixels: usize = 100;
20    let pixel_size = wall_size / canvas_pixels as f64;
21    let half = wall_size / 2.0;
22
23    let mut canvas = Canvas::new(canvas_pixels, canvas_pixels);
24    let mut shape = Sphere::new();
25    shape.set_transform(
26        Matrix::shearing(1.0, 0.0, 0.0, 0.0, 0.0, 0.0) * &Matrix::scaling(0.5, 1.0, 1.0),
27    );
28    shape.set_material(Material {
29        texture: Rc::new(SolidColor::new(Color::new(1.0, 0.2, 1.0))),
30        ..Material::default()
31    });
32    let shape: Rc<dyn Shape> = Rc::new(shape);
33
34    let light = PointLight::new(Tuple::point(-10.0, 10.0, -10.0), Color::new(1.0, 1.0, 1.0));
35
36    for y in (0..canvas_pixels).rev() {
37        let world_y = half - pixel_size * y as f64;
38
39        for x in 0..canvas_pixels {
40            let world_x = pixel_size * x as f64 - half;
41
42            let position = Tuple::point(world_x, world_y, wall_z);
43
44            let ray = Ray::new(ray_origin, (position - ray_origin).normalized());
45            let intersections = shape.intersect(&ray);
46
47            if let Some(hit) = intersections.hit() {
48                let point = ray.at(hit.t());
49                let normal = hit.shape().normal_at(point);
50                let eye = -ray.direction();
51
52                let color = hit.shape().material().lighting(
53                    Rc::clone(&shape),
54                    &light,
55                    point,
56                    eye,
57                    normal,
58                    false,
59                );
60
61                canvas[[x, y]] = color;
62            }
63        }
64    }
65
66    canvas.to_ppm(&mut std::io::stdout())?;
67
68    Ok(())
69}
Source

fn normal_at(&self, point: Tuple) -> Tuple

Examples found in repository?
examples/sphere.rs (line 49)
14fn main() -> Result<(), Box<dyn std::error::Error>> {
15    let ray_origin = Tuple::point(0.0, 0.0, -5.0);
16    let wall_z = 10.0;
17    let wall_size = 7.0;
18
19    let canvas_pixels: usize = 100;
20    let pixel_size = wall_size / canvas_pixels as f64;
21    let half = wall_size / 2.0;
22
23    let mut canvas = Canvas::new(canvas_pixels, canvas_pixels);
24    let mut shape = Sphere::new();
25    shape.set_transform(
26        Matrix::shearing(1.0, 0.0, 0.0, 0.0, 0.0, 0.0) * &Matrix::scaling(0.5, 1.0, 1.0),
27    );
28    shape.set_material(Material {
29        texture: Rc::new(SolidColor::new(Color::new(1.0, 0.2, 1.0))),
30        ..Material::default()
31    });
32    let shape: Rc<dyn Shape> = Rc::new(shape);
33
34    let light = PointLight::new(Tuple::point(-10.0, 10.0, -10.0), Color::new(1.0, 1.0, 1.0));
35
36    for y in (0..canvas_pixels).rev() {
37        let world_y = half - pixel_size * y as f64;
38
39        for x in 0..canvas_pixels {
40            let world_x = pixel_size * x as f64 - half;
41
42            let position = Tuple::point(world_x, world_y, wall_z);
43
44            let ray = Ray::new(ray_origin, (position - ray_origin).normalized());
45            let intersections = shape.intersect(&ray);
46
47            if let Some(hit) = intersections.hit() {
48                let point = ray.at(hit.t());
49                let normal = hit.shape().normal_at(point);
50                let eye = -ray.direction();
51
52                let color = hit.shape().material().lighting(
53                    Rc::clone(&shape),
54                    &light,
55                    point,
56                    eye,
57                    normal,
58                    false,
59                );
60
61                canvas[[x, y]] = color;
62            }
63        }
64    }
65
66    canvas.to_ppm(&mut std::io::stdout())?;
67
68    Ok(())
69}

Implementors§