' '

Difficulty

3

Prerequisites

patterns/transformations

Patterns are functions that associate a boolean value (typically interpreted as black and white) with every point.

bool pattern_function(const Point2D& point) // 2D
bool pattern_function(const Point3D& point) // 3D

We also know there exist operations on boolean values:

  • Conjunction b1 && b2.

  • Disjunction b1 || b2.

  • Negation !b.

In this extension, we find out what happens if we apply those logic operators on patterns.

Say we have two patterns p1 and p2.

p1 p2
hlines
vlines

If we combine them using disjunction, we get

combined

Notice how in the resulting image, a pixel is white if either one of the images above has a white pixel in the same spot.

1. Implementation

Create files patterns/pattern-logic-operations.cpp and patterns/pattern-logic-operations.h.

1.1. 2D

1.1.1. Conjunction

Write a function

Pattern2D conjunction(Pattern2D pattern1, Pattern2D pattern2)

It implements the following table:

1st pattern 2nd pattern result

Make use of make_pattern from lambda pattern extension.

1.1.2. Disjunction

Write a function

Pattern2D disjunction(Pattern2D pattern1, Pattern2D pattern2)

It implements the following table:

1st pattern 2nd pattern result

Make use of make_pattern from lambda pattern extension.

1.1.3. Exclusive Disjunction

Write a function

Pattern2D exclusive_disjunction(Pattern2D pattern1, Pattern2D pattern2)

It implements the following table:

1st pattern 2nd pattern result

Make use of make_pattern from lambda pattern extension.

1.1.4. Negation

Write a function

Pattern2D negation(Pattern2D pattern)

It implements the following table:

1st pattern result

Make use of make_pattern from lambda pattern extension.

1.2. 3D

Implement the same logical operations, but now on 3D patterns.

Pattern3D conjunction(Pattern3D pattern1, Pattern3D pattern2)
Pattern3D disjunction(Pattern3D pattern1, Pattern3D pattern2)
Pattern3D exclusive_disjunction(Pattern3D pattern1, Pattern3D pattern2)
Pattern3D negation(Pattern3D pattern)

Make use of make_pattern from lambda pattern extension.

2. Finishing Touches

Expose all these operations to the scripting language.

3. Evaluation

Render the following scene:

challenge
global white = Materials.uniform([ "ambient": Colors.white() ])
global black = Materials.uniform([ "ambient": Colors.black() ])

def material(pattern)
{
  Materials.from_pattern(pattern, white, black)
}

def scene_at(now)
{
  var camera = Cameras.perspective( [ "eye": pos(0, 0, 8),
                                      "look_at": pos(0,0,0) ] )

  var hlines = Patterns.lines(0.1, 0.1)
  var vlines = Patterns.rotate(degrees(90), hlines)

  var conjunction = Patterns.conjunction(hlines, vlines)
  var disjunction = Patterns.disjunction(hlines, vlines)
  var xdisjunction = Patterns.exclusive_disjunction(hlines, vlines)
  var negation = Patterns.negation(hlines)

  var root = union( [
  	decorate(
          material(conjunction),
          translate(vec(-1.5, 1.5, 0), sphere())),
  	decorate(
          material(disjunction),
          translate(vec(1.5, 1.5, 0), sphere())),
  	decorate(
          material(xdisjunction),
          translate(vec(-1.5, -1.5, 0), sphere())),
        decorate(
          material(negation),
          translate(vec(1.5, -1.5, 0), sphere()))
  ] )

  var lights = [ Lights.omnidirectional( pos(0,5,2), Colors.white() ) ]

  create_scene(camera, root, lights)
}


var raytracer   = Raytracers.v1()
var renderer    = Renderers.standard( [ "width": 500,
                                        "height": 500,
                                        "sampler": Samplers.single(),
                                        "ray_tracer": raytracer ] )

pipeline( scene_animation(scene_at, seconds(1)),
          [ Pipeline.animation(1),
            Pipeline.renderer(renderer),
            Pipeline.studio() ] )
  • Show that your implementations make use of the lambda pattern.