Midterm Progess 1 : Yash

Concept & Vision

A Painting That Breathes
Most generative art announces itself by motion or glitch. This project moves the other way. It aims for quiet conviction, a hand painted lotus pond rendered in code that rewards patient looking. Water moves almost not at all, petals sway just enough to suggest breath, leaves hold rain in waxy cups.

The aesthetic is botanical realism not photorealism. Think of careful natural history study and Japanese ink observation. Every element is built with gradients, procedural noise, and layered compositing. Stems read cylindrical, leaves show radial veins in perspective, petals catch light and fade to pink. The goal is to invite the eye into believing the scene exists, not to fool it.

System Design

Architecture of the Garden
Rendering follows a strict depth order from background to foreground. The design uses layered abstraction

Layer 1 Ground
Perspective leaves lie behind everything. Foreshortened ellipses suggest a low water view.

Layer 2 Structure
Stems are quadratic Bezier curves shaded as cylindrical forms with node rings at internodes.

Layer 3 Flower
The lotus bloom is built from sepals and two petal layers with a central receptacle. Petals contain dense micro vein texture.

Layer 4 Water planned
A subtle water surface will use Perlin noise for displacement, specular highlights, and interaction ripples that distort reflections.

Core Functions
Five focused drawing functions keep the code compact. They draw leaves, stems, the assembled lotus, individual petals with micro veins, and sepals with tonal transition. A hybrid of p5 and Canvas2D enables Path2D clipping, radial gradients, and precise shadow compositing.

Interactivity Design planned
Interaction is minimal
Hover makes nearby petals lean inward as if breathed on
Click drops a ripple that spreads and shears the reflected scene

Variations and States
Seeded randomness creates variation in petal size, vein curvature, leaf edges, bloom scale, light angle, and water tone.

Current Progress

What Exists Now
A static 600 by 800 canvas renders a complete scene with three perspective leaves, a tall central bloom, and a smaller secondary bloom. The scene draws once with no animation loop, showing the visual vocabulary.

Key achievements include foreshortened leaf geometry with accurate vein placement, three pass cylindrical stem shading with sampled node rings, and petals rendered with ninety micro vein strokes and soft gradients. The hybrid canvas approach confines detail through save clip restore patterns.

Risk Identification & Mitigation

The Most Frightening Part
Animating a convincing water surface with coherent reflections is the largest risk. A single sine wave looks fake, and per pixel displacement at full resolution is expensive. The aesthetic risk is motion that reads as mechanical.

What I did to reduce this risk
I isolated a water proof of concept using two octave Perlin noise summed across horizontal strips. The approach proved tunable and performant. Reflections will be rendered to an off screen buffer and displaced with the same noise field. Interaction ripples will be an additive decaying sine term centered at the click point.

Looking Forward

The Next Passes
Integrate animated water and place botanicals above the water line. Add off screen reflection rendering, petal Perlin oscillation seeded by index, mouse proximity response, and click ripples. Final work will be patient tuning of motion and color until the scene reads as living.

Assignment 4 : Yash

Swinging Shadows: Simulating Harmonic Motion and Light

Concept & Inspiration

The initial idea for this sketch was born out of an interest in exploring simple harmonic motion and dynamic lighting. I wanted to create a scene that felt alive, where pendulums swing back and forth, casting real-time, infinite shadows over a central object.

While a pure top-down 2D view was the starting point, I quickly realized that squashing the arc of a pendulum into a straight line kills the illusion of gravity and momentum. To fix this, I shifted the frame of reference to a 2.5D isometric perspective. By pitching the camera down slightly, the vertical arc (the Z-axis height) of the pendulum becomes visible, allowing for suspension wires and a much more realistic sense of depth and physics.

The Sketch

Interact with the canvas below! Use the + and buttons to add or remove swinging lamps.

Code Highlight: The  Shadow Engine

Creating realistic lighting and shadows in the canvas without relying on heavy, resource-intensive raycasting is a fun challenge. Instead of standard lighting engines, I am particularly proud of the custom reverse-masking trick used here.

To keep the shadows perfectly sharp while maintaining the angled 2.5D perspective, the math temporarily stretches the angled coordinate space back into a perfect 2D circle, calculates the exact light tangents of the cylinder relative to the light source, and then squashes the coordinates back down to match the camera tilt. It then draws a polygon matching the background color to act as a stencil, creating perfect, infinite shadows.

// 3. Draw shadows cast by the lamps on the cylinder
  fill(bgColor); // Shadows act as a mask matching the background
  noStroke();
  
  for (let pos of currentPositions) {
    // Stretch the position mathematically to compensate for the 2.5D tilt
    let stretchY = cy + (pos.y - cy) / tilt;
    let stretchX = pos.x;
    
    let d = dist(cx, cy, stretchX, stretchY);
    
    if (d > cylinderRadius) {
      // Calculate exact tangent points on the stretched perfect circle
      let angleToCenter = atan2(stretchY - cy, stretchX - cx);
      let theta = asin(cylinderRadius / d); 
      
      let angle1 = angleToCenter + PI - theta;
      let angle2 = angleToCenter + PI + theta;

      let p1x = cx + cylinderRadius * cos(angle1);
      let p1y_circle = cy + cylinderRadius * sin(angle1);
      let p2x = cx + cylinderRadius * cos(angle2);
      let p2y_circle = cy + cylinderRadius * sin(angle2);

      // Squash the Y coordinates back down to match our tilted screen perspective
      let p1y = cy + (p1y_circle - cy) * tilt;
      let p2y = cy + (p2y_circle - cy) * tilt;

      // Project the shadow polygon far off the canvas
      let rayLength = max(width, height) * 2;
      let p3x = p1x + (p1x - pos.x) * rayLength;
      let p3y = p1y + (p1y - pos.y) * rayLength;
      let p4x = p2x + (p2x - pos.x) * rayLength;
      let p4y = p2y + (p2y - pos.y) * rayLength;

      // Draw the masking quad
      beginShape();
      vertex(p1x, p1y);
      vertex(p2x, p2y);
      vertex(p4x, p4y);
      vertex(p3x, p3y);
      endShape(CLOSE);
    }
  }

Milestones and Challenges

Milestone 1: Basic Pendulum Motion with Light Glow

The first major milestone was getting the pendulum physics working with a simple light effect. I started by implementing the basic sine wave motion for a single lamp and added a glowing effect using radial gradients. This helped me understand the core animation loop before adding complexity.

One challenge here was getting the light to look realistic. I had to experiment with diffrent opacity values and multiple gradient layers to achieve the soft glow effect.

Milestone 2: Adding the Cylinder and Shadow Projection

The biggest chalenge was implementing the shadow geometry. I needed to calculate the tangent lines from the lamp position to the cylinder edge, then project those shadows outward. This required understanding some trigonometry with atan2() and asin() to find the exact tangent points.

Getting the shadow to look correct from the tilted perspective was tricky. I had to “stretch” the lamp position back to a top-down view, calculate the tangents, then apply the tilt transform to the shadow vertices. After alot of trial and error with the math, it finaly worked!

Reflection & Future Work

Exploring how mathematical rules govern natural movement has been a recurring theme in my coding practice. Just as manipulating acceleration can simulate organic flocking behaviors, manipulating phase offsets and trigonometric tangents here brings mechanical pendulums to life. Shifting from a flat plane to a 2.5D environment was the biggest hurdle, but it completely transformed the visual weight of the project.

For future iterations, I would love to push the visual polish even further. Adding a subtle, fading particle trail behind the glowing bulbs could give the motion more visual history. Additionally, mapping the user’s mouse coordinates to the tilt variable would allow for dynamic camera control, letting users seamlessly fly the camera from a pure top-down view to a low, ground-level angle in real-time. Finally, integrating these canvas controls into a more robust, styled UI overlay would align it nicely with modern web design standards.

Assignment 3: Yash

Project Title: Window Pane Serenity

Concept

The concept for this project is grounded in the feeling of solitude and comfort sitting beside a window wall in a dimly lit room, watching a storm pass over a city at night. I wanted to capture the specific physical behavior of water on glass: how it sticks, slides, and merges.

Connecting this to the assignment task, I treated the raindrops as the primary movers. Instead of standard “bouncing balls,” these bodies obey a specific set of forces:

  • Gravity: The constant downward acceleration.

  • Turbulence: I utilized Perlin noise to simulate wind, pushing the drops slightly sideways to create organic, non-linear paths.

  • Attraction/Cohesion: The “attractor” element is implemented through the surface tension of water. When drops touch, they attract and merge into larger bodies.

  • Friction: This acts as a resisting force; drops below a certain mass (MIN_MASS_TO_SLIDE) are held in place by friction against the glass until they merge with another drop and become heavy enough to slide.

Visual Demo

Project Walkthrough:

Interactive Sketch:

Code Highlight

I am particularly proud of the drop merging logic. Implementing this was tricky because it required checking every drop against every other drop without crashing the performance. I also had to calculate the new size based on the combined area of the two circles to maintain realistic conservation of volume.

Additionally, managing the array was difficult here; I had to iterate backwards through the array to safely remove the “absorbed” drop without messing up the loop index.

// PHYSICS EFFECT 2: Drops merge when they touch each other
    // We iterate backwards to safely splice items out of the array
    for (let j = drops.length - 1; j >= 0; j--) {
      if (i !== j) { // Don't check a drop against itself
        let other = drops[j];
        let dist = p5.Vector.dist(d.pos, other.pos);
        
        // If drops are overlapping
        if (dist < d.r + other.r) {
          // Combine their areas (preserve total water volume)
          // Area = PI * r^2
          let newArea = (PI * d.r * d.r) + (PI * other.r * other.r);
          d.r = sqrt(newArea / PI); // Calculate new radius
          d.vel.y *= 0.9; // Slow down slightly due to mass increase/friction
          
          // Remove the absorbed drop from the simulation
          drops.splice(j, 1);
          if (j < i) i--; // Adjust index if we removed an item before the current one
        }
      }
    }

Milestones & Challenges

1. Layering the Visuals One of the biggest challenges was creating the “wet trail” effect behind the drops. Initially, I just drew semi-transparent rectangles over the background to fade the trails. However, this darkened the entire window, obscuring the moon and city layer I had drawn.

  • Solution: I implemented a createGraphics layer specifically for the trails. Instead of painting “black” to fade them, I used the erase() function. This allowed me to subtract the trails’ opacity over time, revealing the crisp city background underneath without darkening it.

2. Simulation Physics Getting the “sticky” feel of the rain was a milestone. At first, all drops fell at the same speed. Adding the MIN_MASS_TO_SLIDE logic changed the feel entirely—it allowed small drops to accumulate on the screen (creating a texture) until a larger drop swept them up, which felt much more realistic.

3. Atmospheric Depth I struggled to make the scene feel like a room rather than just a flat drawing. Adding the drawVignette() function with a loop of fading strokes helped create a sense of depth and focus, mimicking the way a human eye or camera lens focuses on the light source.

Reflection & Future Work

I am happy with how the mood translates. The combination of the dark interior colors and the bright drops creates a strong contrast. The physics successfully meet the assignment requirements by using turbulence and attraction to generate a constantly evolving design.

For future improvements:

  • Interaction: I would like to add a mouse interaction where the user can “wipe” the fog off the glass with their cursor.

  • Sound: Adding a rain loop and distant thunder would make the experience fully immersive.

  • Lighting: Currently, the drops are lit statically. It would be interesting if the drops refracted the light from the moon or the city below based on their position.

Assignment 2 : Yash

Code Production: The Physics of the Chase

Concept & Inspiration

For this assignment, I was tasked with finding an example of movement in nature and simulating it using code. I started by looking at how birds move in flocks. There is a specific fluidity to how they accelerate and glide that feels very different from mechanical movement.

I found this video of birds in flight which served as my primary visual reference:

https://www.youtube.com/watch?v=SCX946jtKXw

The Pivot

While watching the video, I realized that we almost always observe birds from the ground looking up. I wondered: How do birds see each other?

I decided to shift the perspective. Instead of a human watching a bird, I wanted to create a First-Person Flyer (FPF) experience. The concept became a “Bird Chase Simulation,” where the user plays as a predator bird (or perhaps a playful friend bird) trying to catch up to a leading bird.

My goal was to give the movement “personality” not just through the way the bird looks, but through how the acceleration feels. High acceleration shouldn’t just mean “go faster”, it should feel energetic and slightly chaotic, changing the bird’s perspective of the world.

Process

Before I could make it look like a bird, I had to make it move like one. The prompt required controlling motion only by manipulating acceleration.

I started with a greyboxing phase.  I created a relationship where the distance between the player and the target wasn’t represented by X/Y coordinates, but by the scale of the target. If you accelerate and get closer, the target gets bigger,if you stop flapping (drag), you fall back, and the target shrinks.

Here is a screen recording of that initial physics test:

 

The Code

The part of the code I am most proud of is the relationship between the Acceleration Input and the Camera Shake.

The prompt asked us to give the movement personality. I achieved this by making the “camera” (the viewport) physically shake when the user pushes the acceleration slider to the max. It simulates the physical exertion of flapping wings hard against the wind. It bridges the gap between the math (acceleration numbers) and the feeling (struggle/speed).

Here is the snippet that handles that logic:

// === PHYSICS SECTION ===
  let accVector = createVector(0, accInput);
  playerVel.add(accVector); 
  
  // === CAMERA SHAKE EFFECT ===
  // Add shake when accelerating hard (makes it feel more dynamic)
  let shakeX = 0;
  let shakeY = 0;
  
  // Only shake if we are putting in significant effort (> 0.05)
  if (accInput > 0.05) {
    // Map the shake intensity to the acceleration input
    let shakeAmt = map(accInput, 0, 0.5, 0.5, 6); 
    shakeX = random(-shakeAmt, shakeAmt);
    shakeY = random(-shakeAmt, shakeAmt);
  }

  // Later, in the drawing section:
  translate(width/2 + shakeX, height/2 + shakeY);

The Simulation

To finalize the piece, I added a circular clipping mask to create a “binocular” or “focus” effect, simulating the bird’s vision. I also added wind lines that react to the player’s speed to create a parallax effect, enhancing the sensation of forward momentum.

Instructions:

  1. Use the slider at the bottom to control your Acceleration (how hard you are flapping).

  2. Try to catch up to the bird in front of you.

  3. Notice how the view shakes and the wind rushes faster as you exert more energy.

Reflection & Future Work

This project was a great exercise in using simple variables (acceleration and scale) to create a 3D illusion. The hardest part was tuning the “drag” or air resistance. If the drag was too high, it felt like flying through soup; too low, and the bird felt like a rocket with no weight.

I’m happy with how the beak breathing animation and the camera shake added life to the static shapes.

For the future: Currently, the movement is linear (forward/backward). I would love to introduce steering, allowing the player to move left and right to chase the target bird as it weaves through the sky. I also think adding a Stamina bar would add a game-like element, forcing the player to choose when to glide and when to sprint.

Yash Raj – Assignment 1

Reading Response on Computational Beauty of Nature

 

I honestly used to think that biology and computer science were totally different worlds but reading the first chapter of The Computational Beauty of Nature really changed my perspective. The reading explains that usually science tries to understand things by breaking them down into tiny pieces like atoms or cells but that does not always tell you how the whole system works. It is super interesting to see that nature is actually a lot like the code we write because it uses simple rules and parallel processing to build complex things like ant colonies or even the human brain.

What really stuck with me is how this idea challenges the way I’ve been trained to think about problems. In computer science, I am used to focusing on algorithms, logic, and efficiency, while in biology I always assumed things were more descriptive and observational. This reading made me realize that both fields are actually asking the same question which is how do simple interactions give rise to complex behavior? Seeing natural systems as computational systems made biology feel much more relatable and even exciting to me, especially because it connects directly to ideas like emergence and self-organization that we also see in simulations and programs.

It changes how i look at the world when i realize that everything from a snowflake to the stock market is just processing information. It makes me wonder if we can actually simulate everything if we just find those basic rules. I wonder will we ever be able to write a program that perfectly copies nature or is there something random in the universe that we can never predict?

Personally, this question keeps bothering me the more I think about it. Part of me feels optimistic, like maybe with enough data, computing power, and better models, we could simulate almost anything. At the same time, I also feel that there might always be some level of unpredictability, whether it comes from randomness, chaos, or limits in our understanding. That uncertainty is what makes this topic so fascinating to me. Instead of seeing nature as something separate from computation, I now see it as the ultimate computational system something that we are still only beginning to understand.

Code Production

Concept

I wanted to make something that feels alive but simple. A leaf sits in the middle and a small caterpillar wanders on it. As it moves it eats away the leaf and the eaten parts turn white. The leaf slowly changes shades of green based on where the caterpillar is and how it moves. New leaves pop up nearby when you click so the scene keeps growing. I imagined the caterpillar as both a painter and a tiny critic of the leaf, leaving a trail that tells the story of its path. The motion mixes a random walker for direction with a gaussian walk for color so the visual change feels organic and a little surprising.

Why this feels right to me

I like the idea of a creature that only moves on a surface and changes that very surface while it moves. It gives a simple rule set but the result looks like a small life form making a mark. The interaction is gentle. A click resets and gives a new canvas so you can explore again. It feels playful and quiet at the same time.

Code highlight I am proud of

The most complex part of this sketch for me was designing the caterpillar movement so that it feels random but still intentional. I did not want it to just jitter around the screen. I wanted it to look like it is exploring the leaf but also aware of its boundaries.

To do this I created a random walker with dynamic probabilities. The caterpillar has two different states depending on where it is on the leaf. When it is close to the edge it is much more likely to turn back toward the center and only rarely continue forward. When it is in a safe area it mostly moves straight but sometimes turns left or right. This balance took time to get right because small changes in probability made the motion feel either too mechanical or too chaotic.

What makes this challenging is that the movement still remains random but it is guided by invisible rules. The caterpillar never explicitly checks for the leaf shape yet it almost always stays on it which makes the motion feel natural rather than scripted.

This logic is what gives the sketch its personality.

// Pick a new random target for the caterpillar to move towards
pickNewTarget() {
  let distanceFromCenter = dist(this.headPos.x, this.headPos.y, width/2, height/2);
  let stepSize = 15;
  let newAngle;

  let randomVal = random(1.0); 

  // If near edge, turn back towards center
  if (distanceFromCenter > 140) {
    let angleToCenter = atan2(height/2 - this.headPos.y, width/2 - this.headPos.x);
    
    if (randomVal < 0.95) {
      // Usually go towards center
      newAngle = angleToCenter + random(-0.5, 0.5); 
    } else {
      // Sometimes keep going
      newAngle = this.currentAngle; 
    }
    
  } else {
    // Normal foraging behavoir in safe zone
    if (randomVal < 0.70) {
      // Go straight most of the time
      newAngle = this.currentAngle + random(-0.3, 0.3);
    } else if (randomVal < 0.85) {
      // Turn left sometimes
      newAngle = this.currentAngle - random(0.5, 1.5);
    } else {
      // Turn right sometimes
      newAngle = this.currentAngle + random(0.5, 1.5);
    }
  }

  this.currentAngle = newAngle;

  // Calculate new target position
  let xStep = cos(newAngle) * stepSize;
  let yStep = sin(newAngle) * stepSize;
  this.target = createVector(this.headPos.x + xStep, this.headPos.y + yStep);
}
Embedded sketch

Reflection and ideas for future work
  1. Add more life like feel by giving the caterpillar inertia and a sense of rest when it eats too much. Maybe make it slow down after a long run.

  2. Try a self avoiding walk so the caterpillar learns to avoid recently visited areas and patterns will become more complex. This could make the eaten shapes more deliberate.

  3. Make the leaf grow back slowly so the scene becomes a cycle of eat and heal. That would make the sketch feel like a small ecosystem.

  4. Link sound to movement so each bite triggers a soft tone and the pitch depends on the distance from the center. Then the piece becomes both visual and sonic.

  5. Let multiple caterpillars share the leaf and give them simple rules for interaction. Sometimes they could follow each other and sometimes they could compete for space.