## Assignment 02: Flower Artistry

Concept:  My interactive media class starts just at the end of the day and when I was sitting in the class, brainstorming what I do with loops, I randomly started to draw some simple flowers on P5.js to relieve some stress from having a long day. Then the idea came to my head that having a flower bouquet can make me feel so good, if I don’t have one, then why not create a virtual one? So, here it is!

Proud Moment: I initially sketched some basic flower-like shapes using circles in P5.js, but they didn’t turn out as expected. To achieve the variety and complexity I wanted, I decided to use loops directly as we discussed in class, as manually coding each flower would have been impractical. My main challenge was ensuring that all the flowers had distinct appearances. To address this, I designed each flower type, reusing a base code and adjusting parameters to create different flower variations.

Code Snippet:

```function drawDaisy(x, y, size, rotation) {
let petalCount = 9;
let petalLength = size;
let petalWidth = size / 3;

stroke(0);
fill('#D9E4E6');
push();
translate(x, y);
rotate(rotation);
for (let i = 0; i < petalCount; i++) {
push();
rotate(TWO_PI / petalCount * i);
ellipse(0, -size / 2, petalWidth, petalLength);
pop();
}
pop();

fill('#F2F2F2');
noStroke();
ellipse(x, y, size / 2);
}

function drawTulip(x, y, size, rotation) {
let petalCount = 6;
let petalWidth = size / 2;

stroke(0);
fill('#AEB7FE');
push();
translate(x, y);
rotate(rotation);
for (let i = 0; i < petalCount; i++) {
push();
rotate(TWO_PI / petalCount * i);
ellipse(0, -size / 2, petalWidth, size);
pop();
}
pop();

fill('#EDEAE6');
noStroke();
ellipse(x, y, size / 3);
}```

It made the design part of my work easier, but I initially struggled with making the flowers continuously generate as the mouse cursor moves and ensuring they didn’t cluster in one spot. To address this, I turned to various YouTube videos on Mouse Trails, such as the p5.js | Mouse Trail (Quick Code) tutorial. However, I needed to adapt some parameters and functions to fit my specific goals, which differed slightly from those demonstrated in the videos. This aspect of the project was particularly challenging as I had to first grasp the underlying logic before implementing the necessary code to achieve the desired functionality.

In `mouseMoved()` Function, I’m implementing the logic to generate new flowers as the mouse moves across the canvas. Here’s a breakdown:

```function mouseMoved() {
let currentTime = millis();
if (currentTime - lastGenerationTime > flowerGenerationInterval) {
lastGenerationTime = currentTime;
generateFlowers(mouseX, mouseY);
}
}

function updateFlower(flower) {
let dx = mouseX - flower.x;
let dy = mouseY - flower.y;
let distance = dist(flower.x, flower.y, mouseX, mouseY);

if (distance > 1) {
flower.x += (dx / distance) * followSpeed;
flower.y += (dy / distance) * followSpeed;
}

flower.x += random(-0.5, 0.5);
flower.y += random(-0.5, 0.5);
}
```
I use millis() to get the current time in milliseconds since the sketch started. By comparing it to `lastGenerationTime`, I ensure that new flowers are only generated after a specified interval `(flowerGenerationInterval)`. This prevents an overwhelming number of flowers from being created all at once.

When the time condition is met, I update `lastGenerationTime` and call `generateFlowers()` with the current mouse position `(mouseX, mouseY)`. This function creates flowers around the mouse cursor, adding to the visual interest as I move the mouse.

Then, I calculate the distance between the flower and the mouse cursor using dx and dy. If the distance is greater than 1 pixel, the flower moves towards the mouse position. The followSpeed controls how quickly the flower moves. By dividing dx and dy by the distance, I ensure that the flower moves in the correct direction and scales its speed relative to the distance. While there might be other efficient ways to implement this, I chose this manual approach by carefully considering the underlying logic.

After watching the video “Eyeo2012 – Casey Reas,” I decided to introduce some randomness into the flower movement. I added the last two lines of code to make the movement more natural and less mechanical by including a small random offset to the flower’s position. This randomness results in a more organic and unpredictable motion, enhancing the overall visual appeal.

However, I was confused about which version to use as my final submission because each offers a unique vibe that I find appealing. To showcase the contrast, I am also including my first draft as a media file. This allows for a comparison between the two iterations, each with its distinct style and feel.

First Draw:

Reflection and Ideas for Future Work or Improvements:

By using loops and arrays, I was able to efficiently generate and manage an infinite number of flowers, ensuring that the animation remained dynamic and engaging. The code successfully used these loops to update the positions of the flowers and arrays to store and retrieve flower properties, which was crucial for managing the large number of elements and their interactions. Here is what I think can be done in the future:

Performance Optimization: I encountered performance issues when increasing the number of flowers. For instance, trying to use infinitely many flowers caused the webpage to lag, highlighting the need for optimization to handle more elements smoothly. Addressing this performance challenge would help in making the animation more fluid and responsive.

Color Combinations: The current color scheme for the flowers and background could be improved. Some color combinations might not be as visually appealing or harmonious as they could be. Experimenting with different palettes could enhance the overall aesthetic and make the animation more striking.

User Interface and Interactivity: I initially experimented with aligning flowers based on input words, but this approach did not work as intended. Consequently, I simplified the project to focus solely on basic typography and the interactive aspect of the flowers following the mouse cursor. Future iterations could benefit from refining this concept or incorporating new interactive features to give users more control.

Conclusion: Despite these areas for improvement, I am pleased with the overall vibe of the project. The use of rotation to animate the flowers adds a dynamic touch, enhancing the visual interest of the animation. I enjoy the lively and engaging feel it provides and look forward to further refining and expanding upon this project in the future.

As someone deeply interested in art and technology, I found Casey Reas’s works incredibly inspiring. His integration of algorithms, geometry, and art in design, interactive installations, and games has profoundly shifted my perspective on algorithms. Reas’s emphasis on the importance of randomness and chance operations in sparking imagination and pattern recognition truly resonated with me. Previously, algorithms seemed like rigid, rule-bound constructs, but Casey Reas demonstrated their creative potential through his projects. I also appreciated the historical context he provided on the juxtaposition of order and chaos in art and culture. He discussed how various artists, such as Jean Arp, Marcel Duchamp, John Cage, and Ellsworth Kelly, have employed chance and randomness in their work, showing how these concepts have evolved.

Reas’s ideas about randomness and chance reminded me of a photography project I’ve been working on, capturing different flowers from the NYUAD campus. I realized I could introduce more randomness into the process by experimenting with various camera settings and unconventional techniques. This approach could lead to more unexpected and intriguing results while maintaining cohesion and structure. I was also intrigued to learn about how military research into randomness has evolved into generative art. For example, his 10 PRINT algorithm, which generates unique and intricate patterns, fascinated me by showing how a simple algorithm can produce complex and beautiful results based on randomness. His work has motivated me to delve deeper into creative coding and explore the vast intersection of art and technology.

In general, a balance between randomness and control can be achieved by introducing elements of chance and unpredictability into a structured framework. This can help to create a sense of tension and surprise, while still maintaining a sense of coherence and direction. Casey’s use of the 10 PRINT algorithm to generate unique and intricate patterns is a great example of how a balance between randomness and control can be achieved. The algorithm provides a structured framework for generating patterns, while the random elements introduce a degree of unpredictability and surprise.

## Self Portrait: Assignment_01

Concept: The concept comes from my favourite childhood cartoon Masha and Bear. I always loved how the bear’s room looked so cozy and peaceful in the cartoon. As I grew older, I noticed my younger brothers acting mischievously, much like Masha. In response, I found myself playing a protective role similar to the Bear’s in the series. So, I choose the bear as my concept for this assignment and tried to create a stylized portrait of the bear using basic 2D shapes in P5.js. While the result may not be an exact replica of the Bear, I tried to capture the essence of his character as seen in cartoon.

Highlight Code: One part of the code that I’m particularly proud of is the drawing of the bookshelf. It’s my first time working with Java and doing a full sketch on P5.js, so I had to go through quite a few tutorials from this channel to understand basics of the drawings. I tried to code the bookself using loops technique from this video. I calculated the positions of the shelves and books using variables and loops. This method allowed me to place multiple shelves and books at regular interval but I had to go through a lot of trials and errors so took me quite some time to figure out how to work with the perspective drawing in P5.js. On my first try, I tried to make a 2D bookshelf, but that didn’t look satisfactory so I added some depth in the drawing using `beginShape()`, `vertex()`, and `endShape()` functions to add some thickness on the sides and changed the fill() to create a contrast on the shadow and lighting. To express what I meant to portray I added one line of quote about books, I achieved this by using `textStyle()`and `textAlign()` functions.

Code:

```function setup() {
createCanvas(600, 500);
setGradient(0, 0, width, height, color(255, 182, 193), color(255, 228, 225)); // Gradient background
drawHelloKitty(); //function that I am using to draw the main character
drawBookshelf();
}

function drawHelloKitty() {
noLoop();
noStroke();

// Draw face
stroke(0);
strokeWeight(0.2);
fill("rgb(252,245,225)");
ellipse(200, 200, 180, 180);

// Draw ears
fill('rgb(244,230,215)');
ellipse(120, 130, 70, 70); // Left ear
ellipse(280, 130, 70, 70); // Right ear

//inner ear color

fill(160, 82, 45); // Medium brown
ellipse(120, 130, 50, 50); // Left inner ear
ellipse(280, 130, 50, 50); // Right inner ear

// eyes
fill(0);
ellipse(170, 200, 22, 22); // Left eye
ellipse(230, 200, 22, 22); // Right eye

// Draw nose
fill(160, 82, 45); // Medium brown
ellipse(200, 230, 22, 18); // Nose

// Draw mouth

stroke(0);
strokeWeight(2);
noFill();
arc(200, 245, 50, 25, 0, PI); // Mouth

// Draw whiskers

stroke(0);
strokeWeight(2);
line(100, 200, 50, 190); // Left whisker 1
line(100, 210, 50, 210); //2
line(100, 220, 50, 230);  //3

line(300, 200, 350, 190); // Right whisker 1
line(300, 210, 350, 210); //2
line(300, 220, 350, 230); //3

// Drawing body
fill(255, 0, 0);
stroke(0);
strokeWeight(2);

fill(160, 82, 45);
ellipse(200, 480, 260, 400);
stroke(0);
strokeWeight(2);
fill("rgb(250,204,109)")
rect(155, 270, 90, 100);

// hand details
fill('rgb(252,245,225)');
ellipse(140, 300, 70, 40); // Left hand
ellipse(260, 300, 70, 40); // Right hand

stroke(0);

strokeWeight(2);

// lines for left hand
line(140, 295, 170, 290); // First finger
line(140, 305, 173, 305);
line(140, 315, 165, 315);

// lines for right hand
line(228, 295, 265, 297); // First finger
line(225, 305, 265, 305);
line(240, 315, 266, 315);
}

function drawBookshelf() {
// Adjusted position of the bookshelf
const shelfX = 400;
const shelfY = 150;
const shelfWidth = 160;
const shelfHeight = 360;
const shelfThickness = 19;

// Draw the bookshelf
fill(150, 75, 0); // Wood color
rect(shelfX, shelfY, shelfWidth, shelfHeight); // Main body of the bookshelf

// Draw the shelves
fill(120, 60, 0); // Slightly darker wood color
for (let i = 1; i <= 5; i++) { // Adjusted to have more shelves
rect(shelfX, shelfY + i * 60, shelfWidth, shelfThickness); // Horizontal shelves
}

// Draw the sides for depth
fill(100, 50, 0); // Darker wood color for sides
beginShape();
vertex(shelfX, shelfY); // Top left corner
vertex(shelfX + 10, shelfY - 10); // Slightly to the right and up
vertex(shelfX + 10, shelfY + shelfHeight - 10); // Down to the bottom
vertex(shelfX, shelfY + shelfHeight); // Back to the bottom left corner
endShape(CLOSE);

beginShape();
vertex(shelfX + shelfWidth, shelfY); // Top right corner
vertex(shelfX + shelfWidth + 10, shelfY - 10); // Slightly to the right and up
vertex(shelfX + shelfWidth + 10, shelfY + shelfHeight - 10); // Down to the bottom
vertex(shelfX + shelfWidth, shelfY + shelfHeight); // Back to the bottom right corner
endShape(CLOSE);

// Draw the books
fill(200, 0, 0); // first row
drawBook(shelfX + 10, shelfY + 60, 40, 80);
drawBook(shelfX + 60, shelfY + 60, 40, 80);
drawBook(shelfX + 110, shelfY + 60, 40, 80);

fill(0, 200, 0); // second row
drawBook(shelfX + 10, shelfY + 130, 40, 80);
drawBook(shelfX + 60, shelfY + 130, 40, 80);
drawBook(shelfX + 110, shelfY + 130, 40, 80);

// a quote below the bookshelf
fill(0);
textSize(18);
stroke(0);
strokeWeight(0);
textFont('Arial');
textStyle(NORMAL);
textAlign(CENTER);

// Text lines
let line2 = "Masha!";

// position of the quote
text(line1, width / 3, 320);
text(line2, width / 3, 340);

}

function drawBook(x, y, w, h) {
fill(255);
rect(x, y, w, h);
fill(0);
rect(x + 10, y, 20, h); //the book spine

}

function setGradient(x, y, w, h, c1, c2) {
noFill();
for (let i = y; i <= y + h; i++) {
let inter = map(i, y, y + h, 0, 1);
let c = lerpColor(c1, c2, inter);
stroke(c);
line(x, i, x + w, i);
}
}
```

P5.js Sketch:

Reflection and ideas for future work or improvements:

I felt as a beginner I learnt a lot while doing this basic shape based portrait. From brainstorming to implementing, I changed some ideas, colors and techniques but at the end, I am pretty happy with this little drawing. However, there are areas for improvement and future exploration.

The bear doesn’t look or match with the bear color from the cartoon, so it can be enhanced by using different color pallets from rgb colors. The face shape of the bear can be refined a bit more with some curves to give a bear like feature.  Interactivity can be added into this portrait to make it more appealing and fun. The color combination makes the brown color heavy on eyesight, it can be changed as well.