' '
def material(color)
{
  Materials.uniform( [ "ambient": color * 0.1,
                       "diffuse": color * 0.8,
                       "specular": Colors.white(),
                       "specular_exponent": 100,
                       "reflectivity": 0.5 ] )
}

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

  var bouncy_sphere_position = Animations.ease( Animations.animate( pos(0,5,0), pos(0,0,0), seconds(3) ), Easing.bounce(5, 5) )[now]
  var elastic_sphere_position = Animations.ease( Animations.animate( pos(0,5,0), pos(0,0,0), seconds(3) ), Easing.elastic(10, 5) )[now]

  var bouncy_sphere = translate(bouncy_sphere_position - pos(0, 0, 0), decorate(material(Colors.red()), sphere()))
  var bouncy_platform = translate(vec(0,-1,0), decorate(material(Colors.white()), crop_spherical(xz_plane(), 2)))
  var elastic_sphere = translate(elastic_sphere_position - pos(0, 0, 0), decorate(material(Colors.red()), sphere()))

  var root = union([
    translate(vec(-2, 0, 0), union([bouncy_sphere, bouncy_platform])),
    translate(vec(2, 0, 0), elastic_sphere)
  ])

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


  create_scene(camera, root, lights)
}

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

pipeline( scene_animation(scene_at, seconds(5)),
          [ Pipeline.animation(30),
            Pipeline.renderer(renderer),
            Pipeline.studio() ] )

1. Elastic

You’ll need to find the formula for bouncing yourself. Rely on a graphing software such as Desmos’s graphing calculator.

  • Start by making a graph of \(\cos(x)\).

    elastic
  • \(\cos(x)\) swings around \(0\) going back and forth between \(-1\) and \(1\). We need it to swing between \(0\) and \(2\) instead.

    elastic2
  • It starts at 2 and goes down to 0. We need it to start at 0 and go up to 2. Modify the formula so that we get

    elastic3
  • Try to increase the frequency. Add some number in the formule, e.g., \(F \cos(x)\) or \(\cos(F x)\) where \(F\) is some number representing the frequency.

    elastic4
  • Find a way to make the bumps become smaller as time passes by. You will need to divide the \(\cos\) by an expression that involves \(x\). Be careful that you divide by numbers greater than 1, otherwise your animation will swing outside the \([0, 2]\) interval.

    elastic5

1.1. Implementation

Create files math/functions/easing/elastic-easing-function.cpp/.h. Use linear-easing-function.h/.cpp as a guide.

Don’t forget to add a binding for the scripting language. In scripting/math-module, update the EasingLibrary structure and add an extra BIND to add_easing.

2. Bouncy

2.1. Formula

Here too you will need to find the mathematical formula that describes a bouncy animation.

Tip
  • Start off with \(\cos(x)\).

    bouncy1
  • The function goes below the X-axis. You’ll need to add something so that it remains positive.

    bouncy2
  • Once you have found the trick to make the \(\cos\) bounce, you can apply it to your elastic formula.

2.2. Implementation

Create files math/functions/easing/bounce-easing-function.cpp/.h. Use linear-easing-function.h/.cpp as a guide.

Don’t forget to add a binding for the scripting language.

3. Evaluation

Recreate the scene below: