Skip to content

Instantly share code, notes, and snippets.

@cosmicmonster
Last active August 6, 2021 08:32
Show Gist options
  • Save cosmicmonster/938c9ef6cd66abd314af5e6c7fef1db8 to your computer and use it in GitHub Desktop.
Save cosmicmonster/938c9ef6cd66abd314af5e6c7fef1db8 to your computer and use it in GitHub Desktop.
Earth, Venus and the Sun Cardioid Animation
/*
* Cosmic Ballet v1.1
*
* Inspired by reddit post by u/mtimetraveller
* Developed by Phil Gullberg, 2018 - adapted to p5js in 2021
* contact@cosmic.monster
*
*/
// SETUP VARS
let w = 500;
let h = 500;
let framerate = 60; // Set framerate
let framesPerLine = framerate / 20; // Determins how many frames will pass for every line drawn
let scale = 1.0;
let allLines = []; // ArrayList that holds all drawn lines
// VENUS VARS
let venusRadius = 6000.0 / 500.0; // Roughtly based on actual proportions, kinda
let venusOrbitalPeriod = 225.0;
let venusDistanceToSun = 108.2;
let venusTheta = 0.0;
let venusSpeed = framerate / venusOrbitalPeriod / 10.0;
let venusPos;
// EARTH VARS
let earthRadius = 6371.0 / 500.0; // Roughtly based on actual proportions, kinda
let earthOrbitalPeriod = 365.0;
let earthDistanceToSun = 149.6;
let earthTheta = 0.0;
let earthSpeed = framerate / earthOrbitalPeriod / 10;
let earthPos;
let sunRadius = 695700.0;
let sunPos;
// Class for the line
class Line {
constructor(_x1, _y1, _x2, _y2) {
this.x1 = _x1;
this.y1 = _y1;
this.x2 = _x2;
this.y2 = _y2;
}
update() {
stroke(255, 20);
strokeWeight(1);
line(this.x1, this.y1, this.x2, this.y2);
}
}
// Set frame rate, screen size and the position of the sun
function setup() {
frameRate(framerate);
createCanvas(w, h);
sunPos = new p5.Vector(w / 2, h / 2);
}
// Draws everything every frame
function draw() {
background(30);
orbits();
drawLine();
updateLines();
noStroke();
sun();
venus();
earth();
drawText();
}
// Draw the orbit of Earth and Venus
function orbits() {
stroke(255);
noFill();
ellipse(sunPos.x, sunPos.y, venusDistanceToSun * 2, venusDistanceToSun * 2);
ellipse(sunPos.x, sunPos.y, earthDistanceToSun * 2, earthDistanceToSun * 2);
}
// Draw Sun
function sun() {
fill(255, 204, 100);
ellipse(sunPos.x, sunPos.y, 30, 30);
}
// Draw venus
function venus() {
venusTheta += venusSpeed;
let posX = sunPos.x + venusDistanceToSun * cos(venusTheta);
let posY = sunPos.y + venusDistanceToSun * sin(venusTheta);
venusPos = new p5.Vector(posX, posY);
fill(255, 0, 100);
ellipse(venusPos.x, venusPos.y, venusRadius, venusRadius);
}
// Draw Earth
function earth() {
earthTheta += earthSpeed;
let posX = sunPos.x + earthDistanceToSun * cos(earthTheta);
let posY = sunPos.y + earthDistanceToSun * sin(earthTheta);
earthPos = new p5.Vector(posX, posY);
fill(0, 255, 100);
ellipse(earthPos.x, earthPos.y, earthRadius, earthRadius);
}
// Draw a line each 6 frames and add to line list
function drawLine() {
if (frameCount % framesPerLine == 0) {
let tmp = new Line(venusPos.x, venusPos.y, earthPos.x, earthPos.y);
append(allLines, tmp);
}
}
function drawText() {
fill(255);
//LEFT
text("Framerate (target): " + round(frameRate(), 2) + " (" + framerate + ")", 10, 15);
text("Lines (total): " + allLines.length, 10, 30);
text("Lines per frame: " + framesPerLine, 10, 45);
fill(255, 0, 100);
text("Speed (Venus): " + round(venusSpeed, 5), 10, 60);
fill(0, 255, 100);
text("Speed (Earth): " + round(earthSpeed, 5), 10, 75);
// RIGHT
fill(255, 0, 100);
text("Theta (Venus): " + venusTheta, 250, 15);
fill(0, 255, 100);
text("Theta (Earth): " + earthTheta, 250, 30);
fill(255, 0, 100);
text("Orbital period (Venus): " + venusOrbitalPeriod, 250, 45);
fill(0, 255, 100);
text("Orbital period (Earth): " + earthOrbitalPeriod, 250, 60);
}
// Update all lines on the screen
function updateLines() {
allLines.forEach((line) => {
line.update();
});
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment