The reading discusses an app called Waze. Waze is a GPS app but with a twist, it does not only tell you how to get to your destination and what the shortest route is, but it also tells you which route has traffic and how long it’ll take you to get to your destination with traffic taken into account. This is not a new idea- to me at least because I have seen it applied in my google maps app. This application of the “social” in the “digital” to make applications even more useful to humans. In the old days, people would have to listen to the radio to know how the traffic conditions are, but now we have such apps to make our lives easier. The inventors of Waze did not create something completely new, they just relied on sensor technology to measure the traffic in the streets. They worked on something that existed previously and helped better it by adding what the reading calls “layers” to the original format – the map.
Author: Dhabia AlMansoori
Design Meets Disability
This reading’s most interesting part to me is the talk of fashion and design for disability clashing. The focus was on glasses, which have now are now called “eyewear” in the industry. While needing glasses is a minimal disability to meet, the design to comfort the wearer and to remove the stigma around wearing them has been successful. Unlike most “designs” for other disabilities, the fashion industry did not try to hide them, but rather emphasize them. Glasses have become more of a fashion accessory rather than a medical necessity. The mention of embracing fashion when designing for disability seems very interesting because it might shed a more positive light on prosthetics and the overall confidence of the person who wears them.
In the reading, prosthetic hands were mentioned, and it said that most of them were either functional, but not good looking, or realistic with minimal function to them. I think we should try to snap out of the traditional thinking and try new “approaches” like the reading suggests in order to best progress and to provide options that are inclusive and will not leave the person to compromise between features.
This reading also reminded me of the alternative limb project. The project “explores the themes of body image, modification, evolution, and transhumanism, whilst promoting positive conversations around disability and celebrating body diversity” Their projects are really beautiful and artistic. Exploring exactly what the reading suggests.
Bouncing Yoga Ball
It’s a Yoga Ball,,,,,, and it bounces.
/********* VARIABLES *********/ // We control which screen is active by settings / updating // gameScreen variable. We display the correct screen according // to the value of this variable. // // 0: Initial Screen // 1: Game Screen // 2: Game-over Screen int gameScreen = 0; int ballX, ballY; int ballSize = 70; int ballColor = color(0); float gravity = 1; float ballSpeedVert = 0; float airfriction = 0.0001; float friction = 0.1; color racketColor = color(255,87,93); float racketWidth = 100; float racketHeight = 10; int racketBounceRate = 20; float ballSpeedHorizon = 10; //int ballZ, ballM; //int ballMSize = 60; /********* SETUP BLOCK *********/ void setup() { size(500, 500); ballX=width/4; ballY=height/5; } /********* DRAW BLOCK *********/ void draw() { // Display the contents of the current screen if (gameScreen == 0) { initScreen(); } else if (gameScreen == 1) { gameScreen(); } else if (gameScreen == 2) { gameOverScreen(); } } /********* SCREEN CONTENTS *********/ void initScreen() { // codes of initial screen background(0); textAlign(CENTER); text("Click to start", height/2, width/2); } void gameScreen() { background(244,56,70); drawBall(); applyGravity(); keepInScreen(); drawRacket(); watchRacketBounce(); applyHorizontalSpeed(); } void applyHorizontalSpeed(){ ballX += ballSpeedHorizon; ballSpeedHorizon -= (ballSpeedHorizon * airfriction); } void makeBounceLeft(int surface){ ballX = surface+(ballSize/2); ballSpeedHorizon*=-1; ballSpeedHorizon -= (ballSpeedHorizon * friction); } void makeBounceRight(int surface){ ballX = surface-(ballSize/2); ballSpeedHorizon*=-1; ballSpeedHorizon -= (ballSpeedHorizon * friction); } // codes of game screen void watchRacketBounce() { float overhead = mouseY - pmouseY; if ((ballX+(ballSize/2) > mouseX-(racketWidth/2)) && (ballX-(ballSize/2) < mouseX+(racketWidth/2))) { if (dist(ballX, ballY, ballX, mouseY)<=(ballSize/2)+abs(overhead)) { makeBounceBottom(mouseY); // racket moving up if (overhead<0) { ballY+=overhead; ballSpeedVert+=overhead; } } } } void applyGravity() { ballSpeedVert += gravity; ballY += ballSpeedVert; ballSpeedVert -= (ballSpeedVert * airfriction); } void makeBounceBottom(int surface) { ballY = surface-(ballSize/2); ballSpeedVert*=-1; ballSpeedVert -= (ballSpeedVert * friction); } void makeBounceTop(int surface) { ballY = surface+(ballSize/2); ballSpeedVert*=-1; ballSpeedVert -= (ballSpeedVert * friction); } void drawRacket(){ fill(racketColor); rectMode(CENTER); rect(mouseX, mouseY, racketWidth, racketHeight); } // keep ball in the screen void keepInScreen() { // ball hits floor if (ballY+(ballSize/2) > height) { makeBounceBottom(height); } // ball hits ceiling if (ballY-(ballSize/2) < 0) { makeBounceTop(0); } if (ballX-(ballSize/2) < 0){ makeBounceLeft(0); } if (ballX+(ballSize/2) > width){ makeBounceRight(width); } } void drawBall() { fill(ballColor); ellipse(ballX, ballY, ballSize, ballSize); //ellipse(ballZ, ballM, ballMSize, ballMSize); } void gameOverScreen() { // codes for game over screen } /********* INPUTS *********/ public void mousePressed() { // if we are on the initial screen when clicked, start the game if (gameScreen==0) { startGame(); } } /********* OTHER FUNCTIONS *********/ // This method sets the necessary variables to start the game void startGame() { gameScreen=1; }
referenced from the tutorial in the following link:
https://www.toptal.com/game/ultimate-guide-to-processing-simple-game
Recreating Old Computer Art
int size = 100; int cols = 7; int rows = 5; boolean light = false; int a; int b; void setup() { size (700, 500); smooth(); noFill(); noLoop(); background (255); } void draw() { int[][] box = new int[cols][rows]; for (int i = 0; i < cols; i++) { for (int j = 0; j < rows; j++) { box[i][j] = i; int a = i*100; int b = j*100; rect(a, b, 100, 100); println(i, j); int tx1 = int (random(i*100,i*100+50)); int ty1 = int (random(j*100,j * 100 + 50)); rect (tx1,ty1,50,50); int tx2 = int (random(i*100,i*100+50)); int ty2 = int (random(j*100,j * 100 + 50)); rect (tx2,ty2,30,30); int tx3 = int (random(i*100,i*100+50)); int ty3 = int (random(j*100,j * 100 + 50)); rect (tx3,ty3,20,20); int tx4 = int (random(i*100,i*100+50)); int ty4 = int (random(j*100,j * 100 + 50)); rect (tx4,ty4,10,10); int tx5 = int (random(i*100,i*100+40)); int ty5 = int (random(j*100,j * 100 + 40)); rect (tx5,ty5,60,60); int tx6 = int (random(i*100,i*100+30)); int ty6 = int (random(j*100,j * 100 + 30)); rect (tx6,ty6,70,70); int tx7 = int (random(i*100,i*100+20)); int ty7 = int (random(j*100,j * 100 + 20)); rect (tx7,ty7,80,80); int tx8 = int (random(i*100,i*100+10)); int ty8 = int (random(j*100,j * 100 + 10)); rect (tx8,ty8,90,90); int tx9 = int (random(i*100,i*100+50)); int ty9 = int (random(j*100,j * 100 + 50)); rect (tx9,ty9,40,40); int tx10 = int (random(i*100,i*100+50)); int ty10 = int (random(j*100,j * 100 + 50)); rect (tx10,ty10,45,45); //for //if (frameCount > 0.1) { noLoop(); // //println(mouseX + " : " + mouseY); // } } } }
Response to Eyeo2012
Casey Reas starts off by showing some of his own work, all of which is very visually striking. It looks somewhat alive like it was taken from something organic and he points out that that was he wanted to do. He started off by building on what others have established and then from that, he decided to start anew and write his own code for new randomness. Some of the shapes and patterns he produces look very abstract, yet somehow still manage to not look very random. These are all done digitally but it made me wonder what if we had a device to paint these patterns and shapes with paint and make it more physical, would it produce even more organic looking final pieces at the end?
What I liked, in particular, was how deeply incorporated the organic is in his work. It all looks alive and that is in part, I guess attributed to the “homeostatic” randomness.
I think this talk will help a lot with this week’s assignments because Reas demonstrates some of the concepts he talks about using processing – the ide we are using in class.
Her Code Got Humans On the Moon – And Invented Software and Attractive Things Work Better
Her Code Got Humans On the Moon – and Invented Software
This Article talked about Margaret Hamilton, aspects of her life and her struggle as a working mother in a predominantly male industry. The most interesting part of the article, to me, was when Hamilton found an issue which made the simulator crash when she was “toying” with it. This reminded me of something that our professor encourages us to do with our project and it was said more than two times (which is I remember it)- and it is to stress test our projects. To work them over and over again until we find an error and fix it. We shouldn’t just assume that things are never going to happen, because they will and they might, at the wrong time, just like it happened with Jim Lovell.
Attractive Things Work Better
This reading’s whole focus was around the three levels of processing: Visceral, Behavioral and Reflective and how they affect human emotions- specifically when it comes to the design of products. The reading started off with a very funny story which made it clear that emotions when it comes to design is a “human” thing and not specific to ethnicity or race. Then it went on to talk about how people who are happier generally have no problem with minor inconveniences and will ignore them and be as positive about the situation as they can be. This means a human being under stress will not be able to think clearly if one thing goes wrong and are bound to crack/ break down and lose rationality. The example of doors at the cinema is very scary, but an important one. It goes back to thinking about the precaution in the design of buildings and items like the fire extinguisher. Making them functional so people can use them when under stress and fear is very important, but also making them look nice so the aesthetics don’t get ruined.
Reading Response- A Brief Rant on the Future of Interaction Design and Responses
Bret Victor talks mainly about making things more graspable, to maximize human capabilities in satisfying their own needs. When reading the “rant”, I realized that most of what he was stating was true as my own “visions” of the future is more advanced versions of the “flat” surfaces we have now. As much as I love my phone, laptop, and Ipad, I have to admit that they do not indeed maximize the full potential of activity that our hands and bodies can do. I do know as someone who paints and draws that the hand, alongside the arm and the shoulder it’s attached to can do so much more and deserves more interactivity than just sliding a flat surface.
Self Portrait – Using Processing
The task was to: create a self-portrait. The fact that I have spent my break actually painting a self-portrait is just funny because, in comparison to that, this small animated version of me is as good as it gets with my skills at processing. I used basic shapes and then a text that changes when you click it just to add some element of interactivity to the portrait. I also added an easel and a pallet at the right because it felt like there had to be something “about me” rather than just an animated version of me.
This was the full version of what I made at the end.
boolean textHasBeenClicked = false; int count = 1; void setup(){ size(1000,1000); background(255, 200, 200); } void draw(){ background(255, 200, 200); fill(101,67,33); ellipse(225,270,250,400); fill(255,205,148); //color of big ellipse ellipse(225,200,175,200); //big ellipse\ noStroke(); fill(101,67,33); rect(165, 100, 120, 40, 7); fill(25.1,50.1,100.2); rect(116,300,200,300,7); fill(255);//white iris ellipse(200, 175, 30, 20);//eye ellipse(250, 175, 30, 20);//eye fill(0); //color of small ellipses ellipse(200, 175, 20, 20);//small ellipses ellipse(250, 175, 20, 20);//small ellipses fill(255,0,0); arc(227, 241, 75, 50, 0, 3.14); //smile fill(0); triangle(228, 209, 221, 217, 237, 217); fill(181,101,29); ellipse(700,150,200,200); fill(255,0,0); ellipse(700,100,20,20); fill(0,255,0); ellipse(650,120,20,20); fill(0,0,255); ellipse(700,150,20,20); fill(250,218,94); ellipse(750,100,20,20); fill(255, 200, 200); ellipse(740,181,50,50); fill(255); rect(578,263,200,250); stroke(0); line(631, 606, 677, 516); line(677,516,717,606); fill(0); if (textHasBeenClicked) { // display text 2 text("I waste my time listening to music and painting <3" , 400,300); } else { // display text 1 text("Hello, I am Dhabia, click on the text please" , 400,300); } frameRate(12); println(mouseX + " : " + mouseY); } void keyPressed(){ } void mouseClicked(){ textHasBeenClicked = ! textHasBeenClicked; }
An artist I felt particularly inspired by while researching is https://www.sergioalbiac.com, as he uses code to make art.
Wheel of Paintings + an Interactive Story
My idea for my midterm changed a few times, beginning with a noise pollution detector, and then changing to a noise-canceling project to a wheel that spins depending on the pitch of the user’s voice. I just knew I wanted to do something with sounds. I wanted to discover more about sound sensors and how to link them to servos.
I couldn’t get a pitch reading using my RedBoard, so instead, I used a Teensy 3.2 board that can take in values and record the pitch and frequency of certain noises. It can also record a certain volume of sound. So I could set it to only read beyond a certain level of decibels and not below that.
For the wheel, I have 7 pieces of art, the cloud one being the most irrelevant one of the batch, and the rest are there to highlight women’s day this weekend. I also realized that the paintings have nothing to actually relate to the whole “using pitch to reveal things” concept so I decided to create a side three-part story inspired by “Goldilocks and the Three Bears”. The father, mother, and baby bear are bound to have different pitches because of very apparent reasons. The user has to use the pitch of their voice and adjust it to fit the set tone to make the servo turn to the specific bear horrified at some strange girl touching their food.
Midterm project: Done
thank u max for the vocal demonstration pic.twitter.com/BT6otOiA1f— Dabz (@nolongergrey) March 6, 2019
// Audio Tone Input // Copyright 2013 Tony DiCola (tony@tonydicola.com) // This code is part of the guide at http://learn.adafruit.com/fft-fun-with-fourier-transforms/ // Additions made by Aaron Sherwood 2019 #define ARM_MATH_CM4 #include <arm_math.h> //////////////////////////////////////////////////////////////////////////////// // CONIFIGURATION // These values can be changed to alter the behavior of the spectrum display. //////////////////////////////////////////////////////////////////////////////// #include <Servo.h> // add servo library Servo myservo; // create servo object to control a servo int SAMPLE_RATE_HZ = 9000; // Sample rate of the audio in hertz. const int TONE_LOWS[] = { // Lower bound (in hz) of each tone in the input sequence. 200, 400, 600 }; const int TONE_HIGHS[] = { // Upper bound (in hz) of each tone in the input sequence. 200, 400, 600 }; int TONE_ERROR_MARGIN_HZ = 0; // Allowed fudge factor above and below the bounds for each tone input. int TONE_WINDOW_MS = 4000; // Maximum amount of milliseconds allowed to enter the full sequence. /////////// ////////// SET THRSHOLED HERE DHABIA float TONE_THRESHOLD_DB = 15.0; // Threshold (in decibels) each tone must be above other frequencies to count. /////////// /////////// const int FFT_SIZE = 256; // Size of the FFT. Realistically can only be at most 256 // without running out of memory for buffers and other state. const int AUDIO_INPUT_PIN = 14; // Input ADC pin for audio data. const int ANALOG_READ_RESOLUTION = 10; // Bits of resolution for the ADC. const int ANALOG_READ_AVERAGING = 16; // Number of samples to average with each ADC reading. const int POWER_LED_PIN = 13; // Output pin for power LED (pin 13 to use Teensy 3.0's onboard LED). // any other changes to the program. const int MAX_CHARS = 65; // Max size of the input command buffer //////////////////////////////////////////////////////////////////////////////// // INTERNAL STATE // These shouldn't be modified unless you know what you're doing. //////////////////////////////////////////////////////////////////////////////// IntervalTimer samplingTimer; float samples[FFT_SIZE * 2]; float magnitudes[FFT_SIZE]; int sampleCounter = 0; char commandBuffer[MAX_CHARS]; int tonePosition = 0; unsigned long toneStart = 0; //////////////////////////////////////////////////////////////////////////////// // MAIN SKETCH FUNCTIONS //////////////////////////////////////////////////////////////////////////////// void setup() { // Set up serial port. Serial.begin(38400); myservo.attach(3); // attaches the servo on pin 9 to the servo object // Set up ADC and audio input. pinMode(AUDIO_INPUT_PIN, INPUT); analogReadResolution(ANALOG_READ_RESOLUTION); analogReadAveraging(ANALOG_READ_AVERAGING); // Turn on the power indicator LED. pinMode(POWER_LED_PIN, OUTPUT); // Clear the input command buffer memset(commandBuffer, 0, sizeof(commandBuffer)); // Begin sampling audio samplingBegin(); } void loop() { // Calculate FFT if a full sample is available. if (samplingIsDone()) { // Run FFT on sample data. arm_cfft_radix4_instance_f32 fft_inst; arm_cfft_radix4_init_f32(&fft_inst, FFT_SIZE, 0, 1); arm_cfft_radix4_f32(&fft_inst, samples); // Calculate magnitude of complex numbers output by the FFT. arm_cmplx_mag_f32(samples, magnitudes, FFT_SIZE); // Detect tone sequence. toneLoop(); // Restart audio sampling. samplingBegin(); } // Parse any pending commands. parserLoop(); } //////////////////////////////////////////////////////////////////////////////// // UTILITY FUNCTIONS //////////////////////////////////////////////////////////////////////////////// // Compute the average magnitude of a target frequency window vs. all other frequencies. void windowMean(float* magnitudes, int lowBin, int highBin, float* windowMean, float* otherMean) { *windowMean = 0; *otherMean = 0; // Notice the first magnitude bin is skipped because it represents the // average power of the signal. for (int i = 1; i < FFT_SIZE / 2; ++i) { if (i >= lowBin && i <= highBin) { *windowMean += magnitudes[i]; } else { *otherMean += magnitudes[i]; } } *windowMean /= (highBin - lowBin) + 1; *otherMean /= (FFT_SIZE / 2 - (highBin - lowBin)); } // Convert a frequency to the appropriate FFT bin it will fall within. int frequencyToBin(float frequency) { float binFrequency = float(SAMPLE_RATE_HZ) / float(FFT_SIZE); return int(frequency / binFrequency); } // Convert intensity to decibels float intensityDb(float intensity) { return 20.0 * log10(intensity); } //////////////////////////////////////////////////////////////////////////////// // SPECTRUM DISPLAY FUNCTIONS /////////////////////////////////////////////////////////////////////////////// void toneLoop() { for (int i = 0; i < sizeof(TONE_LOWS)/sizeof(int); i++) { // Calculate the low and high frequency bins for the currently expected tone. int lowBin = frequencyToBin(TONE_LOWS[i]); int highBin = frequencyToBin(TONE_HIGHS[i]); // Get the average intensity of frequencies inside and outside the tone window. float window, other; windowMean(magnitudes, lowBin, highBin, &window, &other); window = intensityDb(window); other = intensityDb(other); // Check if tone intensity is above the threshold to detect a step in the sequence. if ((window - other) >= TONE_THRESHOLD_DB) { if (i == 0){ Serial.println("low triggered"); myservo.write(25); toneDetected(); } else if (i == 1) { Serial.println("mid triggered"); myservo.write(60); toneDetected(); } else if (i == 2) { Serial.println("high triggered"); myservo.write(110); toneDetected(); } } // // Check if the entire sequence was passed through. // if (tonePosition >= sizeof(TONE_LOWS) / sizeof(int)) { // toneDetected(); // tonePosition = 0; // } } } void toneDetected() { // Flash the LEDs four times. int pause = 150; for (int i = 0; i < 4; i++) { digitalWrite(POWER_LED_PIN, HIGH); delay(pause); digitalWrite(POWER_LED_PIN, LOW); delay(pause); } } //////////////////////////////////////////////////////////////////////////////// // SAMPLING FUNCTIONS //////////////////////////////////////////////////////////////////////////////// void samplingCallback() { // Read from the ADC and store the sample data samples[sampleCounter] = (float32_t)analogRead(AUDIO_INPUT_PIN); // Complex FFT functions require a coefficient for the imaginary part of the input. // Since we only have real data, set this coefficient to zero. samples[sampleCounter + 1] = 0.0; // Update sample buffer position and stop after the buffer is filled sampleCounter += 2; if (sampleCounter >= FFT_SIZE * 2) { samplingTimer.end(); } } void samplingBegin() { // Reset sample buffer position and start callback at necessary rate. sampleCounter = 0; samplingTimer.begin(samplingCallback, 1000000 / SAMPLE_RATE_HZ); } boolean samplingIsDone() { return sampleCounter >= FFT_SIZE * 2; } //////////////////////////////////////////////////////////////////////////////// // COMMAND PARSING FUNCTIONS // These functions allow parsing simple commands input on the serial port. // Commands allow reading and writing variables that control the device. // // All commands must end with a semicolon character. // // Example commands are: // GET SAMPLE_RATE_HZ; // - Get the sample rate of the device. // SET SAMPLE_RATE_HZ 400; // - Set the sample rate of the device to 400 hertz. // //////////////////////////////////////////////////////////////////////////////// void parserLoop() { // Process any incoming characters from the serial port while (Serial.available() > 0) { char c = Serial.read(); // Add any characters that aren't the end of a command (semicolon) to the input buffer. if (c != ';') { c = toupper(c); strncat(commandBuffer, &c, 1); } else { // Parse the command because an end of command token was encountered. parseCommand(commandBuffer); // Clear the input buffer memset(commandBuffer, 0, sizeof(commandBuffer)); } } } // Macro used in parseCommand function to simplify parsing get and set commands for a variable #define GET_AND_SET(variableName) \ else if (strcmp(command, "GET " #variableName) == 0) { \ Serial.println(variableName); \ } \ else if (strstr(command, "SET " #variableName " ") != NULL) { \ variableName = (typeof(variableName)) atof(command+(sizeof("SET " #variableName " ")-1)); \ } void parseCommand(char* command) { if (strcmp(command, "GET MAGNITUDES") == 0) { for (int i = 0; i < FFT_SIZE; ++i) { Serial.println(magnitudes[i]); } } else if (strcmp(command, "GET SAMPLES") == 0) { for (int i = 0; i < FFT_SIZE * 2; i += 2) { Serial.println(samples[i]); } } else if (strcmp(command, "GET FFT_SIZE") == 0) { Serial.println(FFT_SIZE); } GET_AND_SET(SAMPLE_RATE_HZ) GET_AND_SET(TONE_ERROR_MARGIN_HZ) GET_AND_SET(TONE_WINDOW_MS) GET_AND_SET(TONE_THRESHOLD_DB) }
Physical Computing’s Greatest Hits (and misses)
In this reading, the author shows various ways of already established methods of Physical Computing. They encourage the reader that instead of dismissing working on ideas that were already done, they should work on improving them and developing them more than the original creator of the concept. What I like about this, in particular, is that it hints on the idea of innovation not being “brand new” but rather “new elements in existing things”.