Select Page

### Challenge

Use p5.js to create a more robust artistic composition using trigonometric concepts, with bonus points for 3d. Some suggestions:

• a digital painting
• an animated magazine cover
• an interactive concert/show poster

### Solution

Happy Equinox Everyone. For Design Challenge 3, a more robust application based on trigonometry, I chose a celestial application to display an analemma. An analemma is that figure 8 pattern smack in the middle of the Pacific Ocean on our globes. It’s really just a marker for where the Sun appears at the same time everyday. It’s easy to notice the Sun high in the sky in the summer and low during the winter. This is due to the Earth’s 23.5 degree axial tilt. The side to side motion is a little trickier and is a play between the Earth’s orbital eccentricity (how elliptical the orbit is) and when the Earth makes its closest approach (known as perhelion) to the Sun which is during the winter. As the Earth moves along its orbit, it moves faster as it comes closer to the Sun; something discovered in Kepler’s second law of planetary motion. This causes the Sun to be “ahead” or “behind” it’s expected appearance.

I had plans to create a slider where one could change parameters such as orbital eccentricity, axial tilt and perihelion date to mimic the conditions of other planets. Mars’ analemma is egg-shaped mainly because of when perhelion takes place. I delved into equations to determine the Sun’s elevation in the sky given the day of the year and what the time difference to show the side to side motion. And created a little starry night atmosphere. A simple mouseX function uses the entire width of the screen to traverse a year. That number is stored to drive the x and y. All of the trigonometry in this demo is in these calculations. The remaining effort was to just draw it out. That did not come together. I’m left with this oval shape. There is an error in this part of my script that is escaping my efforts to solve. Math is like that sometimes.

analemma.js

// Creative Tech
// Design Challenge 3

/**
Use p5.js to create a more robust artistic composition using trigonometric concepts, with bonus points for 3d. Some suggestions:

a digital painting
an animated magazine cover
an interactive concert/show poster
**/

// constants
const Y_AXIS = 1;
const X_AXIS = 2;

var fromX, fromY;
var toX, toY;
var step = 10;
var slider;

// load any fonts or other resources
}

function setup() {
// define colors
let midnight = color(0,55,102); // midnight
let darkblue = color(0,20,80);
let black = color(0);
let b1 = color(26, 54, 75); // 1a364b – blue background 1
let b2 = color(26, 68, 82); // 1a4452 – blue background 2
let b3 = color(99, 164, 211); // lighter blue

// createCanvas(720, 400);
createCanvas(windowWidth,windowHeight);
noStroke();
background(0,20,80);

// drawStars();
// drawSun();

}

function draw() {
// draw background that fades stars slowly
// derived from https://editor.p5js.org/jd/sketches/HkF70H2uX
background(0,20,80, 1);

if (random() > 0.9) {
stroke(255);
point(random(windowWidth), random(windowHeight));
}

// draw stars
if (random() > 0.95 && step >= 2.5) {
fromX = random(windowWidth);
fromY = random(windowHeight);
toX = random(fromX+10, windowWidth);
toY = random(fromY+10, windowHeight);
step = 0;
}

// draw shooting stars
// randomize this
if (step < 2.5) {
strokeWeight(1);
let nextStep = step + 0.02;
strokeWeight(3);
stroke(0, 20, 80, 30);
line(fromX, fromY, toX, toY);
// draw star
if (step < 1) {
strokeWeight(3);
stroke(255, (1-step) * 200);
line(lerp(fromX, toX, step), lerp(fromY, toY, step),
lerp(fromX, toX, nextStep), lerp(fromY, toY, nextStep));
}
step = nextStep;
}

// drawSun();
createAnalemma();
drawText();

}

// create generic reusable gradient function
// noprotect
noFill();
for (var y = 0; y < height; y++) {
var inter = map(y, 0, height, 0, 1);
var c = lerpColor(c1, c2, inter);
stroke(c);
line(0, y, width, y);
}
}

function drawText() {
// explanation text
textSize(30);
noStroke();
fill(255);
text(‘To create an analemma,’, 50,100);
text(‘move the mouse right or left’, 50, 140);
text(‘to determine the day of the year’, 50, 180);
}

function drawSun() {
let sun1 = color(255, 238, 198); // ffeec6
let sun2 = color(255, 230, 173); // ffe6ad
let sun3 = color(255, 218, 132); // ffda84
let sun4 = color(255, 207, 96); // ffcf60
let sun5 = color(255, 199, 71); // ffc747

noStroke();
//circle(xcoord,ycoord,diameter)

// create here the pulsing sun

// end pulsing Sun

fill(sun5);
fill(sun4);
}

function createAnalemma(x,y,analemmaAngle) {

// DECLINATION
// every year solar declination wanders between -23.44 and +23.44 degree. Angle of Earth’s tilt

// Step 1: determine how many days since Jan 1; add 10
// Step 2: divide 360/number of days in year (360/365 = 0.9863
// Step 3: multiply number from step 1 by number in step 2
// Cos(step3)
// multiply -23.44 * cos(step3)

// example: feb14 is day 44 + 10 = 54
// 54 * (360/365) = 53.2603
// cos(53.2603) = 0.5982
// -23.44 * 0.5982 = -14.02 degrees. That’s the solar declination

// use entire width of screen to determine day of year
var mouseDate = int((mouseX/windowWidth)*365);
// console.log(‘mousex: ‘ + int(mouseDate));

var dayCount = [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334];
var y = year();
var m = month();
var d = day();
var dayofYear = dayCount[m-1] + d;

var earthTilt = 23.44;
var angle1 = radians((360/365)); // .9863
var angle2 = angle1 * mouseDate;
var dec = -(earthTilt) * cos(angle2);
// console.log(‘declination: \n’ + dec);

// FIND ANGLE OF EARTH IN RELATION TO SUN
// earth rotates about 361 degrees in 24 hours (as earth moves in orbit) and there are about 1440 minutes in 24 hours so….
// 1440/361 = 3.98892 minutes per degree of Earth’s rotation

// dayAngle = 360/365.24 // degrees in circle/days in a year
// N = day of year
// e = ellipticity of earth’s orbit about 0.16713

var daysYear = 365.24;
var avAnglePerDay = 360/daysYear; // .985653 degrees for Earth

var e = 0.016713; // earth’s orbital eccentricity
var gamma = radians(avAnglePerDay * (mouseDate-2));
var v = gamma + ((360/PI) * e) * (sin(gamma));
// var v1 = (360/PI) * e;
// var v3 = v1 * v2;
// var v4 = gamma + v3;
var angularDiff = gamma – v;
var timeDiff = angularDiff * 3.98892; // in minutes

console.log(‘xvalue: \n’ + timeDiff);
// pointx is arbitrary
// pointx determined by offset from center of window
// declination can be arbitrary as well … dec * some multiplier

pointX = windowWidth/2 + timeDiff*3;
pointY = windowHeight/2 + dec*10;
fill(0, 255, 0);
circle(pointX, pointY,10);

// show today’s circle
// todayX = windowWidth/2 + v4;
// todayY = windowHeight/2 + dec;
// fill(255, 207, 96);
// circle(todayX,todayY,20);

// explanation text
textSize(30);
noStroke();
fill(255);
text(‘DAY: ‘ + mouseDate, 50,220);

}

Beginning Sketch 