Class: Ra::Shape::Base

Inherits:
Object
  • Object
show all
Defined in:
lib/ra/shape/base.rb

Overview

An abstract shape. Any concrete subclass of shape must implement the methods ‘l_normal` and `t_intersect`. Both methods use a point / ray with a local transform applied.

Direct Known Subclasses

Cube, Cylinder, Plane, Sphere

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(material:, transform: Transform::IDENTITY) ⇒ Base

Returns a new instance of Base.

Parameters:

  • material (Ra::Material)
  • transform (Ra::Matrix) (defaults to: Transform::IDENTITY)


15
16
17
18
# File 'lib/ra/shape/base.rb', line 15

def initialize(material:, transform: Transform::IDENTITY)
  @material = material
  @transform = transform
end

Instance Attribute Details

#materialRa::Material

Returns:



11
12
13
# File 'lib/ra/shape/base.rb', line 11

def material
  @material
end

Instance Method Details

#color(point:) ⇒ Color

Parameters:

  • point (Vector)

    <x, y, z, Tuple::POINT>

Returns:



37
38
39
# File 'lib/ra/shape/base.rb', line 37

def color(point:)
  @material.color(point: uv_point(point: @transform.inverse * point))
end

#intersect(ray:) ⇒ Array<Ra::Intersection>

Parameters:

Returns:



22
23
24
25
# File 'lib/ra/shape/base.rb', line 22

def intersect(ray:)
  t_intersect(ray: ray.transform(@transform.inverse))
    .map { |t| Ra::Intersection.new(ray:, shape: self, t:) }
end

#l_normal(point:) ⇒ Vector

Parameters:

  • point (Vector)

    local

Returns:

  • (Vector)

Raises:

  • (NotImplementedError)


55
56
57
# File 'lib/ra/shape/base.rb', line 55

def l_normal(point:)
  raise NotImplementedError, '#l_normal must be implemented by a concrete subclass'
end

#normal(point:) ⇒ Vector

Returns <x, y, z, Tuple::POINT>.

Parameters:

  • point (Vector)

    <x, y, z, Tuple::POINT>

Returns:

  • (Vector)

    <x, y, z, Tuple::POINT>



29
30
31
32
33
# File 'lib/ra/shape/base.rb', line 29

def normal(point:)
  normal = @transform.inverse.transpose * l_normal(point: @transform.inverse * point)

  Vector[normal[0], normal[1], normal[2], Ra::Tuple::VECTOR].normalize
end

#t_intersect(ray:) ⇒ Array<Intersection>

Parameters:

Returns:

Raises:

  • (NotImplementedError)


49
50
51
# File 'lib/ra/shape/base.rb', line 49

def t_intersect(ray:)
  raise NotImplementedError, '#t_intersect must be implemented by a concrete subclass'
end

#uv_point(point:) ⇒ Vector

Returns <u = 0.0..1.0, v = 0.0..1.0>.

Parameters:

  • point (Vector)

    <x, y, z, Tuple::POINT>

Returns:

  • (Vector)

    <u = 0.0..1.0, v = 0.0..1.0>

Raises:

  • (NotImplementedError)


43
44
45
# File 'lib/ra/shape/base.rb', line 43

def uv_point(point:)
  raise NotImplementedError, '#uv_point must be implemented by a concrete subclass'
end