1. Concept
In the beginning of this process in producing a computer graphic artwork, I was inspired by traditional patterned Indonesian batik. As I searched up some designs, my attention was kept by one particular design. I was struck by the magnitude of breathtaking blue and daring strokes of the artist here. I knew that for my artpiece, I wanted to incorporate water waves.

I was partly inspired by my memories of swirls I’d seen in Starry Night by Vincent Van Gogh and the almost swirly-shaped water wave Under the Wave off Kanagawa by Katsushika Hokusai. I wanted to incorporate patterns of swirls which highlight the tidal aspect of seawater, along with sine waves to depict its wavy nature.


I thought of having my artwork depict a scene, so while keeping patterns as a motif in this piece, I added a sun composed of concentric circles, a sky made of turquoise and cyan waves (because I thought these colours looked cool) and rainfall. However, upon revising my plan much later, so that I would draw a night scene, I realised that a moon instead of a sun makes more sense, as well as dark blue and violet colours for the sky instead of turquoise and cyan.

In order to code up this piece, I first had to study the fundamentals. To generate a spiral, I studied The Coding Train’s explanatory video on polar coordinates. It was very crucial in helping me understand why using the 2D polar coordinate system (location described in terms of radius and angle) is crucial in drawing special (and especially circular shapes) than the 2D Cartesian coordinate system (location described in terms of x- and y- coordinates). Through this video, I got the idea to draw a spiral: I could use the formula for a circle, except I would increase the angle while decrease the radius over time. This is much preferred over using describing a multitude of precise x- and y- coordinates.
At first, my idea to generate an animated sine wave was to move an entire sine wave line to the left or to the right. However, after watching two of The Coding Train’s explanatory videos one on simple harmonic motion and one on graphing sine wave, I realized there’s another really interesting approach. Start from a dot oscillating up and down, then make an array of such dots, all oscillating up and down but with varying period and frequency.
2. Code Highlights
Firstly, generating the spirals, a complex shape is a highlight of the project, and a huge challenge as well. I faced multiple issues:
- Incorrect loop structure: The inner loop used ‘i’ instead of ‘j’ as the variable, potentially causing a conflict with the outer loop. Additionally, the inner loop was never updated, potentially causing an infinite loop.
- Spiral positioning: My translate() was not positioning each spiral correctly, resulting in spirals being drawn on top of each other.
- Spiral reset: Whilst the angle and radius were reset, it was done outside the loop that drew the spiral, so this would cause just one dot of each spiral to be visible, with each point of the spiral being drawn on top of the other spiral points.
At one point, my canvas wasn’t visible, and I think it was because of an infinite loop occurring. AI was a useful resource to help me resolve this, as well as provide suggestions for my code. I learned one correct approach of drawing many spirals: by translating each spiral using i and j and incrementing by the spiral radius (in order to space out spirals evenly with some padding between them).
let angle_spiral = 2.5; let r_spiral = 30; function drawSpirals() { for (let i = 0; i < (height / 2 - 20) / (r_spiral + 20); i++) { for (let j = 0; j < width / (r_spiral + 20); j++) { push(); translate( j * (r_spiral + 20) + r_spiral, 300 + i * (r_spiral + 20) + r_spiral ); // spaces out spirals evenly with some padding between them strokeWeight(2); stroke(0, 191, 255); let tempAngle = angle_spiral; let tempRadius = r_spiral; while (tempRadius > 3) { let x = tempRadius * cos(tempAngle); let y = tempRadius * sin(tempAngle); point(x, y); tempAngle += 0.2; tempRadius -= 0.2; } pop(); } } }
Second, another highlight is the sine waves representing the sky. To implement the array of dots, we need to first find out the total number of wave dots that can fit across the entire width of the canvas. Then comes the mapping function, which becomes really important in generating the sine waves. In this case, it maps each point’s position i along the wave to an angle between 0 and 8*PI radius.
let sky_angles_wave = []; let r_wave = 0.5; function setup() { ... let total_wave_dots = floor(width / (r_wave * 2)); ... for (let i = 0; i < total_wave_dots + 1; i++) { sky_angles_wave[i] = map(i, 0, total_wave_dots, 0, 8 * TWO_PI); } ... }
In the drawing function, the x-coordinates (or angle) of the sine wave will be mapped to span the entire width of the canvas (600 px). The y-coordinates (or sine of each angle in sky_angles_wave) is mapped to a value between -15 to 15, resulting in a sine wave with an amplitude of 15.
function drawSky() { for (let y = 15; y <= 210; y += 30) { push(); translate(300, y); fill(0); strokeWeight(6); stroke(81, 97, 199); beginShape(); for (let i = 0; i < sky_angles_wave.length; i++) { let y = map(sin(sky_angles_wave[i]), -1, 1, -15, 15); strokeWeight(2); let x = map(i, 0, sky_angles_wave.length, -300, 300); vertex(x, y); sky_angles_wave[i] -= 0.001; } endShape(); pop(); } for (let y = 15; y <= 210; y += 30) { push(); translate(300, y); noFill(); strokeWeight(4); stroke(0, 104, 198); beginShape(); for (let i = 0; i < sky_angles_wave.length; i++) { let y = map(sin(sky_angles_wave[i] + PI), -1, 1, -15, 15); strokeWeight(2); let x = map(i, 0, sky_angles_wave.length, -300, 300); vertex(x, y); sky_angles_wave[i] -= 0.001; } endShape(); pop(); } }
Each point can shift down and up using: sky_angles_wave[i] -= 0.001;
Last but not least, apparently creating dotted lines (for the rainfall) is quite complicated. So I tried to think of another way. I used black sine waves to cover the grey rainfall.
All in all, this was a complex code!
3. Embedded sketch
4. Reflection and ideas for future work
I found this project to be very engaging, from the brainstorming stages to the coding process. I found the challenges a valuable opportunity to grow in learning how to graph complex shapes and animate lines (animation was something I wanted to learn from last week!). I have achieved the goal of creating a piece similar to the plan I intended, but have also exceeded that by adding in animations.
I hope the artpiece will be a calming one. An idea for the future is to animate the spirals to shift along with the deeper blue sine water waves. The moon could also be animated to grow and dim in brightness over time. Additionally, it would be cool to learn to animate rainfall (the technique used here was more of a special workaround, and I drew black lines over the moving water, the supposedly “invisible” black waves become more prominent!).