Week 5 – Reading Response

The webpage on Flong.com, “Computer Vision for Artists and Designers: Pedagogic Tools and Techniques for Novice Programmers”, explores techniques of computer visions for artists and programmers. Computer vision varies from human vision in many aspects. Computers can be more sensitive to light of different wavelengths (like infrared), something which isn’t possible in humans. It can also be trained to process images and recognise patterns. However, a computer doesn’t have the same intuitive skill humans do, and tend to not understand complex or abstract concepts. We can use techniques like background subtraction, retro reflective materials and brightness thresholding mentioned in the reading in order to help computers track what we are interested in. Computer vision tracking can significantly influence interactive media. Of course, as with most things, we have to consider ethical issues, especially when tracking might be done in public spaces. Computer vision can be extremely beneficial for data collection, analysing the audiences’ behaviour. Advanced technology can also be extremely useful for seamless communication in interactive media. Through combinations of physical inputs and well-thought creative concepts, we can create more advanced ideas in the field of interactive media. While computer vision has its limitations, we need to carefully understand its advantages and use these characteristics effectively .

Week 3 Project

Inspired by my floor’s theme I am making batman. I used object-based coding to make the rain appear to fall. Adding music also gave it the batman like mood I was looking for. I think the way that half of the rain falls in front of him and half falls behind him was something that took me a while to conceptualize. Therefore this was a part of the code I was proud of.

  // draw raindrops that go behind batman
  for (let drop of drops) {
    if (drop.z <= 1.5) {
      drop.fall();
      drop.show();
    }
  }
  //draw batman
  fill(0)
  noStroke()
  ellipse(200, 250, 100, 100)
  quad(400-250, 248, 250, 248, 400-120, 400, 120, 400)
  triangle(152,240,160,170,182,240)
  triangle(400-152,240,400-160,170,400-182,240)
  fill(255)
  quad(163,250,183,250, 190, 260, 170, 260)
   quad(400-163,250,400-183,250, 400-190, 260, 400-170, 260)
  
  
  // then draw the raindrops in front of batman
  for (let drop of drops) {
    if (drop.z > 1.5) {
      drop.fall()
      drop.show();
    }
  }
}
  //making the raindrops fall
class RainDrop {
  constructor() {
    this.x = random(width);
    this.y = random(-height, 0);
    //perspective
    this.z = random(1, 3);
    // this makes the background slower than the foreground
    this.speed = map(this.z, 0.5, 2, 2, 6);

In terms of improvements I definitely could have made batman less minimalistic, and I think doing some other things to the rain to make it even more real (vary thickness of raindrops to account for perspective and stuff like that) which would add to the artwork. Lastly, adding some sort of more interactive element would have also made it better.

Week 4 – reading response

Reading Response: The Psychopathology of Everyday Things

Something That Drives Me Crazy: Confusing Shower Knobs

One of the most frustrating design flaws in everyday life is the lack of a standardized, intuitive shower knob system across different countries. If you’ve ever traveled internationally, you’ve likely encountered showers that seem to require a degree in engineering to operate.

In the United States, many showers have a single-knob system where you turn left for hot water and right for cold. However, some models require you to pull or push the knob, which isn’t always obvious. In the United Kingdom, separate hot and cold taps are still common, making us mix water manually. In Norway, for example, some showers have buttons that must be pressed in a particular sequence before water flows. The inconsistency means that travellers like me often accidentally scald themselves, turn on the water at full blast, or get an unexpected cold shock.

The biggest issue is discoverability. There’s often no clear indication of how the system works. Some showers even have extra knobs that control water pressure or temperature separately, adding to more confusion. Without obvious instructions, we are left to experiment, sometimes getting drenched unexpectedly in freezing or boiling water.

Applying Norman’s Principles to Improve Shower Design

Don Norman’s principles of discoverability, affordances, and signifiers could help improve shower designs:

  1. Clear affordances. The shape and placement of knobs should signify their function. A lever-style handle naturally implies to us that it has to be turned, while a button clearly calls for you to press it.
  2. Icons or labels could tell us about temperature directions, with simple red/blue colors universally suggesting hot and cold temp.
  3. Natural mapping. This could be a horizontal sliding control that moves left for hot and right for cold. It would be more intuitive than rotating knobs in random directions.

Another potential hi-tech solution is a digital shower interface with a display which could get rid of confusion entirely.

Week 4 – generative text output

Inspiration for This Project

I wanted to create an interactive and visually engaging experience that merges astrology with generative art. The idea was to provide users with a simple yet immersive way to receive a zodiac-based “psychic reading,” followed by animations and visuals. Astrology is often associated with mysticism and magic, so I aimed to reflect that via changing background colours and adding floating particles. For the visual part, I took my inspiration from this website: https://www.horoscope.com/us/index.aspx

Code Highlight I Am Proud Of

One part of the code I’m particularly proud of is the getZodiacColor function, which assigns a unique background color to each zodiac sign:

function getZodiacColor(sign) {
  let colors = {
    "Aries": color(255, 99, 71), "Taurus": color(107, 142, 35), "Gemini": color(255, 215, 0), "Cancer": color(70, 130, 180),
    "Leo": color(255, 165, 0), "Virgo": color(46, 139, 87), "Libra": color(123, 104, 238), "Scorpio": color(148, 0, 211),
    "Sagittarius": color(255, 140, 0), "Capricorn": color(139, 69, 19), "Aquarius": color(0, 191, 255), "Pisces": color(72, 61, 139)
  };
  return colors[sign] || color(240);
}

This function is simple, but it instantly transforms the visual feel of the project based on the user’s selection, creating some sense of personalization.

Reflection

For future projects, I’d love to explore more complex generative animations, such as constellations that change based on the zodiac sign. Things like integrating sound effects or subtle ambient music could enhance the mystical atmosphere. Another direction could be adding more interactive elements, like having particles respond to mouse movement, making the experience feel even more magical and immersive.

Here is the full code:

let signs = [
  "Aries", "Taurus", "Gemini", "Cancer", "Leo", "Virgo",
  "Libra", "Scorpio", "Sagittarius", "Capricorn", "Aquarius", "Pisces"
];

// Zodiac readings for each sign
let readings = {
  "Aries": ["Today is a day for bold moves.", "A new adventure awaits you.", "Your energy will attract opportunities."],
  "Taurus": ["Stay grounded, but take a leap of faith.", "Patience will bring unexpected rewards.", "A financial opportunity is coming your way."],
  "Gemini": ["A conversation will spark inspiration.", "Your curiosity leads to a surprising discovery.", "Adaptability is your greatest strength today."],
  "Cancer": ["Your emotions will guide you well.", "A nostalgic moment will bring clarity.", "Trust your intuition—it knows the way."],
  "Leo": ["Your confidence will open doors.", "A bold move will lead to admiration.", "Shine your light and others will follow."],
  "Virgo": ["Your keen eye will catch an important detail.", "Organization will bring unexpected rewards.", "A small habit change will lead to a breakthrough."],
  "Libra": ["Balance is key today.", "A relationship will deepen in an unexpected way.", "Harmony will find you when you least expect it."],
  "Scorpio": ["Mystery surrounds you—embrace it.", "Transformation is closer than you think.", "Your passion will lead you to new heights."],
  "Sagittarius": ["An exciting journey is on the horizon.", "Your optimism will inspire someone today.", "The universe is conspiring in your favor."],
  "Capricorn": ["Hard work pays off—stay focused.", "A disciplined approach will yield results.", "Your perseverance will be rewarded soon."],
  "Aquarius": ["Innovation is your ally today.", "A sudden insight will change your path.", "Your unique perspective is your greatest strength."],
  "Pisces": ["Your dreams hold important messages.", "Creativity will flow effortlessly.", "A moment of solitude will bring deep understanding."]
};

let dropdown, button, output;
let bgColor;
let particles = [];

function setup() {
  createCanvas(400, 300);
  textSize(16);
  textAlign(CENTER, CENTER);
  
  // Create dropdown menu for zodiac signs
  dropdown = createSelect();
  dropdown.position(100, 100);
  
  for (let sign of signs) {
    dropdown.option(sign);
  }
  
  // Create button to generate reading
  button = createButton("Get Your Reading");
  button.position(100, 140);
  button.mousePressed(generateReading);
  
  output = "Select your sign and receive your reading";
  bgColor = color(240);
  
  // Create floating particles for magical effect
  for (let i = 0; i < 50; i++) {
    particles.push(new Particle());
  }
}

function draw() {
  background(bgColor);
  fill(50);
  text("Psychic Zodiac Reading", width / 2, 50);
  text(output, width / 2, 80);
  
  // Update and show floating particles
  for (let p of particles) {
    p.update();
    p.show();
  }
}

// Generate random reading based on selected zodiac sign
function generateReading() {
  let selectedSign = dropdown.value();
  let possibleReadings = readings[selectedSign];
  output = possibleReadings[int(random(possibleReadings.length))];
  bgColor = getZodiacColor(selectedSign);
}

// Assign unique background color for each zodiac sign
function getZodiacColor(sign) {
  let colors = {
    "Aries": color(255, 99, 71), "Taurus": color(107, 142, 35), "Gemini": color(255, 215, 0), "Cancer": color(70, 130, 180),
    "Leo": color(255, 165, 0), "Virgo": color(46, 139, 87), "Libra": color(123, 104, 238), "Scorpio": color(148, 0, 211),
    "Sagittarius": color(255, 140, 0), "Capricorn": color(139, 69, 19), "Aquarius": color(0, 191, 255), "Pisces": color(72, 61, 139)
  };
  return colors[sign] || color(240);
}

// Particle class for floating magic effect
class Particle {
  constructor() {
    this.x = random(width);
    this.y = random(height);
    this.vx = random(-1, 1);
    this.vy = random(-1, 1);
    this.alpha = random(100, 255);
  }

  // Update particle movement
  update() {
    this.x += this.vx;
    this.y += this.vy;
    if (this.x > width || this.x < 0) this.vx *= -1;
    if (this.y > height || this.y < 0) this.vy *= -1;
  }

  // Display particle as a glowing dot
  show() {
    noStroke();
    fill(255, this.alpha);
    ellipse(this.x, this.y, 5, 5);
  }
}

 

Week 4 – Generative Text

Concept:
This piece is meant to imitate a page turning, but instead of the expected behaviour it slides a new page down from the top. The text itself is pulled from a .txt file, which contains bits of placeholder text (Lorem ipsum dolor) as well as snippets of text from the p5.js reference that pertain to implementing text.

Highlight:
My highlight is still fairly simple, but I chose it since I often forget to include bounds checking or error handling in my code and end up causing myself problems down the road. This snippet checks to make sure that the newly created page is not receiving empty input for its inner text, and cleans up the pages array once a certain number of pages have been created while leaving only the most recent instance.

// // Create a new page on click
  let newText = txt[floor(random(txt.length - 1))];
  let tries = 0;
  // // Make sure new page's text is not empty
  while (!newText && tries < 10) {
    newText = txt[floor(random(txt.length - 1))];
    tries++;
  }
  // // Cull older pages at some upper limit
  if (pages.length >= 10) {
    pages = subset(pages, pages.length - 1, 1);
    console.log("reset");
    console.log(pages);
  }

Embed:

Reflection:
I’m not super satisfied with this piece, doubly so since I tried a few different concepts that I was unable to get to work properly. I had been having issues with getting the data to load from a file, and only managed to get it to work once I pivoted to this idea. I had also wanted to have the sliding direction change between the top, sides, and bottom, either changing randomly or going in a clockwise direction. This week was a bit rough in terms of workload so I was unable to spend as much time adding features to this piece as I would have liked.

Week 4 Generative Text + Reading

For the task of creating generative text, I thought of representing historical conceptual frameworks on machine to create a journey through the development of this conceptualization from literature such as Turing’s ‘Computing Machinery and Intelligence’ in 1950, as well as Isaac Asimov’s exploration of social concepts through the use of machines and robots as a literary medium.

I aimed to extend this literature to create an interactive journey, where the user’s mouse movements will influence the tone of the sentences generated , transitioning to a more hectic state.

 

I am particularly proud of being able to make the generative text based on a function  ‘mood’ which changes how the text is displayed. This required several iterations to nail down:

choosePhrase(type) {
        if (this.mood >= 0.9) {
            return random(this[`veryPess${type}`]);
        } else if (this.mood > 0) { // Use regular pessimistic phrases
            return random(this[`pess${type}`]);
        } else {
            return random(this[`opt${type}`]);
        }

The optimistic phrases display by default, but the method enables the dynamic changing of text which highlights the aforementioned purpose and intent. Other challenges I faced were making the text display within the correct boundaries, and just thinking of which sentences to formulate and how they would be perceived by the user to try to improve the interaction as much as I can.

 

READING

Something that still intrigues me and is of particular interest is the conceptual framework on interaction and the mediums by which we express it. There is no agreement of one single concept of interaction. As a consequence, the mediums through which this interaction can be facilitated are limited by our agreement and interpretation of the conceptual framework at hand. I believe it is difficult to reason about the other fundamental notions presented by the Norman without a detailed analysis of the causality in human-centric design, the reception of it, and as a consequence the dynamic improvement of this concept in literature.

I am able to apply the principles and notions presented by Norman by utilizing the methodology in which he discusses these concepts firstly.  Secondly, I am also able to utilize his critical analysis of concepts in psychology on human interaction and human perception to have a deeper understanding of how the end-user interacts with my generative artwork or projects. In fact, this part of chapter 1 is of key interest, where the analysis of a design takes a methodological approach in viewing instances of design and how humans perceive them, whilst hinting at a psychological notion and referring to psychological literature. This also hints towards a more experiential view of this principle of human design (whether it is human centric or centered towards something else).

 

Week 4 Response

  • What’s something (not mentioned in the reading) that drives you crazy and how could it be improved?

One thing recently is that in the game I’m playing right now, a Pokémon game, I cannot reorder my card decks even though on so many other UI interfaces I can, it is really frustrating that I cannot do this on an iPhone.

  • How can you apply some of the author’s principles of design to interactive media?

I think they are especially applicable. Keeping in mind that products mus be designed with the end-user in mind, we can use the assumptions people will have about things (link should be pressed) (pages scroll down) as ways to help us decide how we should structure the media we create to make it more accessible for users. It is a matter of stepping into their shoes and thinking about how would someone with no knowledge of the thing they are interacting with do upon first instinct.

week4- reading response

Reading Reflection – Week 5

One thing that annoys me is faulty elevator button designs such as the “Door Close” button that doesn’t work or when floors are numbered in a way that makes no sense. Some others make you swipe a keycard first before you press a floor, but you can’t tell that you’re meant to do that, so you just keep pressing the button and can’t figure out why it’s not working. The easy fix is more obvious signifiers, such as a little light or message that says, “Swipe card first.” This is Norman’s guideline that good design must make things obvious so users won’t need to guess. As for interactive media, I believe Norman’s principles can be applied there too.

For example, in VR, buttons and menus need to behave in intuitive ways—like grabbing objects in the same way you would in the real world instead of using awkward button presses. And feedback is crucial as well. If I tap at something within an application or a game, I expect to feel the effect of the tap in some way, with sound, graphical feedback, or vibration. Norman speaks quite extensively about human-centered design, and my favourites kinds of interactive experience are when things just naturally work the way you think you can do with them—they feel intuitive and do not require interrupting flow for working out what you are meant to be doing.

Week 4 : Generative text

For this week’s project, I wanted to create something with a cosmic theme that felt both interactive and magical. I focused on shades of blue and purple to match the theme and added a twinkling star effect as the background. The core of the project is the interactive bubbles—users can click on the screen to generate bubbles, and each bubble will display a random star sign. Clicking on an existing bubble reveals a short message related to that star sign. The letters of the message then fall down in an effect imitating a meteor shower.

CLICK TO CREATE AND POP BUBBLES

One part of the code that I’m particularly proud of is the way the bubbles and the falling messages behave. When the user clicks on a bubble, the bubble displays a message tied to the star sign. After a few seconds, the letters from the message “fall” like meteors. This falling effect was challenging to create because I had to ensure the letters moved smoothly and looked dynamic without overlapping or bunching together. Balancing the timing and position of each letter took some effort, but I’m happy with how it turned out. It adds a playful touch to the overall design.

I’m also proud of how the bubbles behave when they’re generated. Perfecting their collision and bounce behavior was tricky—it was difficult to make sure they didn’t overlap or get stuck together without affecting their smooth movement across the screen. It took a lot of experimenting to perfect the constraints that controlled their movement, Despite the challenges, I found it rewarding to see how small tweaks could make such a big improvement in the final product. These interactions made the overall experience feel more dynamic and immersive, which is exactly what I was aiming for with the cosmic theme.

class Fortune {
  constructor(x, y, message) {
    this.x = x;
    this.y = y;
    this.message = message;
    this.alpha = 0; // Start invisible for fade-in effect
    this.timer = 90; // Now lasts for 3 seconds
    this.fadeInSpeed = 5; // Controls how fast it fades in
    this.released = false;
    this.floatOffset = 0; // For a slight floating effect
  }

  update() {
    if (this.timer > 0) {
      this.timer--;
      if (this.alpha < 255) this.alpha += this.fadeInSpeed; // Gradually appear
      this.floatOffset = sin(frameCount * 0.1) * 2; // Subtle floating effect
    } else if (!this.released) {
      this.releaseLetters();
      this.released = true;
    }
  }

  display() {
    if (this.timer > 0) {
      push();
      translate(this.x, this.y + this.floatOffset);

      // Glowing text effect
      fill(255, 255, 255, this.alpha);
      textSize(14);
      textAlign(CENTER, CENTER);
      drawingContext.shadowBlur = 10;
      drawingContext.shadowColor = color(255, 200, 255, this.alpha);

      text(this.message, 0, 0);

      pop();
    }
  }

  releaseLetters() {
    for (let i = 0; i < this.message.length; i++) {
      rainingLetters.push(new Letter(this.x, this.y, this.message.charAt(i)));
    }
  }
}


class Letter {
  constructor(x, y, char) {
    this.x = x + random(-10, 10);
    this.y = y;
    this.char = char;
    this.speed = random(1, 3);
    this.alpha = 255;
  }

  update() {
    this.y += this.speed;
    this.alpha -= 3;
  }

  display() {
    push();
    translate(this.x, this.y);
    fill(255, this.alpha);
    textSize(20);
    textAlign(CENTER, CENTER);
    text(this.char, 0, 0);
    pop();
  }
}

Reflections and Future Ideas

Overall, I really enjoyed working on this project, even though it was a bit frustrating at times. Looking back, I feel like I could improve the overall aesthetic of the bubbles by adding a shine to make them look like they’re reflecting light. I’d also like to enhance the appearance of the text since the current font is quite simple. Another idea I have is to experiment with different styles for the falling letters—and maybe space them out more and slow the fall for a better visual experience, to better match the cosmic theme.

Week 4 Visualization

I created an interactive galaxy simulation where users can draw stars onto the canvas by clicking the mouse. The stars are generated based on data provided in a CSV file, and the galaxy background moves and spirals as part of the effect.

One of the most challenging aspects of this project was working with dynamic data in the form of a CSV file and integrating it into the interactive star drawing. I wanted to make a galaxy where the background constantly moved while the user could add stars by clicking on the canvas. The CSV file had to be loaded, parsed, and used to generate star properties such as position, size, and color. Managing the data flow, especially ensuring that the properties were being applied correctly to each star object, was tricky.

The file contains predefined star data such as position (x, y), size, and color (r, g, b). In the preload() function, the CSV is loaded using loadTable(), which makes the data accessible within the program. After that, in the setup() function, I loop through each row of the CSV and extract these values to create star objects. These stars are then pushed into the stars array, which holds all the stars that will be drawn on the canvas.


for (let i = 0; i < starData.getRowCount(); i++) {
let x = starData.getNum(i, 'x');
let y = starData.getNum(i, 'y');
let size = starData.getNum(i, 'size');
let r = starData.getNum(i, 'r');
let g = starData.getNum(i, 'g');
let b = starData.getNum(i, 'b');
stars.push({
x: x,
y: y,
size: size,
color: color(r, g, b),
brightness: random(180, 255)
});
}

Right now, all the stars are drawn on the same layer, which can make the galaxy feel flat. I would like to improve this by adding a sense of depth—farther stars could be smaller and move slower than closer stars, and also add different layers of stars to simulate foreground and background elements. Also, I would like to improve the galaxy background, it could be enhanced by adding a texture or some glowing nebula-like shapes to give more life and movement.