How to Enable Mouse Wheel Support in controlP5 on Processing 2.2

I’m finally using controlP5 in earnest, and I noticed that two-finger trackpad scrolling over a knob didn’t dial the knob, like I’d hoped it would. (Thanks to Ben Oakes, again, for showing me – just yesterday afternoon – that Ubuntu’s volume icon supports this. That was the trigger that got me wondering about this.)

It turns out controlP5 does let you turn knobs with the mouse wheel, but, for some reason, it’s disabled by default. There’s an example sketch, “ControlP5mouseWheel”, that shows how to enable it, but it doesn’t work for me with Processing 2.2. The problematic part is the addMouseWheelListener() callback that mucks with java.awt.event stuff.

Here’s a Processing 2.2-style mouseWheel callback event that gets us back to turning knobs by scrolling:

// When working in desktop mode, you can add mousewheel 
// support for controlP5 by using Processing 2.2's built-in 
// support:
void mouseWheel(MouseEvent e) {
  // Processing's `getCount()` returns 1 when the mouseWheel 
  // is rotated down, and -1 when the mouseWheel is rotated 
  // up. Natural scrolling reverses this, so you need to 
  // negate the count value. Try removing the negation, if 
  // the scrolling is backwards for you.
  cp5.setMouseWheelRotation(-e.getCount());
}

While I was at it, I noticed that controlP5 is still hosted on the retired google-code platform, so I exported it to my github account. I expect Andreas will export it to his own soon enough, and I can fork his version then, and merge in my update to the ControlP5mouseWheel example sketch.

NewHaven.IO goes to the White House

President Obama has launched an initiative called TechHire.

You can read the official version, but here’s my summary: there are lots of well-paying technology jobs, and not enough people to fill them. Those jobs could bring lower-income families firmly into the middle class, if only they could get the right skills. The jobs don’t necessarily require a four-year degree; programs like The Flatiron School and General Assembly teach people to program in months, and it seems to work: nearly all graduates are quickly hired. How can we get more people trained like this?

Part of the TechHire plan is to support “local tech community gatherings who can welcome these new students to their tech meet-ups.” They’ve partnered with Meetup.com, and Meetup reached out to growing tech-oriented Meetups – including NewHaven.IO.

Tomorrow, they’re holding a Tech Meetup at the White House, for the organizers of about 30 tech meetups to share stories, and learn from each other – and NewHaven.IO will be there. If you’d like, you can watch a livestream of the event.

As one of NewHaven.IO’s founders and organizers, I’m happy that we’ve gained enough traction to be noticed. As the current organizer of the NewHaven.io Meetup.com group, I’m excited to attend the White House tech meetup. This is my first time running such a successful volunteer organization, so, while I’m ready to share the lessons we’ve learned, I’m eager to learn from the other organizers, to hear what’s worked for them, and how they’ve served their community, so we can make NewHaven.IO even better.

Circle Pictures Redux

Back in December, I posted some images I’d made by dropping non-overlapping circles on an image, larger or smaller based on the brightness of the underlying pixel at that spot. I called them Circle Pictures.

At the time, I was happiest with the black-and-white images; I liked the color ones less. I think I’ve figured out how to make the color images work better; a lot of it comes down to picking the right kind of image to start with. (High-contrast images of recognizable objects works well, especially isolated images.) I also used a broader range of circle sizes, added borders, and played with how the circle size is decided: based on brightness, or saturation, or the amount of blue…any data in the pixel is fair game. The code is basically the same, so I won’t bother re-posting it.

Here are some of the results, including a repeat of the sunflower images. I’ll be showing prints of some of these, and some others like them, at City Wide Open Studios at the Armory space, October 11 and 12, if you’d like to see them up-close.

Here are the source images:

Image Credits

The tree is my least-favorite outcome, but the source image is from John Buchanan’s poetry site. The gorilla source image is from what looks like a Rwanda tourism site. The sea turtle source image is by digivangelist. The turtle with fish source image is from wallpapersak.com. The yellow striped fish source image is by FarzinPhoto. The sea horse source image is from this National Geographic article.

 

“A Little Ruby, a Lot of Objects,” back on line

When I was first learning Ruby, one of the resources that helped me most was Brian Marick’s “A Little Ruby, a Lot of Objects.” It’s modeled after The Little Schemer (or, if you’re older, The Little LISPer), but it uses Ruby, and teaches the core ideas of object-oriented programming in a way that helped me, even after I’d been doing OOP for 6 years. (I’m not surprised that his newer book, Functional Programming for the Object-Oriented Programmer, is just as illuminating.) The only thing I didn’t like was that it stopped after only 55 pages.

My team is about to welcome a new junior intern, and when Ben asked me for any learning resources I thought we should send, I suggested “A Little Ruby.” I have the original PDFs, but we were planning to send an email with URLs, and that’s when I realized that the book’s site, visibleworkings.com/little-ruby, was down.

I asked Brian whether I could host the files, and he agreed (thanks again!), so here they are:

A Little Ruby, A Lot of Objects

Front Matter

“My goal is to teach you a way to think about computation, to show you how far you can take a simple idea: that all computation consists of sending messages to objects.”

“The real reason for reading this book is that the ideas in it are neat.”

Chapter 1: We’ve Got Class…

The First Message: Computation is sending messages to objects.

The Second Message: Message names describe the desired result, independently of the object that provides it.

The Third Message: Classes provide interface and hide representation.

Chapter 2: …We Get It From Others

The Fourth Message: Protocols group messages into coherent sets. If two different classes implement the same protocol, programs that depend only on that protocol can use them interchangeably.

The Fifth Message: Classes define protocols for their subclasses.

The Sixth Message: If a class and its superclass have methods with the same name, the class’s methods take precedence.

The Seventh Message: Instance variables are always found in self.

Chapter 3: Turtles All The Way Down

The Eighth Message: Classes are objects with a protocol to create other objects

The Ninth Message: Methods are found by searching through lists of objects.

The Tenth Message: In computation, simple rules combine to allow complex possibilities

The Eleventh Message: Everything inherits from Object.

Two Copyright-Free Photo Collections

I’m always looking for interesting photos to hack on, so I was glad to find these two sources of free images, both via Vormplus.

New Old Stock: “vintage photos from the public archives free of known copyright restrictions.” Old photos with the fuzzy haze you’d expect. Some have no indication of age besides the color fading, but others have elements that clearly mark them as old.

Unsplash: “Free (do whatever you want) hi-resolution photos.  10 new photos every 10 days.” You can subscribe via email, too.

SuperCollider: 3 introductory posts

Scott Petersen has put together three tutorials on getting started with SuperCollider:

I’ve been reading the new Manning book on ChucK, titled  Programming for Musicians and Digital Artists, but I think ultimately I want to head to SuperCollider, and play more with overtone.

Book Review: The Information, by James Gleick

Or: “The Information: A History, a Theory, a Flood. A Review.”

Oh, I was nervous about this one.

It looked so good! Such an inviting cover, such a broad and eternally relevant topic. The Information. Rational, dispassionate. Ordered. And, “A Flood:” I half-hoped it might talk about information overload. (It does, a bit.)

But so many pages. Could I justify another pop-sci book on my To Read stack? Could I justify the time? Would it be fluff? or a difficult slog? If I’m reading for fun, I don’t want it to be harder work than what I already do for, you know, work.

Wasted worry.

The Information is a layman’s introduction to Claude Shannon’s information theory. It covers a lot of ground, and while it can be a bit slow in parts, it’s enjoyable. As a programmer, I was aware of information theory, a little, but not very clear what it was all about, or for. I was pretty sure it was lurking around behind compression, and probably positional numbering systems, especially the way they can look like dimensionality if you squint the right way, like with chmod permission bits. The Information filled in a lot of gaps for me, and showed me bridges into other fields I hadn’t expected.

Some teasers:

Gleick describes African talking drums as a way to illustrate information redundancy: two drums, high- and low-toned, mimic the tonal spoken language; drummers use long, flowery phrases to clarify ambiguity. He talks about how written language abstracts thought, and the invention of the dictionary.

He explains how information is like uncertainty or surprise. In a string of symbols (letters, music notes, numbers, bits), given a string of them, how easily can you guess the next one? If a torn piece of paper says “Kermit the Fr,” you can infer what was torn off. If I say “I got a BigMac and fries,” you can guess where I went for lunch; my adding “…at McDonald’s” doesn’t help you much – it doesn’t add much new information. (To explore this point, Claude Shannon had his wife repeatedly guess the next word in sentences from a detective novel.)

Gleick talks about information theory’s relationship to entropy. A closed system has fixed energy, but the energy dissipates: it spreads evenly throughout the system, and we can’t use it to do work. If we could re-order the energy, collect it, sort it, we could reverse entropy. Information is work.

Information is also related to computability. Sometimes, the best way to store a message is to store an algorithm for computing it.

This, in particular, is something I’d noticed. Which of these is a better way to send a smiley face? This one?


Or this one?

size(250, 250);
background(255);
noFill();
smooth();
stroke(0);
strokeWeight(5);
ellipseMode(CENTER);
ellipse(125, 125, 200, 200);
ellipse(100, 90, 10, 10);
ellipse(165, 90, 10, 10);
arc(125, 125, 100, 120, 0.2, PI - 0.2);

The first is 2D grid of pixels. The second is the code to render it: an explanation of the steps to reproduce the image.

Which is better? Which is better for making an exact copy of that image? A checkerboard, 250 squares on a side, 2502 = 62500 squares in total, and a listing of which ones should be white (about 93% of them), which should be black? Or 11 lines of text – just 222 characters? Say you had to write the message down on paper and mail it: would you rather write a list of 62500 numbers, or 11 lines of code? What would the message’s recipient have to know to reproduce the image, exactly? Pixel-for-pixel?

The Information also eventually gets into DNA, genetics, and memetics. (I never knew Richard Dawkins coined the word meme!)

So. Despite being slow in parts, the book is much better, much more enjoyable, than this review. It’ll be an enjoyable bunch of hours, and give you new ways to think about things.

(Postscript: I read this book in mid-2012, and wrote this review in October 2012, but somehow forgot to publish it. Maybe it was information overload?)

Circle Pictures

Circle Pictures

Take an image.

Pick a random pixel. Over a plain background of the same size as the image, draw a circle over that spot: bigger if it’s lighter, smaller if it’s darker. (Or reverse it: big for dark, small for light.) Repeat, but don’t overlap the circles. After a while, you’ll run out of empty places for new circles, so stop.

overlapping circles

I screwed up the math for checking circle overlaps. At first, I was thinking: pack the circles as tight as you can, so only call it an overlap when the distance between the circle centers is less than the sum of their radii.

But then, from another part of my brain, I drew the circles at half-size, forgetting that Processing’s ellipse method takes width and height parameters, not a radius. So the circles were packed less densely, and I wasn’t clever enough to see why. I hacked it, and decided to count it as an overlap when the distance is bigger than the radius of the bigger circle. (Shrug. Hack.) It worked. And it looked cool.

Eventually I figured out my bug, and fixed it, but then the circles were too dense, so I went back to the happy accident.

I also tried color images. I think there’s potential here, but I like these less.

The source images are images of Paul Erdős, Jorge Luis Borges (twice), Henri de Toulouse-Lautrec, two sunflowers, and a cow.

Here’s the source. (I tried putting it on openprocessing.org, which I normally really like, but I had troubles with the images in JavaScript mode, and they no longer support Java mode.)

PImage image;
boolean dark = true;

ArrayList circles;

// Trailing average. When the average number of tries 
// to place a circle is too high,
// stop trying.
Averager averager;

String paul = "erdos.jpg";
String jorge1 = "borges1.jpg";
String jorge2 = "borges2.jpg";
String henri = "lautrec.jpg";
String sunflower = "sunflower.jpg";
String sunflower2 = "sunflower2.jpg";
String cow = "cow.png";

void setup() {
  image = loadImage(paul);
  image.resize(600, 0);
  size(image.width, image.height);

  ellipseMode(CENTER);
  noStroke();
  smooth();

  reset();
}

void reset() {
  circles = new ArrayList();
  averager = new Averager(20);
  background(dark ? 0 : 255);
}

void draw() {
  for (int i = 0; i < 10; i++) {
    drawRandomCircle();
    if (averager.average() > 100) {
      //save("7.dark.png");
      reset();
      break;
    }
  }
}

void drawRandomCircle() {
  //println(averager.average());
  Circle circ;
  int tries = 0;
  do {
    int x = floor(random(width));
    int y = floor(random(height));

    color c = image.get(x, y);
    float val = brightness(c);

    tries++;
    float circleSize = dark ? 
         map(val, 255, 0, 1, 60) : 
         map(val, 0, 255, 1, 60);
    circ = new Circle(x, y, c, circleSize);
  }
  while (overlaps (circ));

  averager.record(tries);

  circles.add(circ);
  circ.draw();
}

boolean overlaps(Circle c) {
  for (Circle other : circles) {
    if (c.overlaps(other)) {
      return true;
    }
  }
  return false;
}

class Circle {
  int x;
  int y;
  color c;
  float diameter;

  Circle(int x, int y, color c, float diameter) {
    this.x = x;
    this.y = y;
    this.c = c;
    this.diameter = diameter;
  }

  boolean overlaps(Circle other) {
    return dist(x, y, other.x, other.y) < max(diameter, other.diameter);
  }

  void draw() {
    fill(c);
    ellipse(x, y, diameter, diameter);
  }
}

class Averager {
  float[] values;
  int index = 0;
  Averager(int length) {
    values = new float[length];
  }

  void record(float value) {
    values[index] = value;
    index = (index + 1) % values.length;
  }

  float average() {
    float sum = 0;
    for (float val : values) {
      sum += val;
    }
    return sum / values.length;
  }
}