A modern clepsydra
a timepiece in which time is measured by the regulated flow of liquid.
//Ghalya Alsanea
//Section B
//galsanea@andrew.cmu.edu
//Project-06
//configure sizes of each water bowl
var secBowl = 25;
var minBowl = 18;
var hrBowl = 20;
//define x coordinates and y start points for each bowl
var secX = 200;
var secY = 150;
var minX = 300;
var minY = 60;
var hourX = 150;
var hourY = 90;
//water drop animation start X and Y positions
var startX = 0;
var startY = 0;
//set up fill matrix for the seconds
//row is time intervals (s)
//columns are fill for the seconds bowls
var fills =[['blue' , 255 , 255 , 255 ],
[255 , 'blue', 255 , 255 ],
['blue' , 'blue', 255 , 255 ],
[255 , 255 , 'blue', 255 ],
['blue' , 255 , 'blue', 255 ],
[255 , 'blue', 'blue', 255 ],
['blue' , 'blue', 'blue', 255 ],
[255 , 255 , 255 , 'blue'],
['blue' , 255 , 255 , 'blue'],
[255 , 'blue', 255 , 'blue'],
['blue' , 'blue', 255 , 'blue'],
[255 , 255 , 'blue', 'blue'],
['blue' , 255 , 'blue', 'blue'],
[255 , 'blue', 'blue', 'blue'],
['blue' , 'blue', 'blue', 'blue'],
]
function setup() {
createCanvas(480, 480);
angleMode(DEGREES);
}
function draw() {
background("pink");
//background mechanisms --> graphics
noStroke();
//top
fill(255);
arc(width/2, 20, 50, 50, 0, 180);
fill('blue');
arc(width/2, 30, 40, 28, 0, 180);
//bottom
circle(width/2, height -50, 50);
//connecting tubes
rect(width/2 - 3, 32, 6, height - 100);
rect(minX - 2, minY + minBowl * 0.6 * 29, 4, minBowl + 10);
//blue lines
noFill();
strokeWeight(3);
stroke('blue');
//minute connectors
line(minX, (minY + minBowl * 31 * 0.6), width/2, height - 50);
line(minX - minBowl +2, minY + minBowl * 0.6 * 30, minX, minY + minBowl * 0.6 * 30);
//seconds connectors
line(secX, secY + secBowl*6, secX, secY + secBowl*7);
line(secX, secY + secBowl*7, width/2, secY + secBowl*8);
line(secX, secY, secX, secY - secBowl*3);
arc(secX + 8, secY - secBowl*3, 16, 16, 180, 360);
line(secX + 16, secY - secBowl*3, secX + 16, secY - secBowl*2);
arc(secX + 24, secY - secBowl*2, 16, 16, 0, 180);
line(secX + 32, secY - secBowl*2, secX + 32, 35);
//don't start filling up hours if it's noon or midnight
if(hour() == 12) {
stroke(255);
} else {
stroke('blue');
}
//hour connectors
line(minX - minBowl*2, hourY + hrBowl * 1.2 * 12, hourX, hourY + hrBowl * 1.2 * 12);
line(hourX, hourY + hrBowl * 1.2 * 11, hourX, hourY + hrBowl * 1.2 * 12);
//purely white lines
stroke(255);
arc(minX- minBowl*1.5 + 2, minY, minBowl, minBowl, 180, 360);
line(minX - minBowl*2 + 2, minY, minX - minBowl*2 + 2, hourY);
line(hourX, hourY-25, hourX, hourY);
line(hourX, hourY-25, width / 2 - 15, 25);
//do the math to figure out the times in useful numbers
//since the cycle is in 2 minute intervals
//you have to shift the seconds in the second minute
if(minute() % 2 == 0) {
var s = floor(second() / 8);
} else {
var s = floor((60 + second())/8);
}
//if minutes is divisible by 2, fill one of the minute bowls
var m = floor(minute()/2);
//every hour, fill one hour bowl
var h = hour() % 12;
//seconds base
for (i = 0; i < 4; i++) {
noStroke();
//assign each bowl to it's color
fill(fills[s][i]);
circle(secX, secY + secBowl * 1.5 * i, secBowl + 4*i);
rect(secX - 3.5, secY + secBowl * 1.5 * i, 7, secBowl + 4*i);
}
//minutes base
strokeWeight(0.5);
for (i = 0; i < 30; i++) {
noStroke();
//figure out if bowl should be filled with water
if(30 - i <= m){
fill("blue");
}
else {
fill(255);
}
//bowls
ellipse(minX, minY + minBowl * i * 0.6, minBowl, minBowl / 2);
rect(minX - 2, minY + minBowl * 0.6 * i, 4, minBowl / 2);
//siphon tube
rect(minX - minBowl, minY + minBowl * 0.6 * i, 4, minBowl);
//tick marks for every 10 minutes
if (i % 5 == 0) {
push();
translate(minX + minBowl, minY + minBowl * i * 0.6);
stroke("blue");
for(var a = 0; a < 30 - i; a+=5){
line(0, 0, a/2 + 2, 0);
}
pop();
}
}
//hours base
for (i = 0; i < 12; i++) {
noStroke();
//figure out if bowl should be filled with water
if(12 - i <= h){
fill("blue");
}
else {
fill(255);
}
//bowls
circle(hourX, hourY + hrBowl*1.2*i, hrBowl);
rect(hourX - 3, hourY + hrBowl * 1.2 * i, 6, hrBowl);
//siphon tube
rect(minX - minBowl*2, hourY + hrBowl * 1.2 * i, 4, hrBowl*2);
}
// water dripping annimation
push();
translate(secX, secY - secBowl);
stroke('blue');
strokeWeight(3);
//draw dashed line
for (i = 0; i < 160; i+=20) {
var y = map(startY, 0, secBowl*8, 0, 100);
line(startX, y+i, startX, y + i + 5);
}
//animate line
startY = startY + 2;
//reset after 3 bowls
if (startY > secBowl*3) {
startY = 0;
}
pop();
}
For this project I was inspired by this clock in a mall I used to go to back home, which is the oldest mall in Kuwait. I used to sit in the main lobby as a child and stare at the sculpture for hours. Here’s a video…
I started by doing a lot of research about water clocks and how they work. You can find a brief history here. I decided to take the modern approach of the scientist, Bernard Gitton’s. I used this animation to visually understand how the clock works, and I used the explanations behind the physics of the timepiece and the calculations found on this page to figure out the code necessary to simulate the water clock.