Simulation Project


Screenshot 2025-03-20 at 4.34.10 PM.png

<aside>

A very normal weather simulator

Weather Code

Real link to project 👇

http://147.182.212.82:3000/

Summary

This is just a classic weather simulator that fetches a random city and reports its real-time weather worldwide.

</aside>

<aside>

Process

Reuse and Design Particles

</aside>

<aside>

async function fetchData() {
    try {
      const data = await getCityWeather(city);
      console.log('Data:', data); 
      currWeather=data.currWeather;
      precip_mm = data.data.current.precip_mm;
      time=data.data.location.localtime;
      isDay=data.data.current.is_day;
      windSpeed = data.data.current.wind_kph; 
      windDirection = data.data.current.wind_degree; 

      inputText = createInput(city);
      inputText.id("textA");
      inputText.position(0, 0);
      inputText.size(width , height / 8);

      weatherButton = createButton(currWeather);
      weatherButton.id("weatherButton")
      weatherButton .position(0, 0);
      weatherButton .size(width , height / 8);
      getWeather();
    } catch (error) {
      console.error('Error:', error);
    }
  }

</aside>

<aside>

Inspiration

offSpace

image.png

Code references:

NOC - Classes, forces and drawing shapes by lac567 -p5.js Web Editor

CC 27: Fireworks by codingtrain -p5.js Web Editor

https://p5js.org/reference/#/p5/width

https://natureofcode.com/forces/

https://natureofcode.com/oscillation/

https://github.com/alterebro/p5.fillGradient

</aside>

<aside>

Next steps

  1. add sound effects
  2. add scenery (trees)
  3. abandon API (cuz it is on free trial)
  4. just use some historical data to find how a weather transits into another
  5. see if I can also simulate the study space in
  6. see if I can also turn existing numerical measurements 👉 ratio measurement
  rect(0, 0, 100, 650); //=> rect(0, 0, window.left, window.bottom);
  rect(700, 0, 98, 650);  //=> rect(window.left+window.w, 0, window.left-2, window.bottom);

</aside>

Screenshot 2025-03-13 at 7.28.30 PM.png

<aside>

loopAround() {
    let widths = this.boundX - this.minX; 
    let heights = this.boundY - this.minY; 

    if (this.position.x < this.minX) {
      this.position.x += widths;
      this.time==0;
    }
    if (this.position.x > this.boundX) {
      this.position.x -= widths;
      this.time==0;
    }
    if (this.position.y < this.minY){
      this.position.y += heights;
      this.time==0;
    } 
    if (this.position.y > this.boundY){
      this.position.y -= heights;
      this.time==0;
    } 
    
}
makeItSplash(){
  this.gravity=createVector(0,0.5);

  if (this.position.x < this.minX || this.position.x > this.boundX || this.position.y < this.minY || this.position.y > this.boundY){
    for(let i=0;i<movers.length;i++){
      if(this==movers[i]){
        movers.splice(i,1);
        break;
      }
    }
  }
}
comeBack(strength = 0.1, frame = 0) {
    let [left, right, top, bottom] = [this.minX + frame, this.boundX - frame, this.minY + frame, this.boundY - frame];

    if (this.position.x < left) this.velocity.add((left - this.position.x) * strength, 0);
    if (this.position.x > right) this.velocity.add((right - this.position.x) * strength, 0);
    if (this.position.y < top) this.velocity.add(0, (top - this.position.y) * strength);
    if (this.position.y > bottom) this.velocity.add(0, (bottom - this.position.y) * strength);
  }
bouncedBack() {
    let gain = abs(randomGaussian(0, 1));
    let x = this.position.x;
    let y = this.position.y;
    let radius = this.radius;
    if (x < radius || x > width - radius) this.velocity.x *= -gain;
    if (y < radius || y > height - radius) this.velocity.y *= -gain;
    this.position.x = constrain(x, radius, width - radius);
    this.position.y = constrain(y, radius, height - radius);
  }

</aside>

Weather - Cloud/Rain/Snow


image.png

Screenshot 2025-03-20 at 5.44.39 PM.png

Screenshot 2025-03-20 at 6.05.11 PM.png

Screenshot 2025-03-20 at 6.05.48 PM.png

function showCloud(){
  gfx1.loadPixels();

  if(tt>=10){
    tt-=0.01;
  }else if(t<=0){
    tt+=0.01;
  }

  for (let x = 0; x < gfx1.width; x++) {
    
      for (let y = 0; y < gfx1.height; y++) {
        let index = (x + y * gfx1.width) * 4;
        let bright = noise(x * 0.004+xoff1, y * 0.004+yoff1,t) * 255;
        gfx1.pixels[index] = bright;
        gfx1.pixels[index + 1] = bright;
        gfx1.pixels[index + 2] = bright;

        if(bright<100){
          gfx1.pixels[index + 3] = 0;  
        }else if(bright<110){
          gfx1.pixels[index + 3] = 10;  
        }else if(bright<180){
          gfx1.pixels[index + 3] = bright-150;  
        }else if(bright>255-t){
          gfx1.pixels[index + 3] = 255;  
        }else{
          gfx1.pixels[index + 3] = bright*2-y/removeScale;  
        }
        
        
      }
      xoff1 += randomGaussian(0,0.001);
      yoff1 += randomGaussian(0,0.001);
  }

  gfx1.updatePixels();
  gfx1.filter(BLUR,1.5);
  image(gfx1, 100, 100); 

}

image.png

Screenshot 2025-03-20 at 6.39.42 PM.png

Screenshot 2025-03-20 at 5.46.28 PM.png

Screenshot 2025-03-20 at 4.34.10 PM.png

function generateRain() {
  console.log("now raining!")
  let bound1 = { minX: 100, minY: 150, maxX: 700, maxY: 550 };
  makeParticles(bound1, "rain-shift", precip_mm*20+100, noiseScale, baseColor);
  
}
function makeParticles(bound, type, num, noiseScale, baseColor) {

//above function

if (type == "rain-shift") {
    for (let p of points) {
      let weight = random(0.1, 1);
      let h = randomGaussian(50, 10);
      let vel = createVector(
        0,
        abs(randomGaussian(10, 2)) * weight
      );
      movers.push(
        new Mover(
          "rain",
          bound,
          p,
          1,
          h,
          weight,
          vel,
          "loop",
          baseColor,
          drawRect
        )
      );
    }
console.log("sucessfully rain!")
  }
  
 }
  

  addComponents(){
    if(this.weather=="rain" && this.position.y>=this.boundY-5){
      this.time ++;
      this.addRainDrops(int(abs(randomGaussian(3,1))));
      // console.log("raindrops added!")
    }
  }
addRainDrops(num){
    let bound = { minX: 105, minY: 400, maxX: 695, maxY: 590 };
    for (let i=0;i<num;i++) {
      let p = createVector(this.position.x,570);
      let weight = random(0.1, 1);
      let vel = createVector(
        randomGaussian(0, 3),
        -1*abs(randomGaussian(3, 1)) * weight
      );
      movers.push(
        new Mover(
          "rain-drops",
          bound,
          p,
          null,
          null,
          weight,
          vel,
          "splash",
          baseColor,
          drawParticle
        )
      );
    }

image.png

Screenshot 2025-03-20 at 6.02.43 PM.png

Screenshot 2025-03-20 at 5.53.35 PM.png

Screenshot 2025-03-20 at 5.55.01 PM.png

function generateSnow() {
  console.log("now snowing!")
  let bound1 = { minX: 110, minY: 110, maxX: 690, maxY: 580 };
  makeParticles(bound1, "snow", 200, noiseScale, "white");
  let bound2 = { minX: 110, minY: 110, maxX: 690, maxY: 590 };
  makeParticles(bound2, "snow-shift", precip_mm*20+100, noiseScale, "white");
}
function makeParticles(bound, type, num, noiseScale, baseColor) {
	  if (type == "snow") {
    for (let p of points) {
      let weight = random(0.1, 1);
      let vel = createVector(
        randomGaussian(0, 0.2),
        abs(randomGaussian(7, 2)) * weight
      );
      movers.push(
        new Mover(
          "snow",
          bound,
          p,
          null,
          null,
          weight,
          vel,
          "stop",
          baseColor,
          drawCircle
        )
      );
    }
  }
  if (type == "snow-shift") {
    for (let p of points) {
      let weight = random(0.1, 1);
      let vel = createVector(
        randomGaussian(0, 1),
        abs(randomGaussian(7, 2)) * weight
      );
      movers.push(
        new Mover(
          "snow-shift",
          bound,
          p,
          null,
          null,
          weight,
          vel,
          "loop",
          baseColor,
          drawCircle
        )
      );
    }
  }
}

Weather - Wind/Thunder/Light