Steven Fei & Mike Jin – Final Project

Press your mouse to add planets and nebulas and use your mouse to hover around the Canvas and explore the universe!!

sketch

//Steven Fei & Fanjie Mike Jin
//Section A & C
//Final Project
//zfei@andrew.cmu.edu & fjin@andrew.cmu.edu
var starNumber = 150;//number of the stars on the background
var starsize = 1.5;//size of the stars
var sx = [];//array to define the x position of the stars
var sy = [];//array to define the y position of the stars
var sz = [];//array to define the z position of the stars
var amplitude = 3.14 * 3;//define the moving margin of the stars
var waveSpeed;//define the moving speed of the stars on the background
var theta = 0;//define the moving angle of the stars
var glowDefiner = [];//define the true false value for whether to let the star glow
var glowSize = 22;//glowing size of the stars
var newStars = [];//array for making new stars
var mouseXList = [];//arrays to store mouseX value
var mouseYList = [];//arrays to store mouseY value
var img; //load image for the earth texture mapping 
var w = 600 / 7 // devivded the canvas into seven regions and from left to right, the pitches of the piano sound will progressively become higher  
var newExplod = [];//array for making new explosion at the background
var mouseXListEx = [];//arrays to store mouseX value
var mouseYListEx = [];//arrays to store mouseY value


function setup() {
//load the background image for the texture mapping of the earth
//coded by Mike
    img = loadImage("https://i.imgur.com/lamlO83.jpg");
    createCanvas(600, 600,WEBGL);

//create values for the positions of the stars on the background
//coded by Mike
    for (var i = 0; i < starNumber; i++){
        sx.push(random(-width * 0.75, width * 0.75));
        sy.push(random(-height, height));
        sz.push(random(-width, height/2));
        var toggle = random(1.0);
        //define whether the stars on the background will glow
        if(toggle < 0.9){
            glowDefiner.push(false);
        }else{
            glowDefiner.push(true);
        }
    }
    for(var j = 0; j < glowDefiner.length; j++){
    print(glowDefiner[j]);
    }
}

function draw(){
    background(0);
    noStroke();
    normalMaterial();
    centerCube();//create a center star to give a sense of what perspective we are looking at
    makeCamera();//use the makeCamera function to change the viewport angle
    makeearth();
    push();
    //draw the stars on the background
    for(var i = 0; i < starNumber; i++){
        //coded by Mike
        push();
        waveSpeed = map(sz[i], -width, height/2, 15000, 60000);//define the moving speed of the stars
        theta += (TWO_PI / waveSpeed);//define the moving angle of the stars
        if(theta > amplitude){
            theta = -theta;//set the moving margins of the stars
        }
        sy[i] += sin(theta);//set the moving value to the positions
        sx[i] += cos(theta);//set the moving value to the positions
        translate(sx[i], sy[i], sz[i]);
        if(glowDefiner[i]){
            fill(255, 200, 130, 4);
            sphere(glowSize);//draw glow light of the sphere
        }
        fill("white");
        smooth();
        sphere(starsize);//draw the stars
        pop();
    }
    pop();
    //draw some new stars
    //coded by Steven
    if (mouseXList.length != 0){
        for(var k = 0; k < newStars.length; k++){
            newStars[k].updateStar();//animate the expansion of the stars
            push();
            translate(newStars[k].x, newStars[k].y,0);
            rotateX(frameCount * 0.05 + k*2);//rotate the new star
            rotateY(frameCount * 0.05 + k*2);//rotate the new star
            newStars[k].draw();//animate the emergence of the stars
            pop();
        } 
    }
    if(newStars.length > 4){
        newStars.shift();
    }

    push();
    //make the planet
    if (mouseXListEx.length != 0){
        for(var k = 0; k < newExplod.length; k++){
            newExplod[k].updateExplo();//animate the expansion of the stars
            push();
            translate(newExplod[k].x, newExplod[k].y,0);
            rotateX(frameCount * 0.05 + k*2);//rotate the new star
            rotateY(frameCount * 0.05 + k*2);//rotate the new star
            newExplod[k].draw();//animate the emergence of the stars
            pop();
        } 
    }
    if(newExplod.length > 2){
        newExplod.shift();
    }
    pop();

    
}

function makeCamera(){
//coded by Steven
    camX = map(mouseX, 0, width, -width/2, width/2);//changing camera position x
    camY = map(mouseY, 0, height, -height/2, height/2);//changing camera position y
    camZ = height/2;//changing camera position z
    camera(camX, camY, camZ,0,0,0,1,1,0);//allow the viewport angle to change
}
//make object to create new stars
function makeNewStar(x, y, radius){
//coded by Mike
    var newstar = {x: x,
                    y: y,
                    r: radius,
                    updateStar: updateStar,
                    draw: drawNewStar};
    return newstar;
}

function makeNewExplo(x, y, radius){
//coded by Mike
    var newExplo = {x: x,
                    y: y,
                    r: radius,
                    updateExplo: updateExplo,
                    draw: drawNewExplo};
    return newExplo;
}

//function to draw new star
function drawNewStar(){
//coded by Mike
    var color1 = random(150, 255);
    var color2 = random(100,180);
    var color3 = random(100,200);
    var density = random(14,20);//allow different numbers of the spheres to appear on the star
    for(var i = 0; i < density; i++){
        var lengthValue = map(i, 0, density, -PI, PI); //set longitudinal value
        for(var j = 0; j< density; j++){
            var widthValue = map(j, 0, density, -PI/2, PI/2);// set horizontal value
            var pX = this.r * sin(lengthValue) * cos(widthValue);
            var pY = this.r * sin(lengthValue) * sin(widthValue);
            var pZ = this.r * cos(lengthValue);
            push();
            fill(color1, color2, color3);
            translate(pX, pY, pZ);
            sphere(1.6);
            pop();
        }
    }
}

function drawNewExplo(){
//coded by Mike
    var color4 = random(100, 255);
    var color5 = random(100,180);
    var color6 = random(100,200);
    var density = random(12, 15);//allow different numbers of the spheres to appear for the explosion
    for(var i = 0; i < density; i++){
        var lengthValue = map(i, 0, density, -PI, PI); //set longitudinal value
        for(var j = 0; j< density; j++){
            var widthValue = map(j, 0, density, -PI/2, PI/2);// set horizontal value
            var pX1 = this.r * sin(lengthValue) * cos(widthValue * 0.5) * 0.5;
            var pY1 = this.r * sin(lengthValue * 0.5) * sin(widthValue) * 0.5;
            var pZ1 = this.r * cos(lengthValue);
            push();
            fill(color4, color5, color6);
            translate(pX1, pY1, pZ1);
            box(2, 2, 2);
            pop();
        }
    }
}

function updateStar(){
//coded by Mike
    this.r += random(0.5,2);//allow the new star to expand
}

function updateExplo(){
//coded by Mike
    this.r += random(1,2);//allow the new explosion to expand
}


function mousePressed(){
//coded by Steven
    var newStarMaking = [];
    var newMouseXList = [];
    var newMouseYList = [];
    var newExploMaking = [];
    var newmouseXListEx = [];
    var newmouseYListEx = [];
    var clickEx;//check whether there is existing new stars
    var click;//check whether there is existing new stars
    
    if(mouseXList.length == 0){
        click = 0;
        newStarMaking.push(newStars[0]);
        newMouseXList.push(mouseXList[0]);
        newMouseYList.push(mouseYList[0]);
    }
    else{
        for(var l = 0; l < newStars.length; l++){
            var distance = dist(mouseX - width/3, mouseY - height/3, newStars[l].x, newStars[l].y);
            if(distance <= 30){
                click = 1;
            }else{
                click = 0;
                newStarMaking.push(newStars[l]);
                newMouseXList.push(mouseXList[l]);
                newMouseYList.push(mouseYList[l]);
            }
        }
        newStars = newStarMaking;
        mouseXList = newMouseXList;
        mouseYList = newMouseYList;
    }
    if(click == 0){
        mouseXList.push(mouseX - width/3);
        mouseYList.push(mouseY - width/3);
        var newStar = makeNewStar(mouseX - width/3, mouseY-width/3, 30);
        newStars.push(newStar);
    }

    //add value to empty list
    if(mouseXListEx.length == 0){
        clickEx = 0;
        newExploMaking.push(newExplod[0]);
        newmouseXListEx.push(mouseXListEx[0]);
        newmouseYListEx.push(mouseYListEx[0]);
    }
    else{
    //assign initiating position according to the mouse postion
        for(var w = 0; w < newExplod.length; w++){
            var distance = dist(mouseX - width/3, mouseY - height/3, newExplod[w].x, newExplod[w].y);
            if(distance <= 30){
                clickEx = 1;
            }else{
                clickEx = 0;
                newExploMaking.push(newExplod[w]);
                newmouseXListEx.push(mouseXListEx[w]);
                newmouseYListEx.push(mouseYListEx[w]);
            }
        }
        //assign values back to the list
        newExplod = newExploMaking;
        mouseXListEx = newmouseXListEx;
        mouseYListEx = newmouseYListEx;
    }
    //avoid invalid value
    if(clickEx == 0){
        mouseXListEx.push(mouseX - width/3);
        mouseYListEx.push(mouseY - width/3);
        var newExplo = makeNewExplo(mouseX - width/3, mouseY-width/3, 300);
        newExplod.push(newExplo);
    }
}


//function to make a center planet to have some understanding of the perspective
//coded by Mike
function centerCube(){
    //make sure the location of the center planet is always at the center of the canvas
    push();
    var locX = mouseX - height / 2;
    var locY = mouseY - width / 2;
    ambientLight(50);
    directionalLight(255, 0, 0, 0.25, 0.25, 0);
    pointLight(0, 0, 255, locX, locY, 250);
    ambientMaterial(100);
    strokeWeight(0.5);
    stroke(255);
    smooth();
    sphere(40);
    pop();
    //first ring surronding the planet
    push();
    rotateZ(frameCount * 0.01);
    rotateX(frameCount * 0.01);
    rotateY(frameCount * 0.01);
    strokeWeight(0.5);
    smooth();
    stroke(255);
    torus(60, 0.5);
    pop();
    //second ring surronding the planet
    push();
    rotateZ((100+ frameCount) * 0.01);
    rotateX((100 + frameCount) * 0.01);
    rotateY((100+ frameCount) * 0.01);
    smooth();
    strokeWeight(0.5);
    stroke(255);
    torus(70, 0.5);
    pop();
    //third ring surronding the planet
    push();
    rotateZ((200+ frameCount) * 0.01);
    rotateX((200 + frameCount) * 0.01);
    rotateY((200+ frameCount) * 0.01);
    smooth();
    strokeWeight(0.5);
    stroke(255);
    torus(80, 0.5);
    pop();
    //fourth ring surronding the planet
    push();
    rotateZ((300+ frameCount) * 0.01);
    rotateX((300 + frameCount) * 0.01);
    rotateY((300+ frameCount) * 0.01);
    smooth();
    strokeWeight(0.5);
    stroke(255);
    torus(90, 1);
    pop();
}
//function to make a earth adjacent to the center planet 
//coded by Mike
function makeearth(){
    push();
    translate(width / 2, height / 3, -150);
    rotateX(frameCount * 0.05);
    rotateY(frameCount * 0.05);
    texture(img);
    sphere(20);
    pop();
}

 

In this project, we aim to establish an interactive universe made possible by using the P5 3D geometry and 3D lighting. When you are hovering around in this universe, the stars and planets will move according to your mouse position. When you lower the mouse position, the screen will be zoomed out and when you higher the mouse, the screen will zoom in more.  When the mouse is pressed, new “stars” which look like the colorful spheres composed of smaller spheres with galaxy-like explosion will happen randomly on the screen and would expand further until they can be seen no more. However, once you click on the screen, you will be able to see them again. The small spheres are glowing on the background to have an interstellar appearance. The center spindle-like sphere and an “Earth” like sphere are created to give us a general understanding of what perspective we are looking at the canvas. 

Leave a Reply