Pixel Manipulation

Using the p5.js image object’s pixel array, I attempted a number of different image manipulations:

reduceColors():  in lieu of a proper “posterize” effect — one which finds a set of color averages from the value and frequency of each color in the image — this function simply maps each pixel’s color to a reduced set of possible colors.

Original Image:

  

thresholdChange(): this function takes three thresholds (one for each color value) and takes any value above that threshold in each pixel, and bumps it up to 255:

Finally, I made a slightly different version of the pointillism effect from class, using a different method to iterate through the pixels.  As in all of my functions this week, speed became an issue and I began to understand why certain techniques (such as using modulo to spread the load out across multiple frames) allow an animation to run much faster despite the appearance being nearly identical.

Setting up a github workflow:

Finally, I spent some time this week following along with this set of videos and spent some time figuring out how to work locally using the command line tool http-server and store code in github.  While it doesn’t appear much different to me now than Dropbox / Google Drive / etc.,  I imagine once I begin working on more collaborative coding projects, that will change.

ICMadness!

With a little over an hour, and a random prompt, Sandy, Luna and I attempted to make “a project about hope which writes a letter using the microphone.”  As you speak into the microphone, the quote (from this Junot Diaz article in The New Yorker) appears above a hopeful video of people helping each other in the recent Hurricane Harvey in Houston.

You can see our project among the others here.

One Year of Citibiking

This week’s project is an attempt to visualize a year’s worth of my Citi Bike trip history.  I chose to do this because I use the Citi Bike bike sharing system often (>500 times within the last year) and wanted to learn to work with maps and mapping APIs in javascript.  The end result is an animation from October 2016 to October 2017 displaying all rides as they happen.

Wish List:

  • Trips should display the full route as pulled from Google Maps’ Directions API.  This was partially implemented, but not finished.
  • Regular commuting routes should appear increasingly visible as the number of times they’ve been ridden increases.  I didn’t know whether to implement this by associating stations with a times-visited variable, or to make this happen visibly by drawing everything at a low alpha level, and having the stacking make it happen.

Data Sources:

The data for this project came from a few different places and in a few different formats:

  • I found my ride history on the Citi Bike website within the “Trips” menu (after I had logged in).  Unfortunately, this data did not come quite as neatly organized as I had hoped.  The “Export” function opened a web page from which I could copy and paste the data into a text file.  The individual trip datum (trip starting time, trip starting station, etc.) were separated by newlines, and each block of 5 lines made up the available data about a single trip.
     
    I pulled a year’s worth of ride data (the maximum amount allowed at once) from this web interface, and copied it into a text file.  In my P5.js sketch, I use the loadStrings() function to separate this text into an array of strings, each composing a single line, and use a callback function to place each string into a Trip object and add that object to an array of Trip objects.
  • Citibike station information is made available in JSON format through the Citibike API, and contains, among other things, the name, latitude and longitude of each Citibike station.  Because the trip information I had downloaded did not contain the latitude and longitude, this would be vital to map any of my trips.  I loaded this information into my sketch using the loadJSON() function, using a callback function to add the name, latitude and longitude of each station into a Station object, which I then added into an array of Station Objects.

Code Organization:

  • There was a great degree of trial and error in my code organization.  As I slowly realized why certain organizational strategies made better logical sense and required less debugging, I would rewrite portions of my code to match these understandings.  At this point, trip and station data are stored separately in their own objects.  I would ideally like to have one set of trip objects, which contains all trip related information, including route data pulled from the Google Maps Directions API.  Unfortunately, when I tried to merge data from the two relatively large (>500 points each) arrays of objects (trips and stations), I ran into infinite loop errors.  Eventually I realized that this error was from the editor, and managed to solve it by switching to an offline text editor and using http-server to test my code.
  • I used the javascript Date() object to compare dates between the (somewhat confusingly named) “now” variable — which refers to the current time of the animation — and the start and end times of each trip.  The Date.parse() function managed to pull data from the Citi Bike trips textfile in the format “09/28/2017 7:54:16 AM” so that I could compare the two using boolean operators.
  • Google Maps Directions: I used the Google Maps Directions API, along with the origin and destination coordinates of Citi Bike stations, to pull route data.
  • All latitude/longitude to X,Y coordinate conversions were done using the Mappa library’s “latLngToPixel()” function.

ICM Week 4: Bouncing (and Disappearing!) Balloons

This week was a challenge to place all of our p5.js sketch’s functionality within functions defined outside of the main draw loop. My sketch (a variation on the bouncing balloon we made in previous weeks) placed all functionality within ball objects created every time the mouse is clicked.

In addition to the standard functionality (bouncing, moving, drawing), I attempted to add several other features (some successfully, many not).  Please note that the balls are called ‘magnets’ because I originally wanted them to attract and repel based on their N&S poles, but this proved a bit too complicated for this week’s project.

  • WORKS: Every 200 frames, the balls reverse direction,
  • WORKS: When the balls approach their ‘birthplace,’ they disappear (are spliced from the ball array),
  • WORKS: A new ball object is created at mouseX,mouseY when the mouse is clicked,
  • DOES NOT WORK: Repelling function, which would have each ball adjust its speed to avoid other balls,
  • DOES NOT WORK: Gravity (updateSpeed) function, which would update each ball’s yspeed based on a function which mimicked gravity…

Below is the current status of the code:

And the sketch in the editor.

AC Power Visualizer / Sharing Code

Alternating Current Visualizer

A few weeks ago, I was speaking with a co-worker and trying to understand a few aspects of the power distribution system in place in our theater.  I understood that most power transmission lines carry three phases of alternating current, and that typical household power contains only a single phase of 120V at 60 Hertz, but I didn’t understand how we managed to make usable 240V out of two phases of 120V. After digging a bit, it became clear that this system used two directly out of phase 120V circuits to create a 240V potential between the two “hot” phases, each of which was only 120V from ground. Still, several aspects of our power distribution system remain somewhat confusing to me, so for this week’s ICM project, I attempted to make a p5.js sketch able to visualize the various waveforms of alternating current.

As this project progressed, I quickly realized the complexity I could build into it given time. I began by figuring out how to continuously redraw a sine wave using a series of nested for-loops: once for each phase of power, then once for each point along that wave. Within the for-loop designated with actually drawing the sine wave, I calculated a line to be drawn between a previous point and a newly calculated by y=sin(x) with a precision factor and a scaling factor added for both x and y, then drew the actual line:


//create the sine wave at several separate phases
for (let j = 0; j < phaseQty; j++) { 
//reset previous x and y to starting point 
//formula for previous y is same as formula for making sine wave at x=0 
px = 0; 
py = -sin(j * phaseOffset - rOffset) * yScale; 

//in every phase instance, run from x=0 to x

The full version of this sketch can be found here!

Sharing Code

The second part of this week’s assignment involved sharing code with a classmate.  Having never shared code before, I was surprised how difficult it can be to figure out what is going on in someone else’s code!  Even after running the code and seeing the output, it took some time to dig into the specific causes and effects within the code.  Especially difficult were:

  • ambiguously named variables
  • related sections of code that weren’t physically near each other
  • long formulas or boolean statements

It is quickly becoming obvious why code semantics and style are so important for anything more complex than these ~100 line sketches we are working on!

That said, after delving into how my partner’s code worked, I began playing with altering it aesthetically and functionally.  Below are my partner’s code output and mine:

ICM Week 2

For week two, I had big ambitions, and somewhat less exciting results.  My ambitions were twofold:

  1. to create an interactive animation that allowed someone to use the mouse to blow up a balloon, then have it float away when released, and
  2. (at someone’s very kind suggestion) to have a mouse click make a progressively larger ball, which, on a mouse release, would drop down at a rate in accordance with its size.

The question I didn’t manage to overcome in both of these scenarios was this: how to keep track of the balloon or bowling ball after if has been dropped?  How can I have two states: one in which the ball is held by the mouse, the other in which the ball is free to float / drop.  Additionally, because I would like to give the user the ability to blow up multiple balls, how can I keep track of /keep redrawing these multiple separate shapes when the number of shapes is not pre-determined? I believe the answer revolves around a list (of coordinates) and a for loop, but I wasn’t entirely sure how to implement this.

So, what I have is a somewhat less dynamic animation, which allows the user to create circles of progressively larger size as they hold down their mouse, of a fill color determined by their location, and on a background that is randomly generated.  Maybe next week I can move a little further towards combining multiple elements (user created ball, gravity, multiple balls).

Original: http://alpha.editor.p5js.org/embed/Bk4jJnF5-

 

p5.js Drawing

Computation as a tool is most exciting to me in its ability to facilitate real-world experiences — to build some level of intelligence or reactivity into passive objects.  By adding a layer of software between cameras, microphones, and other sensors, and lights, motors, and speakers, we can imbue these unthinking inputs and outputs with the ability to understand and react to their surroundings.  This can feel very close to magic!

One project that excites me is this Arduino-based motor controller for a telescope mount.  It allows a telescope to be positioned through a computer for star tracking and astro-photography.  The concept isn’t terribly complex, and all of the math relating to converting celestial coordinates into Earth based coordinates has long since been figured out, but the project’s (apparently) comprehensive and elegant execution allows an amateur astronomer to capture incredible images of deep space objects.

Another computing project which allows amateurs to use simple and cheap hardware to explore a previously hidden part of their world is Software Defined Radio.  This uses a simple radio receiver with an analog-digital converter and open source software to allow amateurs access to broad swathes of the radio spectrum.  I have been able to listen to Radio Cuba on shortwave as well as my local ham enthusiasts with about $25 dollars worth of equipment.

I would like to use computation to build real-world experiences which give previously passive objects some level of intelligence and understanding.

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Above is my first drawing made in the p5.js javascript library.  It is composed entirely of 2D shapes (triangles, ellipses, and curved lines) with some adjustments in the stroke weight and color throughout.  The most challenging part was trying to remember which coordinate I was defining in which parameter of the various functions.  In the curves especially (in which you define 4 coordinates for a total of 8 parameters) it would have been helpful to have the parameter names x1,y1, etc. auto-populate after entering the function.  Another fun feature for the editor would be the ability to click on the preview section and have the x,y coordinates of your mouse click appear onscreen.