# Speech Bubbles Process

How to edit Wiki pages: See the Wikipedia editing cheat sheet.

## Emulating Rivane Neuenschwander's work with speech bubbles

Original work:

Rivane Neuenschwander's work

### Creating "Comic" Panels

#### First Work

[Creating comic panels: http://sophia.smith.edu/~nmaller/bubbles/1/coloredsquares.html]

#### Comic Panels with Ellipses

[Comic panels with random ellipses: http://sophia.smith.edu/~nmaller/bubbles/1/coloredsquares2.html]

```  (Note: The applet is not currently working)
```

#### Generating Panels on Multiple Rows

This started with a looping program created by Professor O'Rourke. For more information on the 6-panel program, refer to section 3: [1]

The next version of multiple panels had two goals: To choose a random number of panels, and then to divide the panels into rows. The maximum number of panels chosen is nine; the max number of panels allowed on a row would be three. If the number of panels was not divisible by three, the last row would divide its panels randomly between the space.

##### Issue: Determining panel placement

The problem of getting the panels to smoothly divide themselves between an un-fixed window size was solved by using cases. The function "PaintPanel" was created in order to create the colors and later the images within the panel as well. The final code of the panel section looked as follows:

```int Case = (panelNum % 3); // Case 1 means 1 panel in last row // Case 2 means 2 panels // Case 0 means last row is filled. println("Case = " + Case ); // i runs over the # of panels for( int i=0; i < panelNum; i++ ) { // row is i / 3 discarding remainder, which is what int / does. // col is the remainder, which is what the % operator. int row = i / 3; int col = i % 3; println("**** PANEL NUMBER i=" + i + " row=" + row + " col=" + col); if ( panelNum / 3 == row ) { // if you're on the last row... print("Last row"); if ( Case == 0 ) { //...and the last row is filled with three panels... println(" Case0"); PaintPanel(speechBubbles, nimages, col * panel, row * panel, panel, panel, Color[int(random(0,15))]); } if ( Case == 1 ) { //...but if there's 1 panel... println(" Case1"); PaintPanel(speechBubbles, nimages, col * panel, row * panel, 3*panel, panel, Color[int(random(0,15))]); } if ( Case == 2 ){ println(" Case2"); int randWidth = int(random(90,width-90)); int secondWidth = (width - (randWidth)); println("randWidth=" + randWidth + " secondWidth=" + secondWidth); PaintPanel(speechBubbles, nimages, col * panel, row * panel, randWidth, panel, Color[int(random(0,15))]); PaintPanel(speechBubbles, nimages, randWidth, row * panel, secondWidth, panel, Color[int(random(0,15))]); i = panelNum; // to force loop to end? } } else PaintPanel(speechBubbles, nimages, col * panel, row * panel, panel, panel, Color[int(random(0,15))]); } } ```

### Random Panels with Ellipses

Code does not translate to a java applet well. Instead, here is the code: [2].

Multiple Panels with Ellipses

### Panels With Images

#### Creating the Images

Original tests were done using ellipses, but it was quickly determined that manually drawing bubble shapes would be difficult and time-consuming. Instead, I created around 25 bubble images, saved as transparent GIFs, to place into an image array. The GIFs were derived from a series of “speech bubble” Photoshop brushes distributed for free online on the website Deviant Art. The final images used were brushes created by DeviantArt user “filmowe,” which can be found here: [3]

#### First Version

The first version only has one image, drawn directly on top of the painted panels, without being placed in an array or within the boundaries of one panel.

Speech Bubbles Sample

## Exploring Processing

### Random Ellipses

My (JOR's) first Processing program. :-)

```size(500, 500); background(200,0,100); stroke(255,255,255); fill(0,0,100); int n = 20; for (int i=0; i < 20; i++) { float x = random(width); float y = random(height); ellipse(x, y, random(75,125), random(40,60)); } save("ellipses.jpg"); ```
Random Ellipses

```PImage img; void setup(){ size(400,300); img = loadImage("GreenSphere.gif"); } void draw(){ background(0); image(img,0,0); } ```

Interesting. size() is the size of the window displayed, not the size of the image. It is displayed with its native aspect ratio. Need to learn how to query image size.

### Panels in a Loop

```int panel = 200; // square panel dimension void setup(){ size(600,400); // Fill up color array. 6 colors for now. Use color() to create color types. color Color[] = { color(10,20,30), color(40,50,60), color(70,80,90), color(100,110,120), color(130,140,150), color(160,170,180) }; int n = 6; // Number of panels. // i runs over the # of panels for( int i=0; i < n; i++ ) { // row is i/3 with remainder discarded, which is what / does to ints. // col is the remainder upon division by 3, which is what % yields. int row = i / 3; int col = i % 3; println("i=" + i + " row=" + row + " col=" + col); PaintPanel(col * panel, row * panel, Color[i]); } } // Paint a panel starting at upperleft corner x,y, in color c. void PaintPanel(int x, int y, color c) { fill( c ); rect(x, y, panel, panel); } ```
Six Panels

### 24 March 2010

This is a screen snapshot. The code seems to be working. One function computes the overlap in pixels, and then some extra calculations turn it into a percentage overlap, suitable for thresholding (e.g., at 25%). The full code is here: RectangleIntersection. Will need to //-comment out some debugging printout eventually.

Rectangle Intersection code computing overlap