Midterm Progress

Inspiration

I grew up in a village without a park, a place where families, friends, and pets gather to enjoy nature and each other’s company. To experience the joy of a park, I had to travel to nearby villages or cities. This sparked my love for parks and inspired my midterm project: creating a virtual park. My goal is to recreate the sense of community and fun found in a park, from children playing on swings to people walking their dogs and old friends catching up. This project is my way of bringing the park experience to those who, like me, have always admired it from afar.

Concept

Building on the foundational inspiration, the core idea of my midterm project is to craft an immersive user experience that mimics the tranquility and community feel of a real park. To achieve this, I’ve begun by setting up a serene background image that serves as the canvas for the park’s life. Central to the scene are two swings, each with a figure that moves in harmony with the swing’s motion. To ensure these movements are as natural as possible, I’ve implemented the lerp() function, which allows for smooth transitions and adds a lifelike quality to the animations.

Adding another layer of interaction to the park, I’ve introduced a jukebox feature. This allows users to engage with the environment actively by selecting and controlling the music to suit their mood, enhancing the personal experience of the park. While the music feature is currently in development, with plans to enable song changes and stops, it promises to be a significant aspect of user engagement.

Looking ahead, I plan to enrich the park’s atmosphere with spritesheets for various people movements, creating a dynamic and bustling park scene. This will include groups of people sitting on the grass or on carpets, adding to the communal vibe. Additionally, to further the immersion, I intend to incorporate ambient sounds, such as birds chirping, which will be a constant backdrop to the park experience, not subject to user control. This sound layer aims to deepen the user’s connection with the virtual environment, making it feel alive and vibrant. Moreover, diversifying the playground equipment, especially with different swings, will offer a variety of interactions for the user, simulating the choice and freedom one finds in a real park. This expansion not only adds visual appeal but also invites users to explore and find their favorite corner of the virtual park.

Challenging Aspects

Drawing Complexities: The first significant challenge is the detailed drawing of park structures and objects using p5.js. Every element, from swings to human-structure, requires time-consuming manual drawing. This process demands a high level of precision and artistic skill to ensure the park’s visual appeal and thematic consistency.

Interactive Features: Introducing interactivity, such as clickable buttons and objects that respond to mouse hover, adds another layer of complexity. For example, making the jukebox highlight when hovered over involves sophisticated input detection and dynamic response coding, enhancing user engagement but also increasing development complexity.

Animating Characters with Spritesheet: Utilizing spritesheets for character movement presents a formidable challenge. Ensuring these animated figures navigate the park without colliding with objects or wandering off the grass involves intricate collision detection and boundary management.

References:

https://www.youtube.com/watch?v=8uLVnM36XUc

Week 4-Assignment

CONCEPT:
In this assignment, my primary objective was to visualize data pertaining to different types of energy consumption spanning from 1900 to 2018. Given the diverse nature of energy sources and their consumption patterns, I decided to employ a line graph as the mode of visualization. However, due to the multitude of energy types and their varying magnitudes of consumption, presenting them all on a single graph would result in a cluttered and incomprehensible visualization. To address this issue, I opted to implement a dropdown menu using the createSelect() function. This feature allows users to select a specific energy type, and subsequently, the graph updates dynamically to display the consumption trend exclusively for the chosen energy source.

One of the prominent challenges encountered during the implementation phase was the disparate scales of energy consumption among different energy types. Some energy sources exhibited significantly higher consumption values compared to others. Consequently, if a uniform y-axis scale were to be applied across all energy types, it would lead to visual distortions, making the graph incomprehensible. To mitigate this challenge, I implemented a dynamic scaling mechanism. This involved calculating the maximum consumption value for the selected energy type and mapping the y-axis scale accordingly. By dynamically adjusting the scale based on the maximum consumption value of each energy type, the visualization maintains clarity and accuracy across all displayed data points.

My favorite part of the code is processData(). It extracts and organizes data for visualization. It initializes empty arrays xValues and yValues, then loops through each row of the dataset. It extracts year and energy consumption values based on the selected energy, storing them in the arrays. This function ensures accurate representation of energy consumption trends.

REFLECTIONS:
Completing this assignment was definitely challenging, but I persisted by referring to the p5.js documentation whenever I encountered difficulties. This helped me understand how to use different functions and techniques to achieve my goals. I also attempted to enhance the visualization by incorporating a background picture, but encountered some issues with how it interacted with other visual elements. I’m eager to continue exploring this project further. I see a lot of potential for adding more interactive elements to make the visualization even more engaging and informative.

Reading Response Week 4

After delving into the first chapter of Don Norman’s “The Design of Everyday Things,” I find myself resonating deeply with his emphasis on the significance of understanding human behavior and psychology in design. Norman’s argument about the importance of putting ourselves in the shoes of users resonates with my own approach to design. I firmly believe that creating anything without considering the end user’s perspective is futile. Design should always prioritize usability and functionality to ensure a seamless interaction between users, systems, and designers.

Norman’s discussion on the paradox of technology also caught my attention, particularly his insight into how experiences shape users’ perceptions of interactions. It serves as a reminder that even the most aesthetically pleasing designs must prioritize functionality and user experience above all else. This resonates with me as I reflect on instances where overly complex features have hindered rather than enhanced my experience with products.

Moreover, Norman’s critique challenges the prevailing notion that more features equate to better functionality. It prompts me to reconsider what truly defines a good design and the balance between form, complexity, simplicity, and functionality. As I continue to contemplate Norman’s insights, I aim to adopt a dual perspective—as both a user and a designer—to ensure that my designs are not only visually appealing but also intuitive and user-friendly. Norman’s work serves as a valuable guide for navigating the complexities of design and human interaction, prompting me to strive for designs that enhance users’ lives without adding unnecessary complexity.

Assignment 3

Concept

For this project, the goal was to apply the concepts learned in class, including loops, arrays, and Object-Oriented Programming (OOP), to create an interactive visual experience.  The initial goal was to create a dynamic piece where a single spiral would be generated with each mouse click. However, I wanted to enhance user engagement by adding a feature that allows spirals to change color when clicked inside. So, I decided to use mouseDragged function to generate spirals and mouseClicked for spirals to change colour. Therefore, the application now produces multiple spirals during a single drag action across the screen. Furthermore, if a spiral is clicked, it temporarily changes color before reverting to its original hue.

To make the application more visually appealing, I attempted to introduce a feature where waves are generated whenever two spirals collide. I added a trailing effect to these waves, aiming to create a mesmerizing interaction between the spirals and the waves produced. Additionally, I implemented a functionality to clear the screen by pressing the ‘c’ key, allowing users to reset the canvas and start anew.

Sample

Embedded Canvas

Drag your mouse and see the magic.

Code

let spirals = [];

function setup() {
  createCanvas(800, 800);
  background(0);
}

function draw() {
  background(0, 25); // Semi-transparent background for a trail effect
  for (let i = 0; i < spirals.length; i++) {
    spirals[i].update();
    spirals[i].display();
    // Check for collision with other spirals
    for (let j = i + 1; j < spirals.length; j++) {
      if (spirals[i].collidesWith(spirals[j])) {
        createWaveBetween(spirals[i], spirals[j]);
      }
    }
  }
}

function mouseDragged() {
  let newSpiral = new Spiral(mouseX, mouseY);
  spirals.push(newSpiral);
}

// Function to chnage colour of the spiral after mouse ci clicked inside the spiral
function mouseClicked() {
  for (let i = 0; i < spirals.length; i++) {
    if (dist(mouseX, mouseY, spirals[i].pos.x, spirals[i].pos.y) < spirals[i].radius) {
      spirals[i].transform();
     
    }
  }
}

class Spiral {
  constructor(x, y) {
    this.pos = createVector(x, y);
    this.radius = random(5, 20);
    this.angle = 60;
    this.color = color(random(255), random(255), random(255), 100);
    this.transformed = false;
  }
  
  update() {
    this.angle += 0.05;
    this.radius += 0.5;
  }
  
  display() {
// Itsaves the current drawing style settings and transformations applied to the canvas
    push();
//   moves the origin to the position of the spiral
    translate(this.pos.x, this.pos.y);
    stroke(this.color);
    noFill();
    beginShape();
    for (let i = 0; i < this.angle; i += 0.1) {
//  Calculate the x and y coordinates of each vertex of the spiral
      let x = this.radius * cos(i);
      let y = this.radius * sin(i);
//  This function adds a vertex to the shape of the spiral
      vertex(x, y);
    }
    endShape();
    pop();
  }

  transform() {
    this.transformed = true;
    this.color = color(random(255), random(255), random(255), 100);
  }

  collidesWith(other) {
    let d = dist(this.pos.x, this.pos.y, other.pos.x, other.pos.y);
    return d < this.radius + other.radius;
  }
}

function createWaveBetween(spiral1, spiral2) {
// Calculates the start and end points of the line connecting the centers of the two spirals
  let startX = spiral1.pos.x + spiral1.radius * cos(spiral1.angle);
  let startY = spiral1.pos.y + spiral1.radius * sin(spiral1.angle);
  let endX = spiral2.pos.x + spiral2.radius * cos(spiral2.angle);
  let endY = spiral2.pos.y + spiral2.radius * sin(spiral2.angle);
  
  let wave = new HorizontalWave(startX, startY, endX, endY);
  wave.display();
}

class HorizontalWave {
  constructor(x1, y1, x2, y2) {
    this.start = createVector(x1, y1);
    this.end = createVector(x2, y2);
    this.amplitude = 20;
    this.frequency = 0.1;
    this.color = color(255);
  }
  
  display() {
    push();
    stroke(this.color);
    noFill();
    beginShape();
    for (let x = this.start.x; x < this.end.x; x += 5) {
      let y = this.start.y + this.amplitude * sin(this.frequency * x);
      vertex(x, y);
    }
    endShape();
// This function restores the drawing state that was saved with the most recent 
    pop();
  }
}

Challenges & Reflections:

One of the significant challenges I encountered was the implementation of the wave generation when two spirals collide. The vision was to have the spirals transform into waves upon collision, with the spirals disappearing and the waves remaining on screen. However, I faced difficulties in realizing this feature due to my current level of understanding and technical limitations. This project has not only been a fun exploration of interactive graphics but also a valuable learning opportunity. I look forward to revisiting this project in the future, armed with more knowledge and experience, to incorporate the envisioned features and further enhance its interactivity and visual appeal.

References:

E. J. C. (2021, February 17). Excel – Adding and Graphing Sine Waves with Any Amplitude or Phase. YouTube. https://www.youtube.com/watch?v=2SdAtjoYEXo

Week 4 Reading Response

Chris Crawford’s elucidation on interactivity, particularly his analogy of it as a conversation between users and systems, introduces a profound reevaluation of our engagement with digital interfaces. This perspective challenges the traditional view of interactivity as mere binary exchanges—inputs and outputs—by imbuing it with a relational, almost human-like quality. The notion that interactivity could harbor the depth and dynamism of a conversation compels us to reconsider the essence of our digital interactions. It suggests that these exchanges are not just about the transmission of information but about building a relationship, a dialogue that evolves with each interaction.

However, while Crawford’s analogy enriches our understanding of interactivity, it also raises several questions about its applicability in the real world. The portrayal of interactivity as a seamless conversation glosses over the inherent complexities and frictions present in human-computer interaction. Real-world interactivity is fraught with misunderstandings, misinterpretations, and a lack of feedback that can disrupt the ideal flow of conversation Crawford imagines. This discrepancy between the ideal and the real prompts a deeper inquiry into how we can design interactive systems that truly embody the conversational model Crawford proposes. Can systems be designed to understand and adapt to the nuanced feedback of users? How do we account for the diverse ways individuals interact with technology?

Moreover, Crawford’s perspective invites us to explore the ethical dimensions of designing interactive systems. If we conceive of interactivity as a conversation, then we must also consider the responsibilities inherent in facilitating these dialogues. How do we ensure that these conversations are inclusive, respectful, and enriching for all participants? In what ways might our interactive systems impose upon, rather than enhance, the autonomy of users?

In reflecting on Crawford’s work, I am both intrigued and skeptical. His vision for interactivity as a conversation between users and systems offers a compelling framework for understanding and enhancing our digital interactions. Yet, it also underscores the need for a critical examination of the assumptions underlying this analogy and the practical challenges of implementing it. As we continue to navigate the evolving landscape of interactive design, Crawford’s insights serve as both inspiration and provocation, urging us to think more deeply about the nature of our digital conversations and the worlds they create.

Reading Response Week-3

Watching Casey Reas at Eyeo2012 unfold the layers of complexity within generative art, particularly through the lens of randomness, was a revelation that challenged my preconceived notions about the nature of creativity and the binary between order and chaos. His discourse on the implementation of randomness to generate art that is ever-evolving and unique each time it’s created stirred a deep curiosity in me about the essence of creativity itself. Is creativity a structured process governed by predefined rules, or does it thrive in the absence of constraints, propelled by the unpredictable forces of randomness?

The aspect that struck me most was the paradox of controlled randomness. The idea that an artist can set parameters within which randomness operates, guiding chaos towards a form of order, resonates with me on a philosophical level. It prompts a reflection on how much of our lives are governed by the illusion of control. We navigate through our existence setting boundaries, creating rules, and forming patterns, yet the most profound moments often arise from the unexpected, from the serendipitous collisions of chance.

Reas’s exploration of randomness as a tool for artistic creation also led me to ponder the intrinsic nature of human perception. How does the introduction of randomness affect our interpretation of art? The concept that a single piece of generative art can evoke a myriad of interpretations based on the viewer’s personal experiences and biases underscores the subjective nature of art and perception. It’s fascinating to consider that what we see in a piece of art is not just a reflection of the artist’s intent but a mirror of our own psyche, shaped by the random accumulation of our life experiences.

Moreover, the dialogue between order and chaos, as presented by Reas, challenges the traditional boundaries of art. It suggests that beauty and meaning can emerge from the most unexpected places, blurring the lines between the deliberate and the accidental. This approach to creating art not only expands the artistic lexicon but also offers a metaphor for embracing the unpredictability of life itself. It’s a reminder that amidst the chaos of existence, there are patterns, rhythms, and a form of order that we might not understand yet but can appreciate for their aesthetic and existential significance.

Casey Reas’s talk was a profound journey into the heart of what it means to create and perceive art in the digital age. It was a call to embrace the unpredictable, to find beauty in the randomness, and to reconsider our notions of order and chaos. This exploration has ignited a desire in me to delve deeper into the realm of generative art, to understand not just the mechanics but the philosophy behind using randomness as a medium for creativity.

Assignment 2

For this assignment, our task was to create a simple artwork using loops and our knowledge from previous classes.

My approach began with crafting an array of circles. Initially, I programmed the display of 10 circles at random locations on the screen. However, to add an interactive element, I modified the code so that numerous circles would appear with each mouse click.

The circles are endowed with distinct properties like colors, speeds, and diameters. I achieved this by employing a random function that assigns different values randomly. This randomness adds variety, ensuring each circle appears unique with its own color, speed, and diameter, enhancing the overall visual appeal of the artwork.

To bring these circles to life, I employed a for loop to create and animate them. I made sure they stayed within the designated canvas space by setting limits on their movement preventing them from disappearing off-screen.

As the artwork evolved, I noticed that the screen became somewhat cluttered after multiple attempts by a user to create circles. To address this, I introduced an option allowing users to clear the screen by pressing the ‘c’ key. This feature enabled users to start afresh without needing to manually restart the entire program.

// Declares a variable and initializes it as an empty array
let circles = [];

function setup() {
  createCanvas(600, 600);
}

function draw() {
  background(220);

  // generate circles on mouse click
  if (mouseIsPressed) {
//   create a circle 
    let newCircle = {
      x: mouseX,
      y: mouseY,
      diameter: random(10, 50),
      speedX: random(-2, 2),
      speedY: random(-2, 2),
      // Generate random color
      r: random(255),
      g: random(255),
      b: random(255)
    };
    // Newly created circle object is added to the circles array
    circles.push(newCircle);
  }

  // This for loop iterates over each circle object stored in the circles array and updates its position
  for (let i = 0; i < circles.length; i++) {
    circles[i].x += circles[i].speedX;
    circles[i].y += circles[i].speedY;

    // Bounce off walls
    if (circles[i].x <= 0 || circles[i].x >= width) {
      circles[i].speedX *= -1;
    }
    if (circles[i].y <= 0 || circles[i].y >= height) {
      circles[i].speedY *= -1;
    }

    // Set fill color
    fill(circles[i].r, circles[i].g, circles[i].b);
    // Draw circle
    ellipse(circles[i].x, circles[i].y, circles[i].diameter);
  }
}

function keyPressed() {
  // Clear the circles array when the 'c' key is pressed
  if (key === 'c' || key === 'C') {
    circles = [];
  }
}

Reflections:

I thoroughly enjoyed working on this project, drawing mainly from the knowledge acquired in class. However, I felt compelled to explore further, leading me to incorporate an additional function into the code. This experience not only allowed me to apply class learnings but also pushed me to expand my understanding. Moving forward, I am excited about the possibility of engaging with more advanced projects, leveraging a broader knowledge base to enhance my skills.

Assignment1- Self Portrait

When I first heard about creating a self-portrait, my mind immediately gravitated towards something that truly defines me – cricket. As someone deeply passionate about the sport, I couldn’t think of a better way to portray myself than through a project that encapsulates the essence of my love for cricket.

In this self-portrait, I envisioned a scene where a girl, embodying my presence, stands proudly with a cricket bat in her hands. The cricket ball, symbolizing the constant motion and dynamism of the game, is placed on the ground, perpetually moving. To add an interactive element, I incorporated the ability for the ball to jump when the user presses the mouse. The subtle details matter, and in this digital representation of myself, the girl periodically opens and closes her eyes every two seconds.

Code:

// Initializing the variables

let ballX = 220;
let ballY = 525;
let ballSpeedX = 1; 
let ballSpeedY = 0; 
let isJumping = false;
let jumpHeight = 100; 
let eyeColor = '#FFFFFF'; 
let pupilcolour = '#E4DDDD';

function setup() {
  createCanvas(600, 550);
}


function draw(){
  background(200);
// sky
  fill("#E5F7FA");
// gorund
  rect(0,0,599,450);
  fill("rgb(21,144,21)");

  rect(0,442,599,600);
  noStroke();
  fill("#C3ECF1")
// clouds
  circle(70,70,50);
  circle(90,60,50);
  circle(110,55,50);
  circle(130,70,50);
  
  circle(300,100,50);
  circle(320,90,50);
  circle(340,85,50);
  circle(360,100,50);
  
  //   Thumbs of both the hands
  
  fill('#E8BEAC')
  ellipse(263,255,8,20);
  ellipse(504,231,8,15);
  
  
//   bat
  fill('#C29C65')
  ellipse(157,266,10,25);
  // cylinder(20, 50);
  rect(160,255,180,22);
  quad(317,256,326,241,326,288,317,276);
  rect(326,241,250,46);
  ellipse(575,260,20,55)
  stroke('#D5B78B')
  strokeWeight(3);
  quad(327,234,326,241,575,243,573,234)
  
//   face 
  noStroke();
  fill('#252423')
  ellipse(390,200,100,110);
  ellipse(410,200,100,110);
  
  fill('#E8BEAC')
  ellipse(400,200,95,105);
  
  // print(mouseX+ ","+ mouseY);
//   halmet
  rect(389,245,25,40)
  
// hair and head
  fill('#252423')
  arc(400, 190, 100, 100, PI, 0);
  
//   hair
  stroke(50);
  strokeWeight(2);
  line(360,166,360,189);
  line(366,166,366,189);
  line(372,166,372,189);
  line(380,166,380,189);
  line(386,166,386,189);
  line(392,166,392,189);
  line(400,166,400,189);
  line(406,166,406,189);
  line(412,166,412,189);
  line(418,166,418,189);
  line(424,166,424,189);
  line(430,166,430,189);
  line(436,166,436,189);
  line(442,166,442,189);
  
  // eyes
  if (frameCount % 120 == 0) { 
    eyeColor = (eyeColor === '#FFFFFF') ? '#000000' : '#FFFFFF'; 
   
  }
  if (frameCount % 120 == 0) { 

    pupilcolour=(pupilcolour === '#E4DDDD') ? '#000000' : '#E4DDDDF'; 
  }
  fill(eyeColor);
  circle(377, 195, 15); 
  circle(422, 195, 15); 
  fill(pupilcolour); 
  circle(377, 195, 5); 
  circle(422, 195, 5); 
//   lips
  noStroke(197,55,80);
  fill('rgb(228,10,48)')
  arc(400,223,30,15,0,PI)
  
//   body
  // rect(348,270,110,150);
  
  quad(388,270,344,276,458,276,415,270);
  rect(350,276,105,120);
//   left arm
  
  quad(350,274,350,309,287,330,287,300);
  quad(287,300,287,330, 232,279,260,278);
  
//   right aarm
  quad(455,277,455,308,515,330,510,302);
  quad(505,302,512,286,534,286,515,331);
  
//   skirt
  fill('#721781')
  quad(350,396,350,506,455,506,455,396);
  
  // fill('black')
  // arc(350, 396, 50, 200, 0, PI + QUARTER_PI, CHORD);
  // arc(350, 396,50, 100,  0, PI + QUARTER_PI, PIE);
  ellipse(350, 450,30,110);
  ellipse(454, 450,30,110);
  // ellipse(403, 490,115,30);
  ellipse(403, 400,115,30);
  fill('#E8BEAC')
  quad(359,505,368,550,397,550,390,505);
  quad(415,505,415,550,444,550,445,505);
  
//   fingers
  quad(264,282,269,277,224,277,239,286);
  // ellipse(263,255,8,20);
  quad(262,245,251,254,253,261,262,253);
  ellipse(252,257,7,7);
  rect(244,246,7,20);
  ellipse(247.5,266,7,7);
  ellipse(247.5,245,7,7);
  quad(247,241,260,247,253,253,249,248);
  rect(236,248,7,20);
  ellipse(239.5,249,7,7);
  ellipse(239.5,269,7,7);
  rect(228,249,7,18);
  ellipse(231.5,251,7,7);
  ellipse(231.5,267,7,7);
  rect(220,251,6,15);
  ellipse(223,254,7,7);
  ellipse(223,264,7,7);
  
  // right hand fingers
  rect(532,228,6,15);
  ellipse(535,228,6,6);
  ellipse(535,242,6,6);
  rect(524,227,6,20);
  ellipse(527,229,7,7);
  ellipse(527,247,7,7);
  rect(516,224,6,25);
  ellipse(519,225,7,7);
  ellipse(519,247,7,7);
  
  rect(509,220,6,25);
  ellipse(512,223,7,7);
  ellipse(512,246,7,7);
  
  quad(221,259,221,249,248,249,248,241);
  
  quad(536,226,535,235,512,230,512,220);
  
 // Check if mouse is pressed
  if (mouseIsPressed && !isJumping) {
    isJumping = true;
    ballSpeedY = -5; 
  }

  // Move the ball
  ballX += ballSpeedX;
  ballY += ballSpeedY;

  // apply gravity if not jumping
  if (!mouseIsPressed && ballY < 525) {
    ballSpeedY += 0.5; 
  } else if (ballY >= 525) {
    ballY = 525; 
    ballSpeedY = 0;
    isJumping = false;
  }

 
  if (ballX + 25 >= width || ballX - 25 <= 0) { 
    ballSpeedX *= -1; 
  }

  // Ball
  fill('#FFEB3B');
  circle(constrain(ballX, 25, width - 25), ballY, 50); 
  fill('#E91E63');
  ellipse(constrain(ballX, 25, width - 25), ballY, 20, 50);
  ellipse(constrain(ballX, 25, width - 25), ballY, 50, 20);
  
}

Reflection:

Despite my numerous attempts, the eye pupil stubbornly refuses to close along with the eyelids, leaving the eyes in a perpetual state of openness. I’m determined to address this issue and make the portrait more interactive by achieving a natural blink.

As I work through these challenges, I’ve developed a deep fondness for the project. The blend of my love for cricket and the creative process has made it a personal journey. Honestly, I find myself reluctant to see this assignment come to an end. The joy of refining and perfecting this interactive self-portrait has made it a labor of love, and I’m eager to continue the journey beyond the assigned timeframe.