Homage to Robert Delaunay: Exploring Orphism through Code
Robert Delaunay is one of the pioneers of abstract painting. His legacy of vibrant, abstract compositions continues to be a profound source of inspiration for me.
I'll make some creative coding artwork with the inspiration of the paintings by Robert Delaunay.
Distributing Arcs Across Concentric Circles
I began by rendering a series of concentric circles in varying shades of grey to establish a foundation.
Next, I layered randomized arcs over the foundation.
Here is an example of the generated visual. I applied transparency on these arcs.
Here is the example drawing with the 'blendMode(BURN)' effect.
p5.js Example Code
Click the canvas to regenerate the composition.
/**
* In admiration of Robert Delaunay.
* Put arcs randonly
*
* @author @deconbatch
* @version 0.1
* @license CC0
* p5.js 1.5.0
* created 2023.02.15
*/
const w = 640;
const h = w;
const circleNum = 9;
const arcNum = 8;
const baseR = w * 1.3;
function setup() {
createCanvas(w, h);
colorMode(HSB, 360, 100, 100, 100);
noLoop();
}
function draw() {
translate(w * 0.5, h * 0.5);
blendMode(BLEND);
background(0, 0, 100, 100);
// concentric circles
blendMode(BLEND);
noStroke();
for (let cCnt = 0; cCnt < circleNum; cCnt++) {
fill(0, 0, random(60, 80), random(60));
circle(0, 0, baseR * (circleNum - cCnt) / circleNum);
}
// arcs
blendMode(BURN);
noFill();
strokeCap(SQUARE);
for (let aCnt = 0; aCnt < arcNum; aCnt++) {
let arcR = random(baseR);
let arcW = random(baseR);
let tFr = random(TWO_PI);
let tTo = tFr + random(PI);
strokeWeight(arcW);
stroke(random(360), 40, random(60, 80), random(60, 100));
arc(
0.0, 0.0,
arcR + arcW, arcR + arcW,
tFr, tTo
);
}
}
function mouseClicked() {
redraw();
}
Instead of using 'fill()', I used a heavy stroke with the 'arc()' function to create bold, structured forms.
Using 'strokeCap(SQUARE)' is key to achieving a clean, sharp look.
Using the 'PROJECT' cap will cause the ends to extend slightly.
Without the 'strokeCap()' function or with the 'strokeCap(ROUND)' will be like this.
Still, it has its own unique charm.
Step 2: Refining the Composition
While the purely random approach above works, the resulting composition feels cluttered and lacks visual intentionality.
To achieve a more harmonic structure, I decided to constrain the arc radii and widths to a fixed grid based on the concentric divisions.
// let arcR = random(baseR);
// let arcW = random(baseR);
let arcR = baseR * floor(random(1, circleNum)) / circleNum;
let arcW = baseR * floor(random(1, circleNum)) / circleNum;
By snapping the angles to a 24-division grid, the resulting visual becomes much more structured and harmonious.
// let tFr = random(TWO_PI);
// let tTo = tFr + random(PI);
let tFr = TWO_PI * floor(random(24)) / 24;
let tTo = tFr + PI * floor(random(1, 13)) / 12;
It'll create a harmonious result.
Now, I'll show you the example codes of the p5.js and the Processing version.
The Final Result: p5.js Example Code
/**
* In admiration of Robert Delaunay.
* Fixed unit arcs
*
* @author @deconbatch
* @version 0.1
* @license CC0
* p5.js 1.5.0
* created 2023.02.15
*/
const w = 640;
const h = w;
const circleNum = 9;
const arcNum = 8;
const baseR = w * 1.3;
function setup() {
createCanvas(w, h);
colorMode(HSB, 360, 100, 100, 100);
noLoop();
}
function draw() {
translate(w * 0.5, h * 0.5);
blendMode(BLEND);
background(0, 0, 100, 100);
// concentric circles
blendMode(BLEND);
noStroke();
for (let cCnt = 0; cCnt < circleNum; cCnt++) {
fill(0, 0, random(60, 80), random(60));
circle(0, 0, baseR * (circleNum - cCnt) / circleNum);
}
// arcs
blendMode(BURN);
noFill();
strokeCap(SQUARE);
for (let aCnt = 0; aCnt < arcNum; aCnt++) {
let arcR = baseR * floor(random(1, circleNum)) / circleNum;
let arcW = baseR * floor(random(1, circleNum)) / circleNum;
let tFr = TWO_PI * floor(random(24)) / 24;
let tTo = tFr + PI * floor(random(1, 13)) / 12;
strokeWeight(arcW);
stroke(random(360), 40, random(60, 80), random(60, 100));
arc(
0.0, 0.0,
arcR + arcW, arcR + arcW,
tFr, tTo
);
}
}
function mouseClicked() {
redraw();
}
The Final Result: Processing Example Code
/**
* In admiration of Robert Delaunay.
* Fixed unit arcs
*
* @author @deconbatch
* @version 0.1
* @license CC0
* Processing 3.5.3
* created 2023.02.15
*/
public void setup() {
size(640, 640);
colorMode(HSB, 360.0, 100.0, 100.0, 100.0);
smooth();
noLoop();
int circleNum = 9;
int arcNum = 8;
float baseR = width * 1.3;
translate(width * 0.5, height * 0.5);
blendMode(BLEND);
background(0.0, 0.0, 100.0, 100.0);
// concentric circles
blendMode(BLEND);
noStroke();
for (int cCnt = 0; cCnt < circleNum; cCnt++) {
fill(0.0, 0.0, random(60.0, 80.0), random(60.0));
circle(0.0, 0.0, baseR * (circleNum - cCnt) * 1.0 / circleNum);
}
// arcs
blendMode(SUBTRACT);
noFill();
strokeCap(SQUARE);
for (int aCnt = 0; aCnt < arcNum; aCnt++) {
float arcR = baseR * floor(random(1, circleNum)) * 1.0 / circleNum;
float arcW = baseR * floor(random(1, circleNum)) * 1.0 / circleNum;
float tFr = TWO_PI * floor(random(24)) / 24.0;
float tTo = tFr + PI * floor(random(1, 13)) / 12.0;
strokeWeight(arcW);
stroke(random(360.0), 40.0, random(60.0, 80.0), random(60.0, 100.0));
arc(
0.0, 0.0,
arcR + arcW, arcR + arcW,
tFr, tTo
);
}
}
Room for Exploration
I’ve found that the composition feels particularly balanced when the arc edges align with vertical, horizontal, or diagonal axes.
There is endless room for experimentation here—try controlling the color palettes more strictly or experimenting with different stroke weights. I invite you to take my code and find your own interpretation of Delaunay’s rhythm.













