Thoughts rearrange, familiar now strange.break flowersmore quotes
very clickable
music + math
WELCOME TO THE 5TH DIMENSION | This isn't meant to be understood — it's meant to be enjoyed.
Love music and science? Explore my collaboration with Max Cooper where we tell the story of infinities and animate the digits of π. Both tracks appear on Max's Yearning for the Infinite album.
Another collaboration with Max!

# Max Cooper's Ascent — Making of the Music video

## Enter the 5th dimension

Ascent answers the question: if you were living in a 5-dimensional room and projected digits of $\pi$ onto its walls, what would you see?

## 1 · building the animation from the ground up

The Ascent video was created using a custom animation system that I wrote for the video. It's about 5,400 lines of Perl.

Having my own solution to animating the 5-dimensional scene gave me complete control (that could be automated) over every frame. If I wanted to add something (e.g. at some point Max wanted to see gradients mapped onto cube surfaces), I could “just” add it.

Having my own solution also meant a lot more fiddling and debugging, as I was caught up in my own high-dimensional loop of fixing and breaking the code.

I'm also not an animator — I have no familiarity with animation tools. I'm only vaguely aware of After Effects.

## 2 · straightforward math — complex output

It was possible for me to code the animation system because the underlying math is relatively straightforward. The cubes are just a list of $n$-vectors that form their vertices and rotations are just matrix products applied to the vector.

The projection of the high-dimensional objects onto the 2-dimensional canvas was done in the simplest way possible — an orthographic projection, in which we keep the $x$ and $y$ components of a vector and throw out all others (no matter how many).

Adding more dimensions to the scene only requires that you add one more component to the vector and grow the rotation matrix by a row and column. It's as easy to animate a 3-dimensional scene as a 5-dimensional (or higher) scene.

A lot of the funky effects that you see in the video are achieved by the difference blend (logical NAND). The individual compoents (e.g. edges, faces) of the cubes are drawn one at a time and, because of the NAND blending, we never saturate the canvas.

## 3 · how the animation system works

The system works in a very simple way, even though its output can appear quite complicated (thanks difference blend!).

The entire animation is based on a set of $n$-dimensional cubes. For the final version of the video $n = 5$.

The scene is composed of one or more cubes. The cube is composed of (a) vertices (e.g. 32 vertices in 5-dimensional space) and (b) list of area maps to be projected onto one (or more) of its faces.

Cubes are also associated with parameters that determine how the cube is drawn. First, we define whether to draw the cube edges and/or faces. For example, at the start of the video the first cube has its edges drawn but not faces. Later, new cubes are added whose faces are drawn but not edges.

Second, each cube has a size parameter associated for each dimension. This allows me to shrink (or suppress) the cube along some dimensions. So, a 5-dimensional cube can be drawn as a square by setting the size of $z$, $w$ and $v$ dimensions to zero.

Third, a cubes edges (and faces) have themselves a parameter that determines how much of the edge (or face) to draw. This is independent of the cube's size along a given dimension. For example, I can choose to draw only 50% of the edge, which can be done by starting at the vertices (gap in the middle of the edge) or at the middle of the edge (gap at the vertices). For faces, this works the same way — a face can be drawn partially as a (growing or shrinking) square in the middle of a cube face or as four squares tucked up against the vertices.

This basic functionality is relatively easy to program. For each cube in the scene, you (a) iterate across its edges and faces, (b) determine their coordinates in 5-dimensional space by applying the scene's angles (both the camera and cube can rotate independently) as well as the size of the dimension, (c) determine how much of the element to draw based on the edge length (or the analogous parameter for faces) and then (b) draw it as a line (for edges) or filled polygon (faces) using the $(x,y)$ coordinates of the element (orthographic projection).

## 4 · defining the scene

Whereas the geometry is relatively straightfoward, by far the trickiest part of the system is how to define the scene and manage changes over time.

Some of the things that the system should know how to do (over time) is (a) zoom and rotate the camera (there are 10 independent axes of rotation in a 5-dimensional space), (b) add and remove cubes from the scene, (c) shrink and grow a cube, (d) shrink and grow edges and face fills, (e) add and remove area map projections to any set of faces of a cube and (f) shrink and grow area maps.

Finally, the system should be able to apply randomness to any of these parameters. This helps add variation to the animation. For example, I really don't want to have to define the angles of each keyframe manually — it's easier to initialize the angle and then apply a random drift to it over time.

### 4.1 · system parameters

To make the keyframe definitions more modular, I define various parameters that can be reused.

#### 4.1.1 · absolute vs relative

Parameters define either relative or absolute values. The difference between these is that relative values are used as scaling factors and absolute values are additive.

For example, if we define

$param = var1 r0.965$

and later use the command (see below for command syntax)

$cube c0 size [x] var1$

then the size of cube c0 along the $x$ dimension will be multiplied by 0.965.

However, if we define

$param = var1 d0.1$

then the size of the cube will be increased by 0.1. Here $d$ stands for “delta”.

#### 4.1.2 · randomly sampled

A great deal of what you see in the animation is randomly generated — in particular, the rotation angles. Nobody wants to manually manage the values of each of the 10 possible independent angles of rotation.

For example, the following parameter definition and command rotates the scene by angle $0.1 \times 2 \pi$.

$param = var1 d0.1 # values of angles are in units of 2π angle xy var1$

But if we define

$param = var1 d0.1,0.2$

then the value of the parameter will be sampled randomly (and uniformly) from the interval $[0.1,0.2]$ each time it's used.

#### 4.1.3 · normalized

Rotations can be defined about one or more planes of rotation. For example, we can rotate by a given angle about the $xy$ plane or about the $xy$ and $yz$ planes. The latter corresponds to composition of rotations achieved by mutiplying the rotation matrices.

However, given an angle of rotation, the scene will appear to rotate faster (there will be more motion) the more rotations we compose together. For this reason, parameter definitions (used only for angles) can include an $n$ to indicate that the value will be divided by the number of axes we're rotating around.

$param = var1 dn0.020,0.040 frame = 1.a ; ... ; cube c1 angle [x][yz] var1 frame = 1.a ; ... ; cube c1 angle [xy][yzw] var1$

will rotate cube c1 by a random value sampled from the interval [0.02,0.04], divided by the number of planes of rotation.

For frame 4.d, the planes of rotation are defined as $[x][yz]$, which corresponds rotations about $xy$ and $xz$ (we make all pairs of dimensions from the two sets of brackets). Thus, in this case we have two axes of rotation so we would divide $var1$ by 2.

In the next keyframe we rotate about $xy$, $xz$, $xw$, $yz$ and $yw$. We have 5 axes of rotation so we would divide $var1$ by 5.

#### 4.1.4 · macros

A parameter value can be used to store a set of commands. For example,

$param = rotxyz a [x][wv] var1 _ a [y][wv] var2$

rotates about $xw$ and $wv$ by an amount $var1$ and about $yw$ and $yv$ by an amount $var2$. This is convenient when you want to bundle up multiple rotations in a single definition.

$frame = 1.a ; ... ; rotxyz$

Here, $var1$ and $var1$ may be randomly sampled and normalized, as described above.

#### 4.1.5 · function macros

Parameters can also define a function, which helps shorten the syntax of keyframe definitions.

For example, the above could have been a function

$param = rotxyz(v1,v2) a [x][wv] v1 _ a [y][wv] v2$

which would be called

$frame = 1.a ; ... ; rotxyz(var1,var2)$

As another example, to add a cube with size 1 and edge length 0.5 to the scene, the syntax is

$cube c1 + cube c1 size . 1 cube c1 fade . 0.5$

This is pretty tedious. So we can define a function

$param = cube_add(cn,sv,fv) cube cn + _ cube cn size . sv _ cube cn fade . fv$

which will achieve the same thing if we call it as

$frame = 1.a ; ... ; cube_add(c1,1,0.5)$

These macros can be combined. The following will add the cube and rotate the scene. Notice how $var2$ defines an angle that is, on average, twice the size of $var1$. This lets us rotate about one set of axes slowly and around another set more quickly.

$param = var1 dn0.020,0.040 param = var2 dn0.040,0.080 frame = 1.a ; ... ; cube_add(c1,1,0.5) ; rotxyz(var1,var2)$

### 4.2 · system commands

Keyframes are defined by one or more commands.

$################################################################ # global zoom dimensions size . 1.2 # apply to all dimensions size [xy] 1.2 # apply only to x,y ################################################################ # scene angle (all angles in units of 2π) angle xy 0.1 # rotate about xy by 0.1 angle [x][yz] 0.1 # rotate about xy and xz planes by 0.1 angle . 0.1 # rotate about all planes by 0.1 ################################################################ # add a cube cube c1 + # add cube named c1 ################################################################ # cube angle angle c1 xy 0.1 # rotate cube c1 about xy by 0.1 angle c1 [x][yz] 0.1 # rotate cube c1 about xy and xz by 0.1 angle c1 . 0.1 # rotate cube c1 about all planes by 0.1 ################################################################ # cube size cube c1 size x 0.1 # set size of x dimension of cube c1 to 0.1 cube c1 size [xy] 0.1 # set size of x and y dimensions of cube c1 to 0.1 cube c1 size . 0.1 # set size of all dimensions of cube c1 to 0.1 ################################################################ # cube edge fade # analogous to cube size, but now we define how much of the edge to hide cube c1 fade x 0.1 cube c1 fade [xy] 0.1 cube c1 fade . 0.1 ################################################################ # add an area map to a cube face # map 22a is added to xy plane for z = 0 face c1 xy0 map 22a + # map 22a is added to all faces face c1 . map 22a + ################################################################ # fade and zoom an area map face c1 xy0 map 22a fade 0.5 face c1 xy0 map 22a zoom 0.5$

Most commands use a kind of regular expresion to narrow down their targets. For example,

$# apply to cube c1 plane xy angle c1 xy 0.1 # apply to cube c1,c2,c3 plane xy angle c[1-3] xy 0.1 # apply to cube c1,c2,c3 and any plane angle c[1-3] . 0.1 # apply to any cube and any plane angle . . 0.1$

Thus the last command would rotate all cubes on the scene about each plane by 0.1.

### 4.3 · building keyframes

Keyframes are composed of one or more commands and the number of frames over which the parameters changed by the commands are interpolated (see below).

For example, the keyframe

$frame = 1.a1 ; angle . 0$

will set all angles of the scene to 0.

### 4.4 · interpolating frames

Frames are interpolated between keyframes to smoothly vary parameter changes that the keyframes define. The argument to $n$ defines how many frames to interpolate between these two keyframes.

For example, in this pair of keyframes we first set all angles of the scene to zero. In the second keyframe we add 0.1 to the angle about the $xy$ plane and interpolate this change over $2fs$ frames.

$frame = 1.a1 ; angle . 0 frame = 1.a2 ; n 2fs ; angle xy d0.1$

By default, $fs = 24$, which is the number of frames per second. Thus, we have a 2 second rotation of 0.1 about the plane $xy$.

Here is a slightly more complex example

$frame = 1.a1 ; angle . 0 # 2 second rotation about xy by 0.1 frame = 1.a2 ; n 2fs ; angle xy d0.1 # 2 second rotation about xy by 0.2 (faster rotation) frame = 1.a3 ; n 2fs ; angle xy d0.2 # 2 second rotation about xy by 0.2 (faster rotation) and by yz by 0.1 frame = 1.a4 ; n 2fs ; angle xy d0.2 ; angle yz d0.1$

Keyframes can be repeated.

$frame = 1.a4 ; n 2fs ; angle xy d0.2 ; angle yz d0.1 frame = 1.a5 ; n 2fs ; angle xy d0.2 ; angle yz d0.1$

can be shortened to

$frame = 1.a4 ; n 2fs ; angle xy d0.2 ; angle yz d0.1; rep 2$

The purpose of the $rep$ command is to make the keyframe definitions more modular. For example, the above could have been written as

$frame = 1.a4 ; n 4fs ; angle xy d0.4 ; angle yz d0.2;$

where we interpolate over twice as many frames $4fs$ and rotate about angles that are twice as large. However, over time course of defining scenes I discovered that it was very helpful to keep changes defined in keyframes incremental.

## 5 · walkthrough the first few keyframes of ascent

If you've gotten this far, then you're in a good place to understand how each of the keyframes in the Ascent video is defined. Here, I walk you through some of the early keyframes.

Here, I've added the parameter definitions before the keyframe that uses them. Normally, they're stored in a separate file.

$# define a scene marker to which we can jump or stop at frame = 1: # add cube c0 param = fs 24 param = cube_add(cn,sv,fv) cube cn + _ cube cn size . sv _ cube cn fade . fv frame = 1.a; cube_add(c0,0,1) # arrange yw rotation for the split at 1.c* param = astepa2 d-0.048978 frame = 1.a0; a yw astepa2 # grow horizontal line frame = 1.a1; n 2fs; c c0 f [xy] 0 frame = 1.a2; n 2fs; c c0 s [x] 0.05 frame = 1.a3; n 2fs; c c0 s [x] 0.10 frame = 1.a4; n 2fs; c c0 s [x] 0.15 # grow y and rotate param = astepb3 d-0.041667 param = rxy3 a xy astepb3 frame = 1.a5; n 3fs; c c0 s [y] 0.05 ; rxy3 frame = 1.a6; n 3fs; c c0 s [y] 0.10 ; rxy3 frame = 1.a7; n 2fs; c c0 s [y] 0.15 ; rxy3 # grow z param = astepa6 d-0.016326 param = ryz6 a yz astepa6 frame = 1.b1; n 2fs; c c0 s [xy] 0.15 ; c c0 s [z] 0.100 ; c c0 f [z] 0.80 ; ryz6 frame = 1.b2; n 2fs; c c0 s [xy] 0.15 ; c c0 s [z] 0.110 ; c c0 f [z] 0.60 ; ryz6 frame = 1.b3; n 2fs; c c0 s [xy] 0.15 ; c c0 s [z] 0.120 ; c c0 f [z] 0.40 ; ryz6 frame = 1.b4; n 2fs; c c0 s [xy] 0.15 ; c c0 s [z] 0.130 ; c c0 f [z] 0.20 ; ryz6 frame = 1.b5; n 2fs; c c0 s [xy] 0.15 ; c c0 s [z] 0.140 ; c c0 f [z] 0.10 ; ryz6 frame = 1.b6; n 2fs; c c0 s [xy] 0.15 ; c c0 s [z] 0.150 ; c c0 f [z] 0.00 ; ryz6 # split cubes along w (needs yw angle set, see above) frame = 1.c1; n 1fs; c c0 s [xyz] 0.15 ; c c0 s [w] 0.815 # a pause frame = 1.c2; n 2fs;$

## 6 · ascent configuration files

Here are all the configuration files for the animation system. Each file has a hierarchy of blocks that define groups of parameters.

Typically, parameters in sub-blocks overwrite those in their parent blocks.

### 6.1 · global system configuration

This is the top-level configuration for the animation.

Configuration files are imported via the $include$ directive.

$# Debug groups, one or more # cube, eval, basis, angle, timer, step, schedule, size, map, key, param, progress, out, child, param, color, tween, render debug = cube,edge,basis,eval,timer,schedule,t,size,param,progress,out,param,tween scene_name = ascent-acropolis-1 #hdhalf = yes seed = 1 nproc = 100 haldnproc = 100 fps = 24 #wide = 3 lookup_tol = 0.001 lookup_make = yes cache_dir = /tmp/cube frame_dir = /tmp/cube hald_dir = ../hald map_dir = cache/maps clear_cache = no clear_frames = no aa = no # All angles in units of 2pi <angle> b = 0.125 # 0.78539816339 # pi/4 b2 = 0.0625 # 0.392699 # b/2 b4 = 0.03125 # 0.392699 # b/4 a = 0.097956 # 0.615479708670387 # Math::Trig::asin( Math::Trig::tan(pi/6) ) a2 = 0.048978 # 0.3077395 # a/2 a4 = 0.024489 # 0.3077395 # a/4 </angle> # Other useful angles param beta 0.125 param beta2 beta/2 param beta4 beta/4 param beta6 beta/6 param beta8 beta/8 param alpha 0.097956 param alpha2 alpha/2 param alpha4 alpha/4 param alpha6 alpha/6 param alpha8 alpha/8 param gamma 0.152043362 param gamma2 0.076021681 # angle bookmarks param refxy 135/360 # 147/360 #pi/180 ?135 param refxz 135/360 # 129/360 #pi/180 param refxw 270/360 # 259/360 #pi/180 param refxv 270/360 # 269/360 #pi/180 param refyz 180/360 # 192/360 # param refyw 180/360 # 210/360 #pi/180 param refyv 180/360 # 267/360 #pi/180 # elements to draw cube_edge = yes face_map = yes face_label = yes map_line = yes map_fill = yes z_tone = no z_tone_edge = no dim_color = yes xmult = 1 ymult = 1 ################################################################ # Break points # # 0 after scene init # 1 after keyframe # 2 after frame # 3 after memory size report # 4 after tween # ################################################################ # GLOBALS # Define dimensions ndim N # Inactive -COMMAND ... # -size 1 # -a 02 10 # Size dimensions size 1,1,1,1 # size . 1 # size 1 1 # size x 1 # size [12] 1 # size [xy] 1 # size [1-3] 1 # Global angle a 02 0.5 # a xz 0.5 # a [xy]z 0.5 # CUBES # # add a cube cube NAME + # # Cube angle a CUBE xz VALUE CUBE = RX (eg: . = all) # _ current # # Face f xy COMMAND all xy # f xy0 COMMAND xy z=0 # f xy1 COMMAND xy z=1 # f xy.1 COMMAND xy z=ANY w=1 # f xyz COMMAND all pairs from xyz # f xy1. COMMAND all xy z=1 w=ANY # f x COMMAND any with x # f x.1. COMMAND any with x z=1 # f x.10 COMMAND any with x z=1 w=0 (same as xy10) # f . COMMAND any face # Blends # diff creates dark intersections # add creates light intersections # lighten like add, but more subtle # multiply high contrast; needs white background, nice with opacity 0.5 # darken more subtle multiply # hue fun # # Some m/n Pi approximations # 19 6 3.166666666667 0.007981306249 improved # 22 7 3.142857142857 0.000402499435 improved # 179 57 3.140350877193 0.000395269704 improved # 201 64 3.140625000000 0.000308013704 improved # 223 71 3.140845070423 0.000237963113 improved # 245 78 3.141025641026 0.000180485705 improved # 267 85 3.141176470588 0.000132475164 improved # 289 92 3.141304347826 0.000091770575 improved # 311 99 3.141414141414 0.000056822190 improved # 333 106 3.141509433962 0.000026489630 improved # 355 113 3.141592920354 0.000000084914 improved # Layer # # cube:targetlayer:combine:opacity:color:ztone:thickness level = 3 # Variations of final video <<include acropolis/scene.ascent.conf>> # Scenes for testing <<include liverpool/scene.ascent.conf>> <<include scene.310.conf>> # 310 <<include scene.306.conf>> # 306 <<include scene.305.conf>> # 305 <<include scene.304.conf>> # 304 <<include scene.302.conf>> # 302 303 <<include scene.301.conf>> # 301 <<include scene.300.conf>> # 300 <<include scene.205.conf>> # 205 <<include scene.204.conf>> # 204 <<include scene.203.conf>> # 203 <<include scene.202.conf>> # 202 <<include scene.201.conf>> # 201 <<include scene.200.conf>> # 200 <<include scene.105.conf>> # 105 106 107 <<include scene.101.conf>> # 101 102 103 104 <<include scene.100.conf>> # 100 <<include scene.004.conf>> # 004 <<include scene.003.conf>> # 003 <<include scene.002.conf>> # 002 <<include scene.001.conf>> # 001 <<include scene.000.conf>> # 000 # Description of audio effects at specific frames # For debugging - they do not influence the animation. <schedule> 0 strt 1296 chng 1992 upmd 2184 bass 2592 dist 3840 chrd 5328 dyad 6672 peak 7392 outr 7800 dc 7944 fd 8568 end </scedule> # Times of musical accents in the video. # For debugging - they do not influence the animation. <accents> 0:16 * 0:28 * 0:34 * 0:43 * 1:07 * 1:13 * 1:22 * 1:30 * 1:36 * 1:57 * 1:59 * 2:06 * 2:16 * 2:22 * 2:27 * 2:47 * 2:56 * 3:14 * 3:23 * 3:34 * 3:52 * 4:03 * 4:10 * 4:16 * 4:22 * 4:32 * 5:26 * 5:28 * </accents> # Size of the rendered frame <canvas> width = 1920 height = 1080 scale = 0.5 </canvas> # Some colors <color> 0 = fg 1 = fg 2 = fg 3 = 255,0,0 4 = 0,255,0 5 = 0,0,255 6 = 255,0,255 7 = 0,255,255 8 = 255,255,0 bg = 0,0,0 lbg = 128,128,128 vlbg = 200,200,200 vvlbg = 225,225,225 fg = 255,255,255 orange = 251,176,59 blue = 41,171,226 dblue = 0,113,188 green = 140,198,63 dgreen = 0,146,69 red = 193,39,45 purple = 102,45,145 magenta= 237,30,121 eblue = 30,58,245 egreen = 127,249,107 epurple = 76,39,245 emagenta= magenta # If using 10 dims #d0 = 237,32,121 #d1 = 237,62,54 #d2 = 247,99,33 #d3 = 255,183,59 #d4 = 245,236,43 #d5 = 141,197,58 #d6 = 55,179,71 #d7 = 0,171,238 #d8 = 40,56,145 #d9 = 146,39,139 # If using 5 dims d0 = 237,32,121 #d1 = 237,62,54 d1 = 247,99,33 #d3 = 255,183,59 d2 = 245,236,43 #d5 = 141,197,58 d3 = 55,179,71 #d7 = 0,171,238 d4 = 40,56,145 #d9 = 146,39,139 #d2 = orange #d3 = red #d5 = blue #d9 = green </color> # For larger number of dimensions, PDL is faster # e.g. ndim=8, 1 frames per dim : PDL (8 sec), Math::Matrix (23 sec) use_pdl = no # Use precompiled rotation functions from rotate.pm (see bin/make_rotate_package) # For ndim > 8, PDL is faster use_fast_rot = no number = pi number_file = num/conf(number).5000.txt divide_ratio = 1$

### 6.2 · global parameters

Parameters and functions used in the keyframe definitions.

$# Not all these parameters are used - many are left over # from past versions. param = zremap -1 1 0 1 1 param = xmult 1; ymult 1 # Ways in which we shrink edges and faces. For example, edge fade # is set to 'shrinkcorners' meaning that when edges are drawn only # partially, there will a gap in the middle of the edge # shrinkmid | shrinkstart | shrinkend | shrinkcorners | hide | ignore param = mapedgefade shrinkmidrand param = mapfillfade shrinkmidrand param = edgefade shrinkcorners param = fillfade shrinkcorners param = facefillsort dimdesc # area | dim | faceidx # Randomly sampled angle rotation rates. # d - the value is an absolute amount to be added # n - the value is normalized by the number of axes we're rotating on # x,y - the value is sampled uniformly from [x,y] param = astep-vvslow dn0.001,0.002 param = astep-vslow dn0.002,0.005 param = astep-slow dn0.005,0.010 param = astep-med dn0.010,0.020 param = astep-fast dn0.020,0.040 param = astep-vfast dn0.040,0.060 param = astep-vvfast dn0.060,0.080 param = astep-vvvfast dn0.080,0.100 param = astep2-vvslow dn0.00125,0.0025 param = astep2-vslow dn0.00250,0.0060 param = astep2-slow dn0.00600,0.0125 param = astep2-med dn0.01250,0.0240 param = astep2-fast dn0.024,0.050 param = astep2-vfast dn0.050,0.070 param = astep2-vvfast dn0.070,0.090 param = astep2-vvvfast dn0.090,0.110 # Fixed values for rotation param = astepa d-alpha param = astepb d-beta param = astepa2 d-0.048978 param = astepb2 d-0.0625 param = astepa3 d-0.032652 param = astepb3 d-0.041667 param = astepa4 d-0.024489 param = astepb4 d-0.03125 param = astepa6 d-0.016326 # Various absolute (d) and relative (r) values used in sizing param = s3s d0.025 param = s3f d0.10 param = s4f d0.30 param = s4u d0.10 param = p1 r0.965 param = p2 d0.05 param = s5f d0.009 param = s5cf r0.96 param = s5cs r0.98 param = ps20 d0.05 param = ps21 d-0.025 # Specific plane rotations # e.g. rxy1 rotates in xy plane by amount astepb param = rxy1 a xy astepb param = ryz1 a yz astepa param = rxz1 a xz astepb param = rxy2 a xy astepb2 param = ryz2 a yz astepa2 param = rxz2 a xz astepa2 param = rxy3 a xy astepb3 param = ryz3 a yz astepa3 param = rxz3 a xz astepa3 param = rxy4 a xy astepb4 param = ryz4 a yz astepa4 param = rxz4 a xz astepa4 param = ryz6 a yz astepa6 # Function macros, _ acts as a delimiter between steps # # Adding, sizing, fading, rotating cubes param = cube_add(cn,sv,fv) cube cn + _ cube cn size . sv _ cube cn fade . fv param = map_add(cn,rx,mn) face cn rx map mn + _ face cn . map . fade 1 _ face cn . map . zoom 1 param = map_fade(cn,mn,fv) face cn . map mn fade fv param = cube_rot(cn,rx,av) cube cn a rx av param = cube_size(cn,sv) cube cn size . sv # Scene rotations # e.g. a [xy][wu] rotates about xw xu yw wu by astep-vvslow param = rotvvs a [xy][wu] astep-vvslow _ a [xy][vt] astep2-vvslow _ a xz astep-vvslow param = rotvs a [xy][wu] astep-vslow _ a [xy][vt] astep2-vslow _ a xz astep-vslow param = rots a [xy][wu] astep-slow _ a [xy][vt] astep2-slow _ a xz astep-slow param = rotm a [xy][wu] astep-med _ a [xy][vt] astep2-med _ a xz astep-med param = rotf a [xy][wu] astep-fast _ a [xy][vt] astep2-fast _ a xz astep-fast param = rotvf a [xy][wu] astep-vfast _ a [xy][vt] astep2-vfast _ a xz astep-vfast param = rotvvf a [xy][wu] astep-vvfast _ a [xy][vt] astep2-vvfast _ a xz astep-vvfast param = rotvvvf a [xy][wu] astep-vvvfast _ a [xy][vt] astep2-vvvfast _ a xz astep-vvvfast param = rotthis2 a [x][wu] astep-vslow _ a [y][zv] astep2-vslow _ ryz2 _ !rxz2 _ rxy2 param = rotthis3 a [x][wu] astep-fast _ a [y][zv] astep2-fast _ ryz2 _ rxy2 param = rot6vvvf a [x][wu] astep-vvfast _ a [y][zv] astep2-vvvfast param = rot6vvf a [x][wu] astep-vvfast _ a [y][zv] astep2-vvfast param = rot6vf a [x][wu] astep-vfast _ a [y][zv] astep2-vfast param = rot6f a [x][wu] astep-fast _ a [y][zv] astep2-fast param = rot6m a [x][wu] astep-med _ a [y][zv] astep2-med param = rot6s a [x][wu] astep-slow _ a [y][zv] astep2-slow param = rot6vs a [x][wu] astep-vslow _ a [y][zv] astep2-vslow param = rot6vvs a [x][wu] astep-vvslow _ a [y][zv] astep2-vvslow # rotate along each axis # here the . matches any plane of rotation param = rotallvvvf a . dn0.75-1.00 param = rotallvvf a . dn0.50-0.75 param = rotallvf a . dn0.25-0.50 param = rotallf a . dn0.125-0.25 param = rotallm a . astep-med param = rotalls a . astep-slow param = rotallvs a . astep-vslow param = rotallvvs a . astep-vvslow # some relative multipliers param = s2f r0.80 param = p3 r0.95 param = ps4 r1.01 param = ps5 0.95 param = ps6 0.950-0.990 param = ps7 0.925-0.950 param = ps8 0.900-0.925 param = ps9 0.875-0.900 param = ps10 0.850-0.875 param = ps11 0.825-0.850 param = ps12 0.800-0.825 param = ps13 0.850-0.900 param = ps14 0.900-0.950 param = ps15 0.950-0.975 param = p5 r0.95 param = q31 r0.85 param = q30 r0.75 param = q29 r0.65 param = q32 d0.125 param = q33 d0.025 param = q34 d0.05 param = q40 r0.70 param = q50 d0.0315$

### 6.3 · scene variations

Variety of scene definitions. Most of these vary based on the color of elements. Here, colors are defined with e.g. $color1$ and then these values are used in the $layer$ definitions. All of these have the text “acropolis” because the initial version of the video was prepared for Max's Live at the Acropolis show.

The final version of the video is $ascent-acropolis-11$.

$################################################################ # B/W and color final render <scene ascent-acropolis-11> # viridis param = name acropolis param = version 11 param = color0 fg # initial cube param = color1 fg # param = color2 fg # param = color3 fg # param = color4 fg # <<include scene.ascent.layers.v11.conf>> <<include acropolis/scene.ascent.main.v11.conf>> </scene> <scene ascent-acropolis-11v> # viridis param = name acropolis param = version 11v param = color0 map_plasma_rev # initial cube param = color1 map_viridis_rev # param = color2 map_viridis_rev # param = color3 map_viridis_rev # param = color4 map_viridis_rev # <<include scene.ascent.layers.v11.conf>> <<include acropolis/scene.ascent.main.v11.conf>> </scene> <scene ascent-acropolis-11p> # plasma param = name acropolis param = version 11p param = color0 map_viridis_rev # initial cube param = color1 map_plasma_rev # param = color2 map_plasma_rev # param = color3 map_plasma_rev # param = color4 map_plasma_rev # <<include scene.ascent.layers.v11.conf>> <<include acropolis/scene.ascent.main.v11.conf>> </scene> <scene ascent-acropolis-11pdebug> # plasma debug with annotation param = name acropolis param = version 11pdebug param = color0 map_viridis_rev # initial cube param = color1 map_plasma_rev # param = color2 map_plasma_rev # param = color3 map_plasma_rev # param = color4 map_plasma_rev # <<include scene.ascent.layers.v11.conf>> <<include acropolis/scene.ascent.main.v11.debug.conf>> </scene> # ################################################################ # Other prototype scenes <scene ascent-acropolis-1> param = name acropolis param = version 1 param = color1 fg param = color2 fg param = color3 fg param = color4 fg <<include acropolis/scene.ascent.main.conf>> </scene> <scene ascent-acropolis-2> param = name acropolis param = version 2 param = color1 eblue # eblue param = color2 egreen # egreen param = color3 epurple # epurple param = color4 emagenta # emagenta <<include acropolis/scene.ascent.main.conf>> </scene> <scene ascent-acropolis-3> param = name acropolis param = version 3 param = color1 blue # eblue param = color2 green # egreen param = color3 dblue # epurple param = color4 dgreen # emagenta <<include acropolis/scene.ascent.main.conf>> </scene> <scene ascent-acropolis-4> param = name acropolis param = version 4 param = color1 eblue # eblue param = color2 egreen # egreen param = color3 eblue # epurple param = color4 egreen # emagenta <<include acropolis/scene.ascent.main.conf>> </scene> # scene 6 is faster below # 4th maps level c in scene 6 and 7 <scene ascent-acropolis-5> param = name acropolis param = version 5 param = color1 eblue # eblue param = color2 egreen # egreen param = color3 epurple # epurple param = color4 emagenta # emagenta <<include acropolis/scene.ascent.main.conf>> </scene> <scene ascent-acropolis-6> param = name acropolis param = version 6 param = color1 egreen # eblue param = color2 fg # egreen param = color3 eblue # epurple param = color4 emagenta # emagenta <<include acropolis/scene.ascent.main.conf>> </scene> <scene ascent-acropolis-7> param = name acropolis param = version 7 param = color1 eblue # eblue param = color2 fg # egreen param = color3 fg # epurple param = color4 egreen # emagenta <<include acropolis/scene.ascent.main.conf>> </scene> <scene ascent-acropolis-8> param = name acropolis param = version 8 param = color1 egreen # eblue param = color2 fg # egreen param = color3 fg # epurple param = color4 emagenta # emagenta <<include acropolis/scene.ascent.main.conf>> </scene> <scene ascent-acropolis-9> param = name acropolis param = version 9 param = color1 fg # eblue param = color2 fg # egreen param = color3 fg # epurple param = color4 fg # emagenta <<include acropolis/scene.ascent.main.conf>> </scene> # This version used at the concert. <scene ascent-acropolis-10> param = name acropolis param = version 10 param = color1 fg # eblue param = color2 fg # egreen param = color3 fg # epurple param = color4 fg # emagenta <<include scene.ascent.layers.v10.conf>> <<include acropolis/scene.ascent.main.v10.conf>> </scene> <scene ascent-acropolis-11va> param = name acropolis param = version 11va param = color1 map_viridis_rev # param = color2 map_viridis_rev # param = color3 map_viridis_rev # param = color4 map_viridis_rev # <<include scene.ascent.layers.v11.conf>> <<include acropolis/scene.ascent.main.v11.conf>> </scene> <scene ascent-acropolis-11vb> param = name acropolis param = version 11vb param = area_fraction_max 0.02 param = area_transition 0.5 param = color1 map_viridis_rev # param = color2 map_viridis_rev # param = color3 map_viridis_rev # param = color4 map_viridis_rev # <<include scene.ascent.layers.v11.conf>> <<include acropolis/scene.ascent.main.v11.conf>> </scene> # old v26 <scene ascent-acropolis-11vc> param = name acropolis param = version 11vc param = color1 map_viridis_rev # param = color2 map_viridis_rev # param = color3 map_viridis_rev # param = color4 map_viridis_rev # param = polycolor1 fg # param = polycolor2 fg # param = polycolor3 fg # param = polycolor4 fg # param = area_fraction_max 0.01 param = area_transition 0.75 param = zremap_local -1 1 0 1 1 <<include scene.ascent.layers.v11.conf>> <<include acropolis/scene.ascent.main.v11.conf>> </scene> # old v28 <scene ascent-acropolis-11vd> param = name acropolis param = version 11vd param = color1 map_viridis_rev # param = color2 map_viridis_rev # param = color3 map_viridis_rev # param = color4 map_viridis_rev # param = polycolor1 fg # param = polycolor2 fg # param = polycolor3 fg # param = polycolor4 fg # param = area_fraction_max 0.02 param = area_transition 0.5 param = zremap_local -1 1 0 1 1 <<include scene.ascent.layers.v28.conf>> <<include acropolis/scene.ascent.main.v11.conf>> </scene> <scene ascent-acropolis-11ma> param = name acropolis param = version 11ma param = color1 map_magma_rev # param = color2 map_magma_rev # param = color3 map_magma_rev # param = color4 map_magma_rev # <<include scene.ascent.layers.v11.conf>> <<include acropolis/scene.ascent.main.v11.conf>> </scene> <scene ascent-acropolis-11mb> param = name acropolis param = version 11mb param = area_fraction_max 0.02 param = area_transition 0.5 param = color1 map_magma_rev # param = color2 map_magma_rev # param = color3 map_magma_rev # param = color4 map_magma_rev # <<include scene.ascent.layers.v11.conf>> <<include acropolis/scene.ascent.main.v11.conf>> </scene> # old v26 <scene ascent-acropolis-11mc> param = name acropolis param = version 11mc param = color1 map_magma_rev # param = color2 map_magma_rev # param = color3 map_magma_rev # param = color4 map_magma_rev # param = polycolor1 fg # param = polycolor2 fg # param = polycolor3 fg # param = polycolor4 fg # param = area_fraction_max 0.01 param = area_transition 0.75 param = zremap_local -1 1 0 1 1 <<include scene.ascent.layers.v11.conf>> <<include acropolis/scene.ascent.main.v11.conf>> </scene> # old v28 <scene ascent-acropolis-11md> param = name acropolis param = version 11md param = color1 map_magma_rev # param = color2 map_magma_rev # param = color3 map_magma_rev # param = color4 map_magma_rev # param = polycolor1 fg # param = polycolor2 fg # param = polycolor3 fg # param = polycolor4 fg # param = area_fraction_max 0.02 param = area_transition 0.5 param = zremap_local -1 1 0 1 1 <<include scene.ascent.layers.v28.conf>> <<include acropolis/scene.ascent.main.v11.conf>> </scene> <scene ascent-acropolis-11vma> param = name acropolis param = version 11vma param = colorm map_magma_rev # param = colorv map_viridis_rev # <<include scene.ascent.layers.v11vm.conf>> <<include acropolis/scene.ascent.main.v11.conf>> </scene> <scene ascent-acropolis-11vmb> param = name acropolis param = version 11vmb param = area_fraction_max 0.02 param = area_transition 0.5 param = colorm map_magma_rev # param = colorv map_viridis_rev # <<include scene.ascent.layers.v11vm.conf>> <<include acropolis/scene.ascent.main.v11.conf>> </scene> # old v26 <scene ascent-acropolis-11vmc> param = name acropolis param = version 11vmc param = colorm map_magma_rev # param = colorv map_viridis_rev # param = area_fraction_max 0.01 param = area_transition 0.75 param = zremap_local -1 1 0 1 1 <<include scene.ascent.layers.v11.conf>> <<include acropolis/scene.ascent.main.v11.conf>> </scene> # old v28 <scene ascent-acropolis-11vmd> param = name acropolis param = version 11vmd param = colorm map_magma_rev # param = colorv map_viridis_rev # param = area_fraction_max 0.02 param = area_transition 0.5 param = zremap_local -1 1 0 1 1 <<include scene.ascent.layers.v28vm.conf>> <<include acropolis/scene.ascent.main.v11.conf>> </scene> ################################################################ ################################################################ ################################################################ <scene ascent-acropolis-12> param = name acropolis param = version 12 param = color1 map_magma # param = color2 map_magma # param = color3 map_magma # param = color4 map_magma # <<include scene.ascent.layers.v11.conf>> <<include acropolis/scene.ascent.main.v11.conf>> </scene> <scene ascent-acropolis-13> param = name acropolis param = version 13 param = color1 map_inferno # param = color2 map_inferno # param = color3 map_inferno # param = color4 map_inferno # <<include scene.ascent.layers.v11.conf>> <<include acropolis/scene.ascent.main.v11.conf>> </scene> <scene ascent-acropolis-14> param = name acropolis param = version 14 param = color1 map_viridis # param = color2 map_viridis # param = color3 map_viridis # param = color4 map_viridis # <<include scene.ascent.layers.v14.conf>> <<include acropolis/scene.ascent.main.v11.conf>> </scene> <scene ascent-acropolis-14b> param = name acropolis param = version 14b param = hald hald1 param = color1 map_viridis # param = color2 map_viridis # param = color3 map_viridis # param = color4 map_viridis # <<include scene.ascent.layers.v14.conf>> <<include acropolis/scene.ascent.main.v11.conf>> </scene> <scene ascent-acropolis-15> param = name acropolis param = version 15 param = color1 map_viridis # param = color2 map_viridis_rev # param = color3 map_viridis # param = color4 map_viridis_rev # <<include scene.ascent.layers.v14.conf>> <<include acropolis/scene.ascent.main.v11.conf>> </scene> <scene ascent-acropolis-16> param = name acropolis param = version 16 param = color1 map_viridis_rev # param = color2 map_viridis # param = color3 map_viridis_rev # param = color4 map_viridis # <<include scene.ascent.layers.v14.conf>> <<include acropolis/scene.ascent.main.v11.conf>> </scene> <scene ascent-acropolis-16b> param = name acropolis param = version 16b param = hald hald1 param = color1 map_viridis_rev # param = color2 map_viridis # param = color3 map_viridis_rev # param = color4 map_viridis # <<include scene.ascent.layers.v14.conf>> <<include acropolis/scene.ascent.main.v11.conf>> </scene> <scene ascent-acropolis-17> param = name acropolis param = version 17 param = color1 map_viridis # param = color2 map_viridis # param = color3 map_viridis_rev # param = color4 map_viridis_rev # <<include scene.ascent.layers.v14.conf>> <<include acropolis/scene.ascent.main.v11.conf>> </scene> <scene ascent-acropolis-17b> param = name acropolis param = version 17b param = hald hald1 param = color1 map_viridis # param = color2 map_viridis # param = color3 map_viridis_rev # param = color4 map_viridis_rev # <<include scene.ascent.layers.v14.conf>> <<include acropolis/scene.ascent.main.v11.conf>> </scene> <scene ascent-acropolis-17c> param = name acropolis param = version 17c param = hald hald1 param = color1 map_viridis # param = color2 map_viridis # param = color3 map_viridis_rev # param = color4 map_viridis_rev # param = area_fraction_max 0.05 param = area_transition 0.5 <<include scene.ascent.layers.v14.conf>> <<include acropolis/scene.ascent.main.v11.conf>> </scene> <scene ascent-acropolis-17d> param = name acropolis param = version 17d param = hald hald1 param = color1 map_viridis # param = color2 map_viridis # param = color3 map_viridis_rev # param = color4 map_viridis_rev # param = area_fraction_max 0.04 param = area_transition 0.5 <<include scene.ascent.layers.v14.conf>> <<include acropolis/scene.ascent.main.v11.conf>> </scene> <scene ascent-acropolis-17e> param = name acropolis param = version 17e param = hald hald1 param = color1 map_viridis # param = color2 map_viridis # param = color3 map_viridis_rev # param = color4 map_viridis_rev # param = area_fraction_max 0.03 param = area_transition 0.5 <<include scene.ascent.layers.v14.conf>> <<include acropolis/scene.ascent.main.v11.conf>> </scene> <scene ascent-acropolis-17f> param = name acropolis param = version 17f param = hald hald1 param = color1 map_viridis # param = color2 map_viridis # param = color3 map_viridis_rev # param = color4 map_viridis_rev # param = area_fraction_max 0.02 param = area_transition 0.5 <<include scene.ascent.layers.v14.conf>> <<include acropolis/scene.ascent.main.v11.conf>> </scene> <scene ascent-acropolis-17g> param = name acropolis param = version 17g param = hald hald1 param = color1 map_viridis # param = color2 map_viridis # param = color3 map_viridis_rev # param = color4 map_viridis_rev # param = area_fraction_max 0.01 param = area_transition 0.5 <<include scene.ascent.layers.v14.conf>> <<include acropolis/scene.ascent.main.v11.conf>> </scene> <scene ascent-acropolis-18> param = name acropolis param = version 18 param = color1 map_viridis # param = color2 map_viridis # param = color3 map_viridis_rev # param = color4 map_viridis_rev # param = polycolor1 fg # param = polycolor2 fg # param = polycolor3 fg # param = polycolor4 fg # <<include scene.ascent.layers.v18.conf>> <<include acropolis/scene.ascent.main.v11.conf>> </scene> <scene ascent-acropolis-19> param = name acropolis param = version 19 param = color1 map_viridis # param = color2 map_viridis # param = color3 map_viridis_rev # param = color4 map_viridis_rev # param = polycolor1 fg # param = polycolor2 fg # param = polycolor3 fg # param = polycolor4 fg # <<include scene.ascent.layers.v19.conf>> <<include acropolis/scene.ascent.main.v11.conf>> </scene> <scene ascent-acropolis-20> param = name acropolis param = version 20 param = color1 map_viridis # param = color2 map_viridis # param = color3 map_viridis_rev # param = color4 map_viridis_rev # param = polycolor1 fg # param = polycolor2 fg # param = polycolor3 fg # param = polycolor4 fg # <<include scene.ascent.layers.v20.conf>> <<include acropolis/scene.ascent.main.v11.conf>> </scene> <scene ascent-acropolis-21> param = name acropolis param = version 21 param = color1 map_viridis # param = color2 map_viridis # param = color3 map_viridis_rev # param = color4 map_viridis_rev # param = polycolor1 fg # param = polycolor2 fg # param = polycolor3 fg # param = polycolor4 fg # <<include scene.ascent.layers.v21.conf>> <<include acropolis/scene.ascent.main.v11.conf>> </scene> <scene ascent-acropolis-22> param = name acropolis param = version 22 param = color1 map_viridis_rev # param = color2 map_viridis_rev # param = color3 map_viridis_rev # param = color4 map_viridis_rev # param = polycolor1 fg # param = polycolor2 fg # param = polycolor3 fg # param = polycolor4 fg # param = area_fraction_max 0.005 param = area_transition 0.5 param = zremap_local -1 1 0 1 1 <<include scene.ascent.layers.v22.conf>> <<include acropolis/scene.ascent.main.v11.conf>> </scene> <scene ascent-acropolis-22b> param = name acropolis param = version 22b param = hald hald1 param = color1 map_viridis_rev # param = color2 map_viridis_rev # param = color3 map_viridis_rev # param = color4 map_viridis_rev # param = polycolor1 fg # param = polycolor2 fg # param = polycolor3 fg # param = polycolor4 fg # param = area_fraction_max 0.005 param = area_transition 0.5 param = zremap_local -1 1 0 1 1 <<include scene.ascent.layers.v22.conf>> <<include acropolis/scene.ascent.main.v11.conf>> </scene> <scene ascent-acropolis-23> param = name acropolis param = version 23 param = color1 map_viridis_rev # param = color2 map_viridis_rev # param = color3 map_viridis_rev # param = color4 map_viridis_rev # param = polycolor1 fg # param = polycolor2 fg # param = polycolor3 fg # param = polycolor4 fg # param = area_fraction_max 0.004 param = area_transition 0.5 param = zremap_local -1 1 0 1 1 <<include scene.ascent.layers.v22.conf>> <<include acropolis/scene.ascent.main.v11.conf>> </scene> <scene ascent-acropolis-24> param = name acropolis param = version 24 param = color1 map_viridis_rev # param = color2 map_viridis_rev # param = color3 map_viridis_rev # param = color4 map_viridis_rev # param = polycolor1 fg # param = polycolor2 fg # param = polycolor3 fg # param = polycolor4 fg # param = area_fraction_max 0.003 param = area_transition 0.35 param = zremap_local -1 1 0 1 1 <<include scene.ascent.layers.v22.conf>> <<include acropolis/scene.ascent.main.v11.conf>> </scene> <scene ascent-acropolis-24b> param = name acropolis param = version 24b param = hald hald1 param = color1 map_viridis_rev # param = color2 map_viridis_rev # param = color3 map_viridis_rev # param = color4 map_viridis_rev # param = polycolor1 fg # param = polycolor2 fg # param = polycolor3 fg # param = polycolor4 fg # param = area_fraction_max 0.003 param = area_transition 0.35 param = zremap_local -1 1 0 1 1 <<include scene.ascent.layers.v22.conf>> <<include acropolis/scene.ascent.main.v11.conf>> </scene> <scene ascent-acropolis-25> param = name acropolis param = version 25 param = color1 map_viridis_rev # param = color2 map_viridis_rev # param = color3 map_viridis_rev # param = color4 map_viridis_rev # param = polycolor1 fg # param = polycolor2 fg # param = polycolor3 fg # param = polycolor4 fg # param = area_fraction_max 0.0025 param = area_transition 0.2 param = zremap_local -1 1 0 1 1 <<include scene.ascent.layers.v22.conf>> <<include acropolis/scene.ascent.main.v11.conf>> </scene> <scene ascent-acropolis-26b> param = name acropolis param = version 26b param = hald hald1 param = color1 map_viridis_rev # param = color2 map_viridis_rev # param = color3 map_viridis_rev # param = color4 map_viridis_rev # param = polycolor1 fg # param = polycolor2 fg # param = polycolor3 fg # param = polycolor4 fg # param = area_fraction_max 0.002 param = area_transition 0.5 param = zremap_local -1 1 0 1 1 <<include scene.ascent.layers.v22.conf>> <<include acropolis/scene.ascent.main.v11.conf>> </scene> <scene ascent-acropolis-27> param = name acropolis param = version 27 param = color1 map_viridis_rev # param = color2 map_viridis_rev # param = color3 map_viridis_rev # param = color4 map_viridis_rev # param = polycolor1 fg # param = polycolor2 fg # param = polycolor3 fg # param = polycolor4 fg # param = area_fraction_max 0.002 param = area_transition 0.5 param = zremap_local -1 1 0 1 1 <<include scene.ascent.layers.v27.conf>> <<include acropolis/scene.ascent.main.v11.conf>> </scene> <scene ascent-acropolis-28b> param = name acropolis param = version 28b param = hald hald1 param = color1 map_viridis_rev # param = color2 map_viridis_rev # param = color3 map_viridis_rev # param = color4 map_viridis_rev # param = polycolor1 fg # param = polycolor2 fg # param = polycolor3 fg # param = polycolor4 fg # param = area_fraction_max 0.002 param = area_transition 0.5 param = zremap_local -1 1 0 1 1 <<include scene.ascent.layers.v28.conf>> <<include acropolis/scene.ascent.main.v11.conf>> </scene> <scene ascent-acropolis-29> param = name acropolis param = version 29 param = color1 map_viridis_rev # param = color2 map_viridis_rev # param = color3 map_viridis_rev # param = color4 map_viridis_rev # param = polycolor1 fg # param = polycolor2 fg # param = polycolor3 fg # param = polycolor4 fg # param = area_fraction_max 0.002 param = area_transition 0.5 param = zremap_local -1 1 0 1 1 <<include scene.ascent.layers.v29.conf>> <<include acropolis/scene.ascent.main.v11.conf>> </scene>$

### 6.4 · scene parameters

Parameters specific to the final version.

$# Include annotations about scene on frame and/or file param = annot 0 param = annotcube 0 param = annotmap 0 param = annotframe 0 param = annotfile 0 # Number of child frame renderers to spawn param = nproc3 144 param = nproc4 144 param = nproc5 50 # careful here, this may need to be as low as 20 param = nproc6 10 param = ndim 5 # param = fs 24 # set to FPS to make fs = 1 second param = seed 1 param = tween 0.85 # final 0.85 <<include scene.ascent.mapcube.conf>> <<include scene.ascent.param.conf>> <<include scene.ascent.keyframes.conf>> # This is a funky feature in which we do not rotate about # the canonical axes but a random orthonormal basis. Because # we're not rotating about features of the cube, the projection # appears more uniformly complex (but actually less interesting!). # dimensions at this or larger index are random #param = randombasis 0$

### 6.5 · object layers

The layers define the order in which elements are drawn, which parts of the cube to draw (e.g. edges), what blend to use (mostly difference), which color to use and line thickness.

$# Blend modes are one of # normal | multiply | add | subtract | diff | lighten | darken | hue | sat | value | color layer = c0:cubeline:normal:1:color0:no:2 layer = c1:cubeline:diff:1:color1:no:5 layer = c2:cubeline:diff:1:color2:no:5 layer = c3:cubeline:diff:1:color3:no:5 layer = c4:cubeline:diff:1:color4:no:5 layer = c1:mapline:diff:1:color1:no:2 layer = c2:mapline:diff:1:color2:no:2 layer = c3:mapline:diff:1:color3:no:2 layer = c4:mapline:diff:1:color4:no:2 layer = c5:cubeface:diff:1:color1:no:1 layer = c6:cubeface:diff:1:color2:no:1 layer = c7:cubeface:diff:1:color3:no:1 layer = c8:cubeface:diff:1:color4:no:1 layer = cg:mapfill:diff:1:color1:no:1 layer = ce:mapfill:diff:1:color2:no:1 layer = cf:mapfill:diff:1:color3:no:1 layer = ch:mapfill:diff:1:color4:no:1 layer = ca:mapfill:diff:1:color1:no:1 layer = cb:mapfill:diff:1:color2:no:1 layer = cc:mapfill:diff:1:color3:no:1 layer = cd:mapfill:diff:1:color4:no:1$

### 6.6 · cubes and area maps

Cubes and area maps to initialize. Cubes are called by name (e.g. c0, ca) in the keyframe definitions.

$# Various approximations of pi map = 10a 10/3 50000 2 map = 10b 10/3 50000 3 map = 10c 10/3 50000 4 map = 10d 10/3 50000 5 map = 10e 10/3 50000 6 map = 22a 22/7 50000 2 map = 22b 22/7 50000 3 map = 22c 22/7 50000 4 map = 22d 22/7 50000 5 map = 22e 22/7 50000 6 map = 179a 179/57 50000 2 map = 179b 179/57 50000 3 map = 179c 179/57 50000 4 map = 179d 179/57 50000 5 map = 179e 179/57 50000 6 map = 179f 179/57 150000 7 map = 245a 245/78 50000 2 map = 245b 245/78 50000 3 map = 245c 245/78 50000 4 map = 245d 245/78 50000 5 map = 245e 245/78 50000 6 map = 245f 245/78 150000 7 map = 355a 355/113 50000 2 map = 355b 355/113 50000 3 map = 355c 355/113 50000 4 map = 355d 355/113 50000 5 map = 355e 355/113 50000 6 map = pia pi 50000 2 map = pib pi 50000 3 map = pic pi 50000 4 map = pid pi 50000 5 map = pie pi 50000 6 # Cube names cube = c0 cube = c1 cube = c2 cube = c3 cube = c4 cube = c5 cube = c6 cube = c7 cube = c8 cube = ca cube = cb cube = cc cube = cd cube = ce cube = cf cube = cg cube = ch$

### 6.7 · keyframes

Keyframes for the final version of the video.

$frame = init ; a . 0 ; size . 1; fade . 1 ################################################################ # SCENE 1 - cube c0 grows to max dimensions and c0 twinkles from corners frame = 1: frame = 1.a; cube_add(c0,0,1) # arrange yw rotation for the split at 1.c* frame = 1.a0; a yw astepa2 # grow horizontal line frame = 1.a1; n 2fs; c c0 f [xy] 0 frame = 1.a2; n 2fs; c c0 s [x] 0.05 ; frame = 1.a3; n 2fs; c c0 s [x] 0.10 ; frame = 1.a4; n 2fs; c c0 s [x] 0.15 ; # grow y and rotate frame = 1.a5; n 3fs; c c0 s [y] 0.05 ; rxy3 frame = 1.a6; n 3fs; c c0 s [y] 0.10 ; rxy3 frame = 1.a7; n 2fs; c c0 s [y] 0.15 ; rxy3 # grow z frame = 1.b1; n 2fs; c c0 s [xy] 0.15 ; c c0 s [z] 0.100 ; c c0 f [z] 0.80 ; ryz6 frame = 1.b2; n 2fs; c c0 s [xy] 0.15 ; c c0 s [z] 0.110 ; c c0 f [z] 0.60 ; ryz6 frame = 1.b3; n 2fs; c c0 s [xy] 0.15 ; c c0 s [z] 0.120 ; c c0 f [z] 0.40 ; ryz6 frame = 1.b4; n 2fs; c c0 s [xy] 0.15 ; c c0 s [z] 0.130 ; c c0 f [z] 0.20 ; ryz6 frame = 1.b5; n 2fs; c c0 s [xy] 0.15 ; c c0 s [z] 0.140 ; c c0 f [z] 0.10 ; ryz6 frame = 1.b6; n 2fs; c c0 s [xy] 0.15 ; c c0 s [z] 0.150 ; c c0 f [z] 0.00 ; ryz6 # split cubes along w (needs yw angle set, see above) frame = 1.c1; n 1fs; c c0 s [xyz] 0.15 ; c c0 s [w] 0.815 frame = 1.c2; n 2fs; # grow w and start to rotate xy/yz/rot* frame = 1.d1; n 2fs; c c0 s [xyz] 0.15 ; c c0 s [w] 0.715 ; c c0 f [w] 0.9 ; rots; !ryz2; rxy2; a xw astepb4 frame = 1.d2; n 2fs; c c0 s [xyz] 0.15 ; c c0 s [w] 0.615 ; c c0 f [w] 0.8 ; rots; !ryz2; rxy2; a xw astepb4 frame = 1.d3; n 2fs; c c0 s [xyz] 0.15 ; c c0 s [w] 0.515 ; c c0 f [w] 0.7 ; rots; !ryz2; rxy2; a xw astepb4 frame = 1.d4; n 2fs; ; c c0 s [w] 0.415 ; c c0 f [w] 0.6 ; rots; !ryz2; rxy2; a xw astepb4 frame = 1.d5; n 2fs; ; c c0 s [w] 0.315 ; c c0 f [w] 0.4 ; rots; !ryz2; rxy2; a xw astepb4 frame = 1.d6; n 2fs; ; c c0 s [w] 0.215 ; c c0 f [w] 0.2 ; rots; !ryz2; rxy2; a xw astepb4 frame = 1.d7; n 2fs; ; c c0 s [w] 0.150 ; c c0 f [w] 0.0 ; rots; !ryz2; rxy2; a xw astepb4 # grow v frame = 1.e1; n 2fs; ; c c0 s [v] 0.150 ; rots; ryz2; rxy2 frame = 1.e2; n 2fs; c c0 s [xyzwv] 0.150 ; ; c c0 f [v] 1.00 ; rots; ryz2; rxy2 frame = 1.e3; n 2fs; c c0 s [xyzwv] 0.175 ; ; c c0 f [v] 1.00 ; rots; ryz2; rxy2 frame = 1.e3; n 1fs; c c0 s [xyzwv] 0.175 ; ; c c0 f [v] 1.05 ; rots; ryz2; rxy2 frame = 1.e4; n 2fs; c c0 s [xyzwv] 0.200 ; ; c c0 f [v] 1.00 ; rots; ryz2; rxy2 frame = 1.e5; n 2fs; c c0 s [xyzwv] 0.225 ; ; c c0 f [v] 1.00 ; rots; ryz2; rxy2 ; size . 1.30 frame = 1.e6; n 2fs; c c0 s [xyzwv] 0.250 ; ; c c0 f [v] 0.80 ; rots; ryz2; rxy2 frame = 1.e7; n 2fs; c c0 s [xyzwv] 0.275 ; ; c c0 f [v] 0.70 ; rots; ryz2; rxy2 frame = 1.e8; n 2fs; c c0 s [xyzwv] 0.300 ; ; c c0 f [v] 0.50 ; rots; ryz2; rxy2 frame = 1.e9; n 2fs; c c0 s [xyzwv] 0.325 ; ; c c0 f [v] 0.40 ; rots; ryz2; rxy2 frame = 1.f1; n 2fs; ; c c0 f [v] 0.30 ; rots; ryz2; rxy2 frame = 1.f2; n 2fs; c c0 f [v] 0.20 ; rots; ryz2; rxy2 frame = 1.f3; n 2fs; c c0 f [v] 0.10 ; rots; ryz2; rxy2 frame = 1.f4; n 2fs; c c0 f [v] 0.00 ; rots; ryz2; rxy2 ################################################################ # xy, xz, xw, *** dimensions grow along edges of new cubes frame = 2: frame = 2.a; cube c1 copyfrom c0 . 1 frame = 2.a; cube c2 copyfrom c0 . 1 frame = 2.a; cube c3 copyfrom c0 . 1 frame = 2.a; cube c4 copyfrom c0 . 1 frame = 2.a; n 2fs; c c1 f [xy] s2f ; rotthis2; frame = 2.b; n 2fs; c c1 f [xy] s2f ; rotthis2; frame = 2.c; n 2fs; c c1 f [xy] s2f ; rotthis2; frame = 2.d; n 2fs; c c1 f [xy] s2f ; rotthis2; frame = 2.e; n 2fs; c c1 f [xy] s2f ; rotthis2; frame = 2.f; n 2fs; c c1 f [xy] s2f ; c c2 f [xz] s2f ; rotthis2; frame = 2.g; n 2fs; c c1 f [xy] s2f ; c c2 f [xz] s2f ; rotthis2; frame = 2.h; n 2fs; c c1 f [xy] s2f ; c c2 f [xz] s2f ; rotthis2; frame = 2.i; n 2fs; c c1 f [xy] s2f ; c c2 f [xz] s2f ; c c3 f [xw] s2f ; rotthis2; frame = 2.j; n 2fs; c c1 f [xy] s2f ; c c2 f [xz] s2f ; c c3 f [xw] s2f ; rotthis2; frame = 2.k; n 2fs; c c1 f [xy] s2f ; c c2 f [xz] s2f ; c c3 f [xw] s2f ; rotthis2; frame = 2.l; n 2fs; c c1 f [xy] s2f ; c c2 f [xz] s2f ; c c3 f [xw] s2f ; rotthis2; frame = 2.m; n 2fs; c c1 f [xy] s2f ; c c2 f [xz] s2f ; c c3 f [xw] s2f ; c c4 f [xv] s2f; rotthis2; frame = 2.n; n 2fs; c c1 f [xy] s2f ; c c2 f [xz] s2f ; c c3 f [xw] s2f ; c c4 f [xv] s2f; rotthis2; frame = 2.o; n 2fs; c c1 f [xy] s2f ; c c2 f [xz] s2f ; c c3 f [xw] s2f ; c c4 f [xv] s2f; rotthis2; frame = 2.p; n 2fs; c c1 f [xy] s2f ; c c2 f [xz] s2f ; c c3 f [xw] s2f ; c c4 f [xv] s2f; rotthis2; frame = 2.q; n 2fs; c c1 f [xy] s2f ; c c2 f [xz] s2f ; c c3 f [xw] s2f ; c c4 f [xv] s2f; rotthis2; frame = 2.r; n 2fs; c c1 f [xy] 0 ; c c2 f [xz] 0 ; c c3 f [xw] 0 ; c c4 f [xv] 0 ; rotthis2; ################################################################ # each cube from (2) expands, splitting up the dimension pairs frame = 3: frame = 3.a; n 2fs; c c1 s . s3s; rotthis2 frame = 3.b; n 2fs; c c1 s . s3s; rotthis2 frame = 3.c; n 2fs; c c1 s . s3s; c c2 s . s3s; rotthis2 frame = 3.d; n 2fs; c c1 s . s3s; c c2 s . s3s; rotthis2 frame = 3.e; n 2fs; c c1 s . s3s; c c2 s . s3s; c c3 s . s3s; c c0 f . s3f ; rotthis2 frame = 3.f; n 2fs; c c1 s . s3s; c c2 s . s3s; c c3 s . s3s; c c0 f . s3f ; rotthis2 frame = 3.g; n 2fs; c c[1-4] s . s3s; c c0 f . s3f ; rotthis2 frame = 3.h; n 2fs; c c[1-4] s . s3s; c c0 f . s3f ; rotthis2 frame = 3.i; n 2fs; c c[1-4] s . s3s; c c0 f . s3f ; rotthis2 ; rep 2 frame = 3.j; n 2fs; c c0 f . s3f ; rotthis2 ; rep 2 frame = 3.k; n 2fs; ; rotthis2 ; rep 2 ################################################################ # # maps fade in one at a time as original cube c0 shrinks to corners frame = 4: frame = 4.a; map_add(c1,xyzwv,22a) frame = 4.a; map_add(c2,xyzwv,22b) frame = 4.a; map_add(c3,xyzwv,22b) frame = 4.a; map_add(c4,xyzwv,22b) frame = 4.a; n 2fs; map_fade(c1,.,p1) ; c c1 f [xy] s4f ; c c[0-1] s . p2 ; size . s4u ; rotthis3; c c0 f . 0.90; frame = 4.b; n 2fs; map_fade(c1,.,p1) ; c c1 f [xy] s4f ; c c[0-1] s . p2 ; size . s4u ; rotthis3; frame = 4.c; n 2fs; map_fade(c1,.,p1) ; c c1 f [xy] s4f ; c c[0-1] s . p2 ; size . s4u ; rotthis3; frame = 4.d; n 2fs; map_fade(c2,.,p1) ; c c2 f [xz] s4f ; c c[0-2] s . p2 ; size . s4u ; rotthis3; cube c[1] a [xy][yzwvu] astep-fast frame = 4.e; n 2fs; map_fade(c2,.,p1) ; c c2 f [xz] s4f ; c c[0-2] s . p2 ; size . s4u ; rotthis3; cube c[1-2] a [xy][yzwvu] astep-fast frame = 4.f; n 2fs; map_fade(c2,.,p1) ; c c2 f [xz] s4f ; c c[0-2] s . p2 ; size . s4u ; rotthis3; cube c[1-2] a [xy][yzwvu] astep-fast frame = 4.g; n 2fs; map_fade(c3,.,p1) ; c c3 f [xw] s4f ; c c[0-3] s . p2 ; size . s4u ; rotthis3; cube c[1-2] a [xy][yzwvu] astep-fast frame = 4.h; n 2fs; map_fade(c3,.,p1) ; c c3 f [xw] s4f ; c c[0-3] s . p2 ; size . s4u ; rotthis3; cube c[1-3] a [xy][yzwvu] astep-fast frame = 4.i; n 2fs; map_fade(c4,.,p1) ; c c3 f [xw] s4f ; c c[0-3] s . p2 ; size . s4u ; rotthis3; cube c[1-3] a [xy][yzwvu] astep-fast frame = 4.j; n 2fs; map_fade(c[1-4],.,p1); c c4 f [xv] s4f ; size . s4u ; rotthis3; cube c[1-3] a [xy][yzwvu] astep-fast frame = 4.k; n 2fs; map_fade(c[1-4],.,p1); c c4 f [xv] s4f ; size . s4u ; rotthis3; cube c[1-4] a [xy][yzwvu] astep-fast frame = 4.l; n 2fs; map_fade(c[1-4],.,p1); c c4 f [xv] s4f ; size . s4u ; rotthis3; cube c[1-4] a [xy][yzwvu] astep-fast frame = 4.m; n 2fs; map_fade(c[1-4],.,p1); size . s4u ; rotthis3; cube c[1-4] a [xy][yzwvu] astep-fast # cube fills from corners and cubes start to independently rotate # fade out map edges c1-4 frame = 5: frame = 5.a; cube c5 copyfrom c1 . 1 frame = 5.a; cube c6 copyfrom c2 . 1 frame = 5.a; cube c7 copyfrom c3 . 1 frame = 5.a; cube c8 copyfrom c4 . 1 frame = 5.a; cube c[5-8] f . 1 frame = 5.a; face c[5-8] . map . - frame = 5.a; n 2fs; c c[5-5] f . s5cf; map_fade(c[1-4],.,s5f) ; rotthis3 ; c c[1-4] a [xy][yzwvu] astep-vfast frame = 5.b; n 2fs; c c[5-5] f . s5cf; map_fade(c[1-4],.,s5f) ; rotthis3 ; c c[1-4] a [xy][yzwvu] astep-vfast frame = 5.c; n 2fs; c c[5-6] f . s5cf; map_fade(c[1-4],.,s5f) ; rotthis3 ; c c[1-5] a [xy][yzwvu] astep-vfast ; rep 5 frame = 5.d; n 2fs; c c[5-7] f . s5cf; map_fade(c[1-4],.,s5f) ; rotthis3 ; c c[1-6] a [xy][yzwvu] astep-vfast ; rep 9 frame = 5.e; n 2fs; c c[5-8] f . s5cf; map_fade(c[1-4],.,s5f) ; rotthis3 ; c c[1-7] a [xy][yzwvu] astep-vfast ; rep 4 frame = 5.f; n 2fs; c c[5-8] f . s5cs; rotthis3 ; c c[1-8] a [xy][yzwvu] astep-vfast ; rep 5 frame = 5.g; n 2fs; c c[5-8] f . s5cs; rotthis3 ; c c[1-8] a [xy][yzwvu] astep-vfast ; rep 6 ################################################################ # dyads (28) # # Map fills grow frame = 6: frame = 6.a; cube ca copyfrom c1 . 1 frame = 6.a; cube cb copyfrom c2 . 1 frame = 6.a; cube cc copyfrom c3 . 1 frame = 6.a; cube cd copyfrom c4 . 1 frame = 5.a; cube c[a-d] f . 1 frame = 6.a; map_add(ca,xyzwv,179a) frame = 6.a; map_add(cb,xyzwv,179b) frame = 6.a; map_add(cc,xyzwv,179b) frame = 6.a; map_add(cd,xyzwv,179c) frame = 6.b; n 14fs; a xy refxy; a xz refxz; a xw refxw; a xv refxv ; a yz refyz; a yw refyw; a yv refyv; c c[0-9a-d] a . 0 ; map_fade(c[a-d],.,ps6) frame = 6.c; n 2fs; rot6vvs; a xw d0.01 ; f . . map . fade ps15 ; cube c[0-8] fade . ps15 ; cube_rot(.,[xy][yzwvu],astep-vvslow) ; size . ps20 frame = 6.d; n 2fs; rot6vs; a xw d0.01 ; f . . map . fade ps14 ; cube c[0-8] fade . ps14 ; cube_rot(.,[xy][yzwvu],astep-vvslow) ; a xy d-0.001 ; size . ps20 frame = 6.e; n 2fs; rot6s; a xw d0.01 ; f . . map . fade ps13 ; cube c[0-8] fade . ps13 ; cube_rot(.,[xy][yzwvu],astep-vslow) ; a xy d-0.002 ; size . ps20 frame = 6.f; n 2fs; rot6s; a xw d0.01 ; f . . map . fade ps12 ; cube c[0-8] fade . ps12 ; cube_rot(.,[xy][yzwvu],astep-slow) ; a xy d-0.002 ; size . ps20 frame = 6.g; n 2fs; rot6f; a xw d0.02 ; f . . map . fade ps11 ; cube c[0-8] fade . ps11 ; cube_rot(.,[xy][yzwvu],astep-slow) ; a xy d-0.002 ; size . ps20 frame = 6.h; n 2fs; rot6f; a xw d0.02 ; f . . map . fade ps10 ; cube c[0-8] fade . ps10 ; cube_rot(.,[xy][yzwvu],astep-med) ; a xy d-0.002 ; size . ps20 frame = 6.i; n 2fs; rot6vf; a xw d0.03 ; f . . map . fade ps9 ; cube c[0-8] fade . ps9 ; cube_rot(.,[xy][yzwvu],astep-med) ; a xy d-0.003 ; size . ps20 frame = 6.j; n 2fs; rot6vf; a xw d0.03 ; f . . map . fade ps8 ; cube c[0-8] fade . ps8 ; cube_rot(.,[xy][yzwvu],astep-fast) ; a xy d-0.003 ; size . ps20 frame = 6.k; n 2fs; rot6vf; a xw d0.04 ; f . . map . fade ps7 ; cube c[0-8] fade . ps7 ; cube_rot(.,[xy][yzwvu],astep-fast) ; a xy d-0.004 ; size . ps21 frame = 6.l; n 2fs; rot6vf; a xw d0.05 ; f . . map . fade ps6 ; cube c[0-8] fade . ps6 ; cube_rot(.,[xy][yzwvu],astep-vfast) ; a xy d-0.005 ; size . ps21 frame = 6.m; n 2fs; rot6vvf; a xw d0.06 ; f . . map . fade ps6 ; cube c[0-8] fade . ps6 ; cube_rot(.,[xy][yzwvu],astep-vfast) ; a xy d-0.010 ; size . ps21 frame = 6.n; n 2fs; rot6vvf; a xw d0.07 ; f . . map . fade ps6 ; cube c[0-8] fade . ps6 ; cube_rot(.,[xy][yzwvu],astep-vfast) ; a xy d-0.010 ; size . ps21 frame = 6.o; n 2fs; rot6vvvf; a xw d0.08 ; f . . map . fade ps8 ; cube c[0-8] fade . ps8 ; cube_rot(.,[xy][yzwvu],astep-vvfast) ; a xy d-0.007 ; size . ps21 frame = 6.p; n 2fs; rot6vvvf; a xw d0.05 ; f . . map . fade ps10 ; cube c[0-8] fade . ps10 ; cube_rot(.,[xy][yzwvu],astep-vvfast) ; a xy d-0.004 ; size . ps21 frame = 6.q; n 2fs; rot6vvvf; a xw d0.03 ; f . . map . fade ps12 ; cube c[0-8] fade . ps12 ; cube_rot(.,[xy][yzwvu],astep-vvfast) ; a xy d-0.002 ; size . ps21 frame = 6.r; n 2fs; rot6vvvf; a xw d0.01 ; f . . map . fade ps14 ; cube c[0-8] fade . ps14 ; cube_rot(.,[xy][yzwvu],astep-vvfast) ; a xy d-0.001 ; size . ps21 ################################################################ # peak (14) # # Grow four maps, drawing their edges. frame = 7: frame = 7.a; cube_add(ce,1,1) frame = 7.a; cube_add(cf,1,1) frame = 7.a; cube_add(cg,1,1) frame = 7.a; cube_add(ch,1,1) frame = 7.a; cube ce size . 1.1 frame = 7.a; cube cf size . 1.2 frame = 7.a; cube cg size . 1.35 frame = 7.a; cube ch size . 1.5 frame = 7.a; cube c[e-h] angle . 0-0.25 frame = 7.a; map_add(ce,xyzwv,pia) frame = 7.a; map_add(cf,xyzwv,pib) frame = 7.a; map_add(cg,xyzwv,pib) frame = 7.a; map_add(ch,xyzwv,pic) frame = 7.a; n 2fs; rot6f; rep 2 ; face c[0-9a-e] . map . fade p5 ; cube c[0-2] fade . p5 ; cube_rot(.,[xy][yzwvu],astep-med) frame = 7.b; n 2fs; rot6f; rep 2 ; cube_rot(.,[xy][yzwvu],astep-med) frame = 7.c; n 2fs; rot6vf; rep 2 ; face c[0-9a-f] . map . fade p5 ; cube c[0-4] fade . p5 ; cube_rot(.,[xy][yzwvu],astep-med) frame = 7.d; n 2fs; rot6vf; rep 2 ; cube_rot(.,[xy][yzwvu],astep-med) frame = 7.e; n 2fs; rot6vvf; rep 2 ; face c[0-9a-g] . map . fade p5 ; cube c[0-6] fade . p5 ; cube_rot(.,[xy][yzwvu],astep-med) frame = 7.f; n 2fs; rot6vvf; rep 2 ; cube_rot(.,[xy][yzwvu],astep-med) frame = 7.g; n 2fs; rot6vf; rep 2 ; face c[0-9a-h] . map . fade p5 ; cube c[0-8] fade . p5 ; cube_rot(.,[xy][yzwvu],astep-med) frame = 7.h; n 2fs; rot6vf; rep 2 ; cube_rot(.,[xy][yzwvu],astep-med) frame = 7.i; n 2fs; rot6vf; rep 2 ; face . . map . fade p5 ; cube c[0-8] fade . p5 ; cube_rot(.,[xy][yzwvu],astep-med) frame = 7.j; n 2fs; rot6vf; rep 2 ; cube_rot(.,[xy][yzwvu],astep-med) ################################################################ # outro (18) # # Slow down rotation and start shrinking and fading everything frame = 8: frame = 8.a; n 2fs ; rep 4 ; rot6f ; size . r0.95 ; cube_rot(.,[xy][yzwvu],astep-med) ; cube . f . q33 ; map_fade(.,.,q33) ; cube c[e-h] s . r0.95 frame = 8.a; n 2fs ; rep 2 ; rot6m ; size . r0.90 ; cube_rot(.,[xy][yzwvu],astep-med) ; cube . f . q33 ; map_fade(.,.,q33) ; cube c[e-h] s . r0.95 frame = 8.c; n 2fs ; rot6s ; rep 4 ; size . q31 ; cube_rot(.,[xy][yzwvu],astep-med) ; cube . f . q50 ; map_fade(.,.,q50) ; cube c[e-h] s . r0.95 ################################################################ # decay and fade (18) # # Further slow rotations and keep shrinking frame = 9: frame = 9.a; n 2fs ; rot6s ; rep 6 ; size . q30 ; cube_rot(.,[xy][ywvu],astep-med) ; cube . f . q50 ; map_fade(.,.,q50) frame = 9.b; n 2fs ; rot6s ; rep 6 ; size . q29 ; cube_rot(.,[xy][ywvu],astep-med) ; cube . f . q50 ; map_fade(.,.,q50) frame = 9.c; n 1fs ; rot6s ; size . 0 ; cube_rot(.,[xy][yzwvu],astep-med) ; cube . f . 1 ; map_fade(.,.,1) frame = stop$
news + thoughts

# Regression modeling of time-to-event data with censoring

Mon 21-11-2022

If you sit on the sofa for your entire life, you’re running a higher risk of getting heart disease and cancer. —Alex Honnold, American rock climber

In a follow-up to our Survival analysis — time-to-event data and censoring article, we look at how regression can be used to account for additional risk factors in survival analysis.

We explore accelerated failure time regression (AFTR) and the Cox Proportional Hazards model (Cox PH).

Nature Methods Points of Significance column: Regression modeling of time-to-event data with censoring. (read)

Dey, T., Lipsitz, S.R., Cooper, Z., Trinh, Q., Krzywinski, M & Altman, N. (2022) Points of significance: Regression modeling of time-to-event data with censoring. Nature Methods 19.

# Music video for Max Cooper's Ascent

Tue 25-10-2022

My 5-dimensional animation sets the visual stage for Max Cooper's Ascent from the album Unspoken Words. I have previously collaborated with Max on telling a story about infinity for his Yearning for the Infinite album.

I provide a walkthrough the video, describe the animation system I created to generate the frames, and show you all the keyframes

Frame 4897 from the music video of Max Cooper's Asent.

The video recently premiered on YouTube.

Renders of the full scene are available as NFTs.

# Gene Cultures exhibit — art at the MIT Museum

Tue 25-10-2022

I am more than my genome and my genome is more than me.

The MIT Museum reopened at its new location on 2nd October 2022. The new Gene Cultures exhibit featured my visualization of the human genome, which walks through the size and organization of the genome and some of the important structures.

My art at the MIT Museum Gene Cultures exhibit tells shows the scale and structure of the human genome. Pay no attention to the pink chicken.

# Annals of Oncology cover

Wed 14-09-2022

My cover design on the 1 September 2022 Annals of Oncology issue shows 570 individual cases of difficult-to-treat cancers. Each case shows the number and type of actionable genomic alterations that were detected and the length of therapies that resulted from the analysis.

An organic arrangement of 570 individual cases of difficult-to-treat cancers showing genomic changes and therapies. Apperas on Annals of Oncology cover (volume 33, issue 9, 1 September 2022).

Pleasance E et al. Whole-genome and transcriptome analysis enhances precision cancer treatment options (2022) Annals of Oncology 33:939–949.

My Annals of Oncology 570 cancer cohort cover (volume 33, issue 9, 1 September 2022). (more)

Browse my gallery of cover designs.

A catalogue of my journal and magazine cover designs. (more)

# Survival analysis—time-to-event data and censoring

Fri 05-08-2022

Love's the only engine of survival. —L. Cohen

We begin a series on survival analysis in the context of its two key complications: skew (which calls for the use of probability distributions, such as the Weibull, that can accomodate skew) and censoring (required because we almost always fail to observe the event in question for all subjects).

We discuss right, left and interval censoring and how mishandling censoring can lead to bias and loss of sensitivity in tests that probe for differences in survival times.

Nature Methods Points of Significance column: Survival analysis—time-to-event data and censoring. (read)

Dey, T., Lipsitz, S.R., Cooper, Z., Trinh, Q., Krzywinski, M & Altman, N. (2022) Points of significance: Survival analysis—time-to-event data and censoring. Nature Methods 19:906–908.

# 3,117,275,501 Bases, 0 Gaps

Sun 21-08-2022

See How Scientists Put Together the Complete Human Genome.

My graphic in Scientific American's Graphic Science section in the August 2022 issue shows the full history of the human genome assembly — from its humble shotgun beginnings to the gapless telomere-to-telomere assembly.

Read about the process and methods behind the creation of the graphic.

3,117,275,501 Bases, 0 Gaps. Text by Clara Moskowitz (Senior Editor), art direction by Jen Christiansen (Senior Graphics Editor), source: UCSC Genome Browser.