Platonic solids, named after the philosopher Plato, are highly symmetrical, three-dimensional shapes. Each face of a Platonic solid is the same regular polygon, and the same number of polygons meet at each vertex. This sketch demonstrates the rendering of Platonic solids using the p5.platonic library, showcasing both the immediate mode and retained mode rendering of the shapes. Check out the platonic cells example, which fills quadrille cells with the Platonic solids introduced here.
code
const colors = [
[1, 0, 0, 1], // Red
[0, 1, 0, 1], // Green
[0, 0, 1, 1], // Blue
[0, 1, 1, 1], // Cyan
[1, 0, 1, 1], // Magenta
[1, 1, 0, 1], // Yellow
[0.5, 0, 0, 1], // Dark Red
[0, 0.5, 0, 1], // Dark Green
[0, 0, 0.5, 1], // Dark Blue
[0, 0.5, 0.5, 1],// Teal
[0.5, 0, 0.5, 1],// Purple
[0.5, 0.5, 0, 1],// Olive
[1, 0.5, 0, 1], // Orange
[1, 0, 0.5, 1], // Pink
[0.5, 1, 0, 1], // Lime
[0, 1, 0.5, 1], // Spring Green
[0.5, 0.5, 0.5, 1],// Grey
[0.5, 1, 0.5, 1],// Mint
[1, 0.5, 0.5, 1],// Salmon
[1, 1, 0.5, 1] // Cream
]
let dodecahedronGeometry
function setup() {
createCanvas(600, 400, WEBGL)
colorMode(RGB, 1)
strokeWeight(2)
stroke('white')
dodecahedronGeometry = platonicGeometry(dodecahedron, 80, true, colors)
}
function draw() {
background(0)
orbitControl()
push()
rotateX(frameCount * 0.01)
rotateY(frameCount * 0.01)
rotateZ(frameCount * 0.01)
model(dodecahedronGeometry)
pop()
push()
translate(-width / 4, -height / 4, 0)
rotateY(frameCount * 0.01)
fill('DarkTurquoise')
tetrahedron()
pop()
push()
translate(width / 4, -height / 4, 0)
rotateZ(frameCount * 0.01)
hexahedron(colors, true)
pop()
push()
translate(-width / 4, height / 4, 0)
rotateX(frameCount * 0.01)
octahedron(colors, 120)
pop()
push()
translate(width / 4, height / 4, 0)
rotateY(frameCount * 0.01)
icosahedron(colors, 80)
pop()
}
Immediate Mode
Immediate mode is a graphics rendering technique where each frame is redrawn from scratch. In p5.js, this is implemented using functions like beginShape and endShape. All Platonic solids in the p5.platonic library, such as tetrahedron
, hexahedron
(or cube
), octahedron
, dodecahedron
and icosahedron
, are implemented in this mode.
The following code snippet demonstrates how various Platonic solids are drawn in immediate mode:
function draw() {
// ...
// tetrahedron
push()
translate(-width / 4, -height / 4, 0)
rotateY(frameCount * 0.01)
fill('DarkTurquoise')
tetrahedron()
pop()
// hexahedron may also be called as cube
push()
translate(width / 4, -height / 4, 0)
rotateZ(frameCount * 0.01)
hexahedron(colors, true)
pop()
// octahedron
push()
translate(-width / 4, height / 4, 0)
rotateX(frameCount * 0.01)
octahedron(colors, 120)
pop()
// icosahedron
push()
translate(width / 4, height / 4, 0)
rotateY(frameCount * 0.01)
icosahedron(colors, 80)
pop()
}
Retained Mode
Retained mode is a graphics rendering technique where graphical objects are stored and managed, reducing the need to redraw them every frame. In p5.js, retained mode can be implemented using 3D primitives and the beginGeometry function.
The following code snippet demonstrates how a dodecahedron
is rendered in retained mode:
let dodecahedronGeometry
function setup() {
// ...
strokeWeight(2)
stroke('white')
// pass dodecahedron drawing function followed by the params used to render it
dodecahedronGeometry = platonicGeometry(dodecahedron, 80, true, colors)
}
function draw() {
// ...
push()
rotateX(frameCount * 0.01)
rotateY(frameCount * 0.01)
rotateZ(frameCount * 0.01)
// render dodecahedronGeometry using model
model(dodecahedronGeometry)
pop()
// ...
}
The platonicGeometry
function in the p5.platonic library is used to create and store the geometry of a Platonic solid for rendering in retained mode. This function takes the solid’s drawing function and parameters as arguments, making it easy to manage and display complex shapes efficiently.
Coloring
Platonic solids may be colored in different ways. The boolean fuse
parameter in the function calls specifies whether to blend colors along the polygons’ faces.
const colors = [
[1, 0, 0, 1], // Red
[0, 1, 0, 1], // Green
[0, 0, 1, 1], // Blue
[0, 1, 1, 1], // Cyan
[1, 0, 1, 1], // Magenta
[1, 1, 0, 1], // Yellow
[0.5, 0, 0, 1], // Dark Red
[0, 0.5, 0, 1], // Dark Green
[0, 0, 0.5, 1], // Dark Blue
[0, 0.5, 0.5, 1], // Teal
[0.5, 0, 0.5, 1], // Purple
[0.5, 0.5, 0, 1], // Olive
[1, 0.5, 0, 1], // Orange
[1, 0, 0.5, 1], // Pink
[0.5, 1, 0, 1], // Lime
[0, 1, 0.5, 1], // Spring Green
[0.5, 0.5, 0.5, 1],// Grey
[0.5, 1, 0.5, 1], // Mint
[1, 0.5, 0.5, 1], // Salmon
[1, 1, 0.5, 1] // Cream
]