mirror of
https://github.com/processing/processing4.git
synced 2026-06-16 04:26:26 +02:00
moving examples to hang out with their libraries
This commit is contained in:
@@ -0,0 +1,42 @@
|
||||
/**
|
||||
* Add Listener
|
||||
* by Damien Di Fede.
|
||||
*
|
||||
* This sketch demonstrates how to use the <code>addListener</code> method of a <code>Recordable</code> class.
|
||||
* The class used here is <code>AudioPlayer</code>, but you can also add listeners to <code>AudioInput</code>,
|
||||
* <code>AudioOutput</code>, and <code>AudioSample</code> objects. The class defined in waveform.pde implements
|
||||
* the <code>AudioListener</code> interface and can therefore be added as a listener to <code>groove</code>.
|
||||
*/
|
||||
|
||||
import ddf.minim.*;
|
||||
|
||||
Minim minim;
|
||||
AudioPlayer groove;
|
||||
WaveformRenderer waveform;
|
||||
|
||||
void setup()
|
||||
{
|
||||
size(512, 200, P2D);
|
||||
|
||||
minim = new Minim(this);
|
||||
groove = minim.loadFile("groove.mp3", 512);
|
||||
groove.loop();
|
||||
waveform = new WaveformRenderer();
|
||||
groove.addListener(waveform);
|
||||
}
|
||||
|
||||
void draw()
|
||||
{
|
||||
background(0);
|
||||
// see waveform.pde for an explanation of how this works
|
||||
waveform.draw();
|
||||
}
|
||||
|
||||
void stop()
|
||||
{
|
||||
// always close Minim audio classes when you are done with them
|
||||
groove.close();
|
||||
// always stop Minim before exiting.
|
||||
minim.stop();
|
||||
super.stop();
|
||||
}
|
||||
+76
@@ -0,0 +1,76 @@
|
||||
// This class is a very simple implementation of AudioListener. By implementing this interface,
|
||||
// you can add instances of this class to any class in Minim that implements Recordable and receive
|
||||
// buffers of samples in a callback fashion. In other words, every time that a Recordable object has
|
||||
// a new buffer of samples, it will send a copy to all of its AudioListeners. You can add an instance of
|
||||
// an AudioListener to a Recordable by using the addListener method of the Recordable. If you want to
|
||||
// remove a listener that you previously added, you call the removeListener method of Recordable, passing
|
||||
// the listener you want to remove.
|
||||
//
|
||||
// Although possible, it is not advised that you add the same listener to more than one Recordable.
|
||||
// Your listener will be called any time any of the Recordables you've added it have new samples. This
|
||||
// means that the stream of samples the listener sees will likely be interleaved buffers of samples from
|
||||
// all of the Recordables it is listening to, which is probably not what you want.
|
||||
//
|
||||
// You'll notice that the three methods of this class are synchronized. This is because the samples methods
|
||||
// will be called from a different thread than the one instances of this class will be created in. That thread
|
||||
// might try to send samples to an instance of this class while the instance is in the middle of drawing the
|
||||
// waveform, which would result in a waveform made up of samples from two different buffers. Synchronizing
|
||||
// all the methods means that while the main thread of execution is inside draw, the thread that calls
|
||||
// samples will block until draw is complete. Likewise, a call to draw will block if the sample thread is inside
|
||||
// one of the samples methods. Hope that's not too confusing!
|
||||
|
||||
class WaveformRenderer implements AudioListener
|
||||
{
|
||||
private float[] left;
|
||||
private float[] right;
|
||||
|
||||
WaveformRenderer()
|
||||
{
|
||||
left = null;
|
||||
right = null;
|
||||
}
|
||||
|
||||
synchronized void samples(float[] samp)
|
||||
{
|
||||
left = samp;
|
||||
}
|
||||
|
||||
synchronized void samples(float[] sampL, float[] sampR)
|
||||
{
|
||||
left = sampL;
|
||||
right = sampR;
|
||||
}
|
||||
|
||||
synchronized void draw()
|
||||
{
|
||||
// we've got a stereo signal if right or left are not null
|
||||
if ( left != null && right != null )
|
||||
{
|
||||
noFill();
|
||||
stroke(255);
|
||||
beginShape();
|
||||
for ( int i = 0; i < left.length; i++ )
|
||||
{
|
||||
vertex(i, height/4 + left[i]*50);
|
||||
}
|
||||
endShape();
|
||||
beginShape();
|
||||
for ( int i = 0; i < right.length; i++ )
|
||||
{
|
||||
vertex(i, 3*(height/4) + right[i]*50);
|
||||
}
|
||||
endShape();
|
||||
}
|
||||
else if ( left != null )
|
||||
{
|
||||
noFill();
|
||||
stroke(255);
|
||||
beginShape();
|
||||
for ( int i = 0; i < left.length; i++ )
|
||||
{
|
||||
vertex(i, height/2 + left[i]*50);
|
||||
}
|
||||
endShape();
|
||||
}
|
||||
}
|
||||
}
|
||||
Binary file not shown.
@@ -0,0 +1,71 @@
|
||||
/**
|
||||
* Band Pass Filter
|
||||
* by Damien Di Fede.
|
||||
*
|
||||
* This sketch demonstrates how to use the BandPass effect.
|
||||
* Move the mouse left and right to change the frequency of the pass band.
|
||||
* Move the mouse up and down to change the band width of the pass band.
|
||||
*/
|
||||
|
||||
import ddf.minim.*;
|
||||
import ddf.minim.effects.*;
|
||||
|
||||
Minim minim;
|
||||
AudioPlayer groove;
|
||||
BandPass bpf;
|
||||
|
||||
void setup()
|
||||
{
|
||||
size(512, 200, P2D);
|
||||
|
||||
minim = new Minim(this);
|
||||
|
||||
groove = minim.loadFile("groove.mp3");
|
||||
groove.loop();
|
||||
// make a band pass filter with a center frequency of 440 Hz and a bandwidth of 20 Hz
|
||||
// the third argument is the sample rate of the audio that will be filtered
|
||||
// it is required to correctly compute values used by the filter
|
||||
bpf = new BandPass(440, 20, groove.sampleRate());
|
||||
groove.addEffect(bpf);
|
||||
}
|
||||
|
||||
void draw()
|
||||
{
|
||||
background(0);
|
||||
stroke(255);
|
||||
// draw the waveforms
|
||||
// the values returned by left.get() and right.get() will be between -1 and 1,
|
||||
// so we need to scale them up to see the waveform
|
||||
for(int i = 0; i < groove.right.size()-1; i++)
|
||||
{
|
||||
float x1 = map(i, 0, groove.bufferSize(), 0, width);
|
||||
float x2 = map(i+1, 0, groove.bufferSize(), 0, width);
|
||||
line(x1, height/4 - groove.left.get(i)*50, x2, height/4 - groove.left.get(i+1)*50);
|
||||
line(x1, 3*height/4 - groove.right.get(i)*50, x2, 3*height/4 - groove.right.get(i+1)*50);
|
||||
}
|
||||
// draw a rectangle to represent the pass band
|
||||
noStroke();
|
||||
fill(255, 0, 0, 60);
|
||||
rect(mouseX - bpf.getBandWidth()/20, 0, bpf.getBandWidth()/10, height);
|
||||
}
|
||||
|
||||
void mouseMoved()
|
||||
{
|
||||
// map the mouse position to the range [100, 10000], an arbitrary range of passBand frequencies
|
||||
float passBand = map(mouseX, 0, width, 100, 2000);
|
||||
bpf.setFreq(passBand);
|
||||
float bandWidth = map(mouseY, 0, height, 50, 500);
|
||||
bpf.setBandWidth(bandWidth);
|
||||
// prints the new values of the coefficients in the console
|
||||
bpf.printCoeff();
|
||||
}
|
||||
|
||||
void stop()
|
||||
{
|
||||
// always close Minim audio classes when you finish with them
|
||||
groove.close();
|
||||
// always stop Minim before exiting
|
||||
minim.stop();
|
||||
|
||||
super.stop();
|
||||
}
|
||||
Binary file not shown.
+75
@@ -0,0 +1,75 @@
|
||||
/**
|
||||
* Forward FFT
|
||||
* by Damien Di Fede.
|
||||
*
|
||||
* This sketch demonstrates how to use an FFT to analyze an AudioBuffer
|
||||
* and draw the resulting spectrum. It also allows you to turn windowing
|
||||
* on and off, but you will see there is not much difference in the spectrum.
|
||||
* Press 'w' to turn on windowing, press 'e' to turn it off.
|
||||
*/
|
||||
|
||||
import ddf.minim.analysis.*;
|
||||
import ddf.minim.*;
|
||||
|
||||
Minim minim;
|
||||
AudioPlayer jingle;
|
||||
FFT fft;
|
||||
String windowName;
|
||||
|
||||
void setup()
|
||||
{
|
||||
size(512, 200);
|
||||
minim = new Minim(this);
|
||||
|
||||
jingle = minim.loadFile("jingle.mp3", 2048);
|
||||
jingle.loop();
|
||||
// create an FFT object that has a time-domain buffer the same size as jingle's sample buffer
|
||||
// note that this needs to be a power of two and that it means the size of the spectrum
|
||||
// will be 512. see the online tutorial for more info.
|
||||
fft = new FFT(jingle.bufferSize(), jingle.sampleRate());
|
||||
textFont(createFont("SanSerif", 12));
|
||||
windowName = "None";
|
||||
}
|
||||
|
||||
void draw()
|
||||
{
|
||||
background(0);
|
||||
stroke(255);
|
||||
// perform a forward FFT on the samples in jingle's left buffer
|
||||
// note that if jingle were a MONO file, this would be the same as using jingle.right or jingle.left
|
||||
fft.forward(jingle.mix);
|
||||
for(int i = 0; i < fft.specSize(); i++)
|
||||
{
|
||||
// draw the line for frequency band i, scaling it by 4 so we can see it a bit better
|
||||
line(i, height, i, height - fft.getBand(i)*4);
|
||||
}
|
||||
fill(255);
|
||||
// keep us informed about the window being used
|
||||
text("The window being used is: " + windowName, 5, 20);
|
||||
}
|
||||
|
||||
void keyReleased()
|
||||
{
|
||||
if ( key == 'w' )
|
||||
{
|
||||
// a Hamming window can be used to shape the sample buffer that is passed to the FFT
|
||||
// this can reduce the amount of noise in the spectrum
|
||||
fft.window(FFT.HAMMING);
|
||||
windowName = "Hamming";
|
||||
}
|
||||
|
||||
if ( key == 'e' )
|
||||
{
|
||||
fft.window(FFT.NONE);
|
||||
windowName = "None";
|
||||
}
|
||||
}
|
||||
|
||||
void stop()
|
||||
{
|
||||
// always close Minim audio classes when you finish with them
|
||||
jingle.close();
|
||||
minim.stop();
|
||||
|
||||
super.stop();
|
||||
}
|
||||
Binary file not shown.
@@ -0,0 +1,22 @@
|
||||
class BeatListener implements AudioListener
|
||||
{
|
||||
private BeatDetect beat;
|
||||
private AudioPlayer source;
|
||||
|
||||
BeatListener(BeatDetect beat, AudioPlayer source)
|
||||
{
|
||||
this.source = source;
|
||||
this.source.addListener(this);
|
||||
this.beat = beat;
|
||||
}
|
||||
|
||||
void samples(float[] samps)
|
||||
{
|
||||
beat.detect(source.mix);
|
||||
}
|
||||
|
||||
void samples(float[] sampsL, float[] sampsR)
|
||||
{
|
||||
beat.detect(source.mix);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
/**
|
||||
* Frequency Energy
|
||||
* by Damien Di Fede.
|
||||
*
|
||||
* This sketch demonstrates how to use the BeatDetect object in FREQ_ENERGY mode.
|
||||
* You can use <code>isKick</code>, <code>isSnare</code>, </code>isHat</code>,
|
||||
* <code>isRange</code>, and <code>isOnset(int)</code> to track whatever kind
|
||||
* of beats you are looking to track, they will report true or false based on
|
||||
* the state of the analysis. To "tick" the analysis you must call <code>detect</code>
|
||||
* with successive buffers of audio. You can do this inside of <code>draw</code>,
|
||||
* but you are likely to miss some audio buffers if you do this. The sketch implements
|
||||
* an <code>AudioListener</code> called <code>BeatListener</code> so that it can call
|
||||
* <code>detect</code> on every buffer of audio processed by the system without repeating
|
||||
* a buffer or missing one.
|
||||
*
|
||||
* This sketch plays an entire song so it may be a little slow to load.
|
||||
*/
|
||||
|
||||
import ddf.minim.*;
|
||||
import ddf.minim.analysis.*;
|
||||
|
||||
Minim minim;
|
||||
AudioPlayer song;
|
||||
BeatDetect beat;
|
||||
BeatListener bl;
|
||||
|
||||
float kickSize, snareSize, hatSize;
|
||||
|
||||
void setup()
|
||||
{
|
||||
size(512, 200);
|
||||
smooth();
|
||||
|
||||
minim = new Minim(this);
|
||||
|
||||
song = minim.loadFile("marcus_kellis_theme.mp3", 2048);
|
||||
song.play();
|
||||
// a beat detection object that is FREQ_ENERGY mode that
|
||||
// expects buffers the length of song's buffer size
|
||||
// and samples captured at songs's sample rate
|
||||
beat = new BeatDetect(song.bufferSize(), song.sampleRate());
|
||||
// set the sensitivity to 300 milliseconds
|
||||
// After a beat has been detected, the algorithm will wait for 300 milliseconds
|
||||
// before allowing another beat to be reported. You can use this to dampen the
|
||||
// algorithm if it is giving too many false-positives. The default value is 10,
|
||||
// which is essentially no damping. If you try to set the sensitivity to a negative value,
|
||||
// an error will be reported and it will be set to 10 instead.
|
||||
beat.setSensitivity(300);
|
||||
kickSize = snareSize = hatSize = 16;
|
||||
// make a new beat listener, so that we won't miss any buffers for the analysis
|
||||
bl = new BeatListener(beat, song);
|
||||
textFont(createFont("SanSerif", 16));
|
||||
textAlign(CENTER);
|
||||
}
|
||||
|
||||
void draw()
|
||||
{
|
||||
background(0);
|
||||
fill(255);
|
||||
if ( beat.isKick() ) kickSize = 32;
|
||||
if ( beat.isSnare() ) snareSize = 32;
|
||||
if ( beat.isHat() ) hatSize = 32;
|
||||
textSize(kickSize);
|
||||
text("KICK", width/4, height/2);
|
||||
textSize(snareSize);
|
||||
text("SNARE", width/2, height/2);
|
||||
textSize(hatSize);
|
||||
text("HAT", 3*width/4, height/2);
|
||||
kickSize = constrain(kickSize * 0.95, 16, 32);
|
||||
snareSize = constrain(snareSize * 0.95, 16, 32);
|
||||
hatSize = constrain(hatSize * 0.95, 16, 32);
|
||||
}
|
||||
|
||||
void stop()
|
||||
{
|
||||
// always close Minim audio classes when you are finished with them
|
||||
song.close();
|
||||
// always stop Minim before exiting
|
||||
minim.stop();
|
||||
// this closes the sketch
|
||||
super.stop();
|
||||
}
|
||||
Binary file not shown.
+70
@@ -0,0 +1,70 @@
|
||||
/**
|
||||
* Get Line In
|
||||
* by Damien Di Fede.
|
||||
*
|
||||
* This sketch demonstrates how to use the <code>getLineIn</code> method of
|
||||
* <code>Minim</code>. This method returns an <code>AudioInput</code> object.
|
||||
* An <code>AudioInput</code> represents a connection to the computer's current
|
||||
* record source (usually the line-in) and is used to monitor audio coming
|
||||
* from an external source. There are five versions of <code>getLineIn</code>:
|
||||
* <pre>
|
||||
* getLineIn()
|
||||
* getLineIn(int type)
|
||||
* getLineIn(int type, int bufferSize)
|
||||
* getLineIn(int type, int bufferSize, float sampleRate)
|
||||
* getLineIn(int type, int bufferSize, float sampleRate, int bitDepth)
|
||||
* </pre>
|
||||
* The value you can use for <code>type</code> is either <code>Minim.MONO</code>
|
||||
* or <code>Minim.STEREO</code>. <code>bufferSize</code> specifies how large
|
||||
* you want the sample buffer to be, <code>sampleRate</code> specifies the
|
||||
* sample rate you want to monitor at, and <code>bitDepth</code> specifies what
|
||||
* bit depth you want to monitor at. <code>type</code> defaults to <code>Minim.STEREO</code>,
|
||||
* <code>bufferSize</code> defaults to 1024, <code>sampleRate</code> defaults to
|
||||
* 44100, and <code>bitDepth</code> defaults to 16. If an <code>AudioInput</code>
|
||||
* cannot be created with the properties you request, <code>Minim</code> will report
|
||||
* an error and return <code>null</code>.
|
||||
*
|
||||
* When you run your sketch as an applet you will need to sign it in order to get an input.
|
||||
*
|
||||
* Before you exit your sketch make sure you call the <code>close</code> method
|
||||
* of any <code>AudioInput</code>'s you have received from <code>getLineIn</code>.
|
||||
*/
|
||||
|
||||
import ddf.minim.*;
|
||||
|
||||
Minim minim;
|
||||
AudioInput in;
|
||||
|
||||
void setup()
|
||||
{
|
||||
size(512, 200, P2D);
|
||||
|
||||
minim = new Minim(this);
|
||||
minim.debugOn();
|
||||
|
||||
// get a line in from Minim, default bit depth is 16
|
||||
in = minim.getLineIn(Minim.STEREO, 512);
|
||||
}
|
||||
|
||||
void draw()
|
||||
{
|
||||
background(0);
|
||||
stroke(255);
|
||||
|
||||
// draw the waveforms
|
||||
for(int i = 0; i < in.bufferSize() - 1; i++)
|
||||
{
|
||||
line(i, 50 + in.left.get(i)*50, i+1, 50 + in.left.get(i+1)*50);
|
||||
line(i, 150 + in.right.get(i)*50, i+1, 150 + in.right.get(i+1)*50);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void stop()
|
||||
{
|
||||
// always close Minim audio classes when you are done with them
|
||||
in.close();
|
||||
minim.stop();
|
||||
|
||||
super.stop();
|
||||
}
|
||||
+72
@@ -0,0 +1,72 @@
|
||||
/**
|
||||
* Get Line Out
|
||||
* by Damien Di Fede.
|
||||
*
|
||||
* This sketch demonstrates how to use the <code>getLineOut</code> method
|
||||
* of <code>Minim</code>. This method returns an <code>AudioOutput</code>
|
||||
* object. An <code>AudioOutput</code> represents a connection to the
|
||||
* computer's speakers and is used to generate audio with <code>AudioSignal</code>s.
|
||||
* There are five versions of <code>getLineOut</code>:
|
||||
* <pre>
|
||||
* getLineOut()
|
||||
* getLineOut(int type)
|
||||
* getLineOut(int type, int bufferSize)
|
||||
* getLineOut(int type, int bufferSize, float sampleRate)
|
||||
* getLineOut(int type, int bufferSize, float sampleRate, int bitDepth)
|
||||
* </pre>
|
||||
* The value you can use for <code>type</code> is either <code>Minim.MONO</code>
|
||||
* or <code>Minim.STEREO</code>. <code>bufferSize</code> specifies how large
|
||||
* you want the sample buffer to be, <code>sampleRate</code> specifies what
|
||||
* the sample rate of the audio you will be generating is, and <code>bitDepth</code>
|
||||
* specifies what the bit depth of the audio you will be generating is (8 or 16).
|
||||
* <code>type</code> defaults to <code>Minim.STEREO</code>, <code>bufferSize</code>
|
||||
* defaults to 1024, <code>sampleRate</code> defaults to 44100, and
|
||||
* <code>bitDepth</code> defaults to 16.
|
||||
*
|
||||
* Before you exit your sketch make sure you call the <code>close</code>
|
||||
* method of any <code>AudioOutput</code>'s you have received from <code>getLineOut</code>.
|
||||
*/
|
||||
|
||||
import ddf.minim.*;
|
||||
import ddf.minim.signals.*;
|
||||
|
||||
Minim minim;
|
||||
AudioOutput out;
|
||||
SineWave sine;
|
||||
|
||||
void setup()
|
||||
{
|
||||
size(512, 200, P2D);
|
||||
|
||||
minim = new Minim(this);
|
||||
|
||||
// get a line out from Minim, default sample rate is 44100, default bit depth is 16
|
||||
out = minim.getLineOut(Minim.STEREO, 2048);
|
||||
|
||||
// create a sine wave Oscillator, set to 440 Hz, at 0.5 amplitude, sample rate 44100 to match the line out
|
||||
sine = new SineWave(440, 0.5, out.sampleRate());
|
||||
// add the oscillator to the line out
|
||||
out.addSignal(sine);
|
||||
}
|
||||
|
||||
void draw()
|
||||
{
|
||||
background(0);
|
||||
stroke(255);
|
||||
// draw the waveforms
|
||||
for(int i = 0; i < out.bufferSize() - 1; i++)
|
||||
{
|
||||
line(i, 50 + out.left.get(i)*50, i+1, 50 + out.left.get(i+1)*50);
|
||||
line(i, 150 + out.right.get(i)*50, i+1, 150 + out.right.get(i+1)*50);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void stop()
|
||||
{
|
||||
// always close Minim audio classes when you are done with them
|
||||
out.close();
|
||||
minim.stop();
|
||||
|
||||
super.stop();
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
/**
|
||||
* Get Meta Data
|
||||
* by Damien Di Fede.
|
||||
*
|
||||
* This sketch demonstrates how to use the <code>getMetaData</code>
|
||||
* method of <code>AudioPlayer</code>. This method is also available
|
||||
* for <code>AudioSnippet</code> and <code>AudioSample</code>.
|
||||
* You should use this method when you want to retrieve metadata
|
||||
* about a file that you have loaded, like ID3 tags from an mp3 file.
|
||||
* If you load WAV file or other non-tagged file, most of the metadata
|
||||
* will be empty, but you will still have information like the filename
|
||||
* and the length.
|
||||
*/
|
||||
|
||||
import ddf.minim.*;
|
||||
|
||||
Minim minim;
|
||||
AudioPlayer groove;
|
||||
AudioMetaData meta;
|
||||
|
||||
void setup()
|
||||
{
|
||||
size(512, 256, P2D);
|
||||
|
||||
minim = new Minim(this);
|
||||
groove = minim.loadFile("groove.mp3");
|
||||
meta = groove.getMetaData();
|
||||
|
||||
textFont(createFont("Serif", 12));
|
||||
textMode(SCREEN);
|
||||
}
|
||||
|
||||
int ys = 25;
|
||||
int yi = 15;
|
||||
|
||||
void draw()
|
||||
{
|
||||
background(0);
|
||||
int y = ys;
|
||||
text("File Name: " + meta.fileName(), 5, y);
|
||||
text("Length (in milliseconds): " + meta.length(), 5, y+=yi);
|
||||
text("Title: " + meta.title(), 5, y+=yi);
|
||||
text("Author: " + meta.author(), 5, y+=yi);
|
||||
text("Album: " + meta.album(), 5, y+=yi);
|
||||
text("Date: " + meta.date(), 5, y+=yi);
|
||||
text("Comment: " + meta.comment(), 5, y+=yi);
|
||||
text("Track: " + meta.track(), 5, y+=yi);
|
||||
text("Genre: " + meta.genre(), 5, y+=yi);
|
||||
text("Copyright: " + meta.copyright(), 5, y+=yi);
|
||||
text("Disc: " + meta.disc(), 5, y+=yi);
|
||||
text("Composer: " + meta.composer(), 5, y+=yi);
|
||||
text("Orchestra: " + meta.orchestra(), 5, y+=yi);
|
||||
text("Publisher: " + meta.publisher(), 5, y+=yi);
|
||||
text("Encoded: " + meta.encoded(), 5, y+=yi);
|
||||
}
|
||||
|
||||
|
||||
void stop()
|
||||
{
|
||||
// always close Minim audio classes when you are done with them
|
||||
groove.close();
|
||||
// always stop Minim before exiting
|
||||
minim.stop();
|
||||
|
||||
super.stop();
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
+77
@@ -0,0 +1,77 @@
|
||||
/**
|
||||
* Get Set Pan
|
||||
* by Damien Di Fede.
|
||||
*
|
||||
* This sketch demonstrates how to use the <code>getPan</code> and
|
||||
* <code>setPan</code> methods of a <code>Controller</code> object.
|
||||
* The class used here is an <code>AudioOutput</code> but you can also
|
||||
* get and set the pan of <code>AudioSample</code>, <code>AudioSnippet</code>,
|
||||
* <code>AudioInput</code>, and <code>AudioPlayer</code> objects.
|
||||
* <code>getPan</code> and <code>setPan</code> will get and set the pan
|
||||
* of the <code>DataLine</code> that is being used for input or output,
|
||||
* but only if that line has a pan control. A <code>DataLine</code> is
|
||||
* a low-level JavaSound class that is used for sending audio to,
|
||||
* or receiving audio from, the audio system. You will notice in this
|
||||
* sketch that you will hear the pan changing (if it's available) but you
|
||||
* will not see any difference in the waveform being drawn. The reason
|
||||
* for this is that what you see in the output's sample buffers is what
|
||||
* it sends to the audio system. The system makes the pan change after
|
||||
* receiving the samples.
|
||||
*/
|
||||
|
||||
import ddf.minim.*;
|
||||
import ddf.minim.signals.*;
|
||||
|
||||
Minim minim;
|
||||
AudioOutput out;
|
||||
Oscillator osc;
|
||||
WaveformRenderer waveform;
|
||||
|
||||
void setup()
|
||||
{
|
||||
size(512, 200);
|
||||
|
||||
minim = new Minim(this);
|
||||
out = minim.getLineOut();
|
||||
|
||||
// see the example AudioOutput >> SawWaveSignal for more about this class
|
||||
osc = new SawWave(100, 0.2, out.sampleRate());
|
||||
// see the example Polyphonic >> addSignal for more about this
|
||||
out.addSignal(osc);
|
||||
|
||||
waveform = new WaveformRenderer();
|
||||
// see the example Recordable >> addListener for more about this
|
||||
out.addListener(waveform);
|
||||
|
||||
textFont(createFont("SanSerif", 12));
|
||||
}
|
||||
|
||||
void draw()
|
||||
{
|
||||
background(0);
|
||||
// see waveform.pde for more about this
|
||||
waveform.draw();
|
||||
|
||||
if ( out.hasControl(Controller.PAN) )
|
||||
{
|
||||
// map the mouse position to the range of the pan
|
||||
float val = map(mouseX, 0, width, -1, 1);
|
||||
// if a pan control is not available, this will do nothing
|
||||
out.setPan(val);
|
||||
// if a pan control is not available this will report zero
|
||||
text("The current pan is " + out.getPan() + ".", 5, 20);
|
||||
}
|
||||
else
|
||||
{
|
||||
text("The output doesn't have a pan control.", 5, 20);
|
||||
}
|
||||
}
|
||||
|
||||
void stop()
|
||||
{
|
||||
// always close Minim audio classes when you are finished with them
|
||||
out.close();
|
||||
minim.stop();
|
||||
|
||||
super.stop();
|
||||
}
|
||||
+76
@@ -0,0 +1,76 @@
|
||||
// This class is a very simple implementation of AudioListener. By implementing this interface,
|
||||
// you can add instances of this class to any class in Minim that implements Recordable and receive
|
||||
// buffers of samples in a callback fashion. In other words, every time that a Recordable object has
|
||||
// a new buffer of samples, it will send a copy to all of its AudioListeners. You can add an instance of
|
||||
// an AudioListener to a Recordable by using the addListener method of the Recordable. If you want to
|
||||
// remove a listener that you previously added, you call the removeListener method of Recordable, passing
|
||||
// the listener you want to remove.
|
||||
//
|
||||
// Although possible, it is not advised that you add the same listener to more than one Recordable.
|
||||
// Your listener will be called any time any of the Recordables you've added it have new samples. This
|
||||
// means that the stream of samples the listener sees will likely be interleaved buffers of samples from
|
||||
// all of the Recordables it is listening to, which is probably not what you want.
|
||||
//
|
||||
// You'll notice that the three methods of this class are synchronized. This is because the samples methods
|
||||
// will be called from a different thread than the one instances of this class will be created in. That thread
|
||||
// might try to send samples to an instance of this class while the instance is in the middle of drawing the
|
||||
// waveform, which would result in a waveform made up of samples from two different buffers. Synchronizing
|
||||
// all the methods means that while the main thread of execution is inside draw, the thread that calls
|
||||
// samples will block until draw is complete. Likewise, a call to draw will block if the sample thread is inside
|
||||
// one of the samples methods. Hope that's not too confusing!
|
||||
|
||||
class WaveformRenderer implements AudioListener
|
||||
{
|
||||
private float[] left;
|
||||
private float[] right;
|
||||
|
||||
WaveformRenderer()
|
||||
{
|
||||
left = null;
|
||||
right = null;
|
||||
}
|
||||
|
||||
synchronized void samples(float[] samp)
|
||||
{
|
||||
left = samp;
|
||||
}
|
||||
|
||||
synchronized void samples(float[] sampL, float[] sampR)
|
||||
{
|
||||
left = sampL;
|
||||
right = sampR;
|
||||
}
|
||||
|
||||
synchronized void draw()
|
||||
{
|
||||
// we've got a stereo signal if right is not null
|
||||
if ( left != null && right != null )
|
||||
{
|
||||
noFill();
|
||||
stroke(255);
|
||||
beginShape();
|
||||
for ( int i = 0; i < left.length; i++ )
|
||||
{
|
||||
vertex(i, height/4 + left[i]*50);
|
||||
}
|
||||
endShape();
|
||||
beginShape();
|
||||
for ( int i = 0; i < right.length; i++ )
|
||||
{
|
||||
vertex(i, 3*(height/4) + right[i]*50);
|
||||
}
|
||||
endShape();
|
||||
}
|
||||
else if ( left != null )
|
||||
{
|
||||
noFill();
|
||||
stroke(255);
|
||||
beginShape();
|
||||
for ( int i = 0; i < left.length; i++ )
|
||||
{
|
||||
vertex(i, height/2 + left[i]*50);
|
||||
}
|
||||
endShape();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
/**
|
||||
* Linear Averages
|
||||
* by Damien Di Fede.
|
||||
*
|
||||
* This sketch demonstrates how to use the averaging abilities of the FFT.
|
||||
* 128 linearly spaced averages are requested and then those are drawn as rectangles.
|
||||
*/
|
||||
|
||||
import ddf.minim.analysis.*;
|
||||
import ddf.minim.*;
|
||||
|
||||
Minim minim;
|
||||
AudioPlayer jingle;
|
||||
FFT fft;
|
||||
|
||||
void setup()
|
||||
{
|
||||
size(512, 200, P2D);
|
||||
minim = new Minim(this);
|
||||
|
||||
jingle = minim.loadFile("jingle.mp3", 2048);
|
||||
// loop the file
|
||||
jingle.loop();
|
||||
// create an FFT object that has a time-domain buffer the same size as jingle's sample buffer
|
||||
// and a sample rate that is the same as jingle's
|
||||
// note that this needs to be a power of two
|
||||
// and that it means the size of the spectrum will be 1024.
|
||||
// see the online tutorial for more info.
|
||||
fft = new FFT(jingle.bufferSize(), jingle.sampleRate());
|
||||
// use 128 averages.
|
||||
// the maximum number of averages we could ask for is half the spectrum size.
|
||||
fft.linAverages(128);
|
||||
rectMode(CORNERS);
|
||||
}
|
||||
|
||||
void draw()
|
||||
{
|
||||
background(0);
|
||||
fill(255);
|
||||
// perform a forward FFT on the samples in jingle's mix buffer
|
||||
// note that if jingle were a MONO file, this would be the same as using jingle.left or jingle.right
|
||||
fft.forward(jingle.mix);
|
||||
int w = int(fft.specSize()/128);
|
||||
for(int i = 0; i < fft.avgSize(); i++)
|
||||
{
|
||||
// draw a rectangle for each average, multiply the value by 5 so we can see it better
|
||||
rect(i*w, height, i*w + w, height - fft.getAvg(i)*5);
|
||||
}
|
||||
}
|
||||
|
||||
void stop()
|
||||
{
|
||||
// always close Minim audio classes when you finish with them
|
||||
jingle.close();
|
||||
minim.stop();
|
||||
|
||||
super.stop();
|
||||
}
|
||||
Binary file not shown.
+67
@@ -0,0 +1,67 @@
|
||||
/**
|
||||
* Load File
|
||||
* by Damien Di Fede.
|
||||
*
|
||||
* This sketch demonstrates how to use the <code>loadFile</code> method
|
||||
* of <code>Minim</code>. The <code>loadFile</code> method allows you to
|
||||
* specify the file you want to load with a <code>String</code> and optionally
|
||||
* specify what you want the buffer size of the returned <code>AudioPlayer</code>
|
||||
* to be. If you don't specify a buffer size, the returned player will have a
|
||||
* buffer size of 1024. Minim is able to play wav files, au files, aif files,
|
||||
* snd files, and mp3 files. When you call <code>loadFile</code>, if you just
|
||||
* specify the filename it will try to load the file from the data folder of
|
||||
* your sketch. However, you can also specify an absolute path
|
||||
* (such as "C:\foo\bar\thing.wav") and the file will be loaded from that
|
||||
* location (keep in mind that won't work from an applet). You can also specify
|
||||
* a URL (such as "http://www.mysite.com/mp3/song.mp3") but keep in mind that
|
||||
* if you run the sketch as an applet you may run in to security restrictions
|
||||
* if the applet is not on the same domain as the file you want to load. You can
|
||||
* get around the restriction by signing the applet. Before you exit your sketch
|
||||
* make sure you call the <code>close</code> method of any <code>AudioPlayer</code>'s
|
||||
* you have received from <code>loadFile</code>, followed by the <code>stop</code>
|
||||
* method of <code>Minim</code>.
|
||||
*/
|
||||
|
||||
import ddf.minim.*;
|
||||
|
||||
AudioPlayer player;
|
||||
Minim minim;
|
||||
|
||||
void setup()
|
||||
{
|
||||
size(512, 200, P2D);
|
||||
|
||||
minim = new Minim(this);
|
||||
|
||||
// load a file, give the AudioPlayer buffers that are 1024 samples long
|
||||
// player = minim.loadFile("groove.mp3");
|
||||
|
||||
// load a file, give the AudioPlayer buffers that are 2048 samples long
|
||||
player = minim.loadFile("groove.mp3", 2048);
|
||||
// play the file
|
||||
player.play();
|
||||
}
|
||||
|
||||
void draw()
|
||||
{
|
||||
background(0);
|
||||
stroke(255);
|
||||
// draw the waveforms
|
||||
// the values returned by left.get() and right.get() will be between -1 and 1,
|
||||
// so we need to scale them up to see the waveform
|
||||
// note that if the file is MONO, left.get() and right.get() will return the same value
|
||||
for(int i = 0; i < player.left.size()-1; i++)
|
||||
{
|
||||
line(i, 50 + player.left.get(i)*50, i+1, 50 + player.left.get(i+1)*50);
|
||||
line(i, 150 + player.right.get(i)*50, i+1, 150 + player.right.get(i+1)*50);
|
||||
}
|
||||
}
|
||||
|
||||
void stop()
|
||||
{
|
||||
// always close Minim audio classes when you are done with them
|
||||
player.close();
|
||||
minim.stop();
|
||||
|
||||
super.stop();
|
||||
}
|
||||
BIN
Binary file not shown.
+77
@@ -0,0 +1,77 @@
|
||||
/**
|
||||
* Load Sample
|
||||
* by Damien Di Fede.
|
||||
*
|
||||
* This sketch demonstrates how to use the <code>loadSample</code>
|
||||
* method of <code>Minim</code>. The <code>loadSample</code>
|
||||
* method allows you to specify the sample you want to load with
|
||||
* a <code>String</code> and optionally specify what you
|
||||
* want the buffer size of the returned <code>AudioSample</code>
|
||||
* to be. If you don't specify a buffer size, the returned sample
|
||||
* will have a buffer size of 1024. Minim is able to load wav files,
|
||||
* au files, aif files, snd files, and mp3 files. When you call
|
||||
* <code>loadSample</code>, if you just specify the filename it will
|
||||
* try to load the sample from the data folder of your sketch. However,
|
||||
* you can also specify an absolute path (such as "C:\foo\bar\thing.wav")
|
||||
* and the file will be loaded from that location (keep in mind that
|
||||
* won't work from an applet). You can also specify a URL (such as
|
||||
* "http://www.mysite.com/mp3/song.mp3") but keep in mind that if you
|
||||
* run the sketch as an applet you may run in to security restrictions
|
||||
* if the applet is not on the same domain as the file you want to load.
|
||||
* You can get around the restriction by signing the applet. Before you
|
||||
* exit your sketch make sure you call the <code>close</code> method
|
||||
* of any <code>AudioSamples</code>'s you have received from
|
||||
* <code>loadSample</code>.
|
||||
*
|
||||
* An <code>AudioSample</code> is a special kind of file playback that
|
||||
* allows you to repeatedly <i>trigger</i> an audio file. It does this
|
||||
* by keeping the entire file in an internal buffer and then keeping a
|
||||
* list of trigger points. <code>AudioSample</code> supports up to 20
|
||||
* overlapping triggers, which should be plenty for short sounds. It is
|
||||
* not advised that you use this class for long sounds (like entire songs,
|
||||
* for example) because the entire file is kept in memory.
|
||||
*
|
||||
* Press 'k' to trigger the sample.
|
||||
*/
|
||||
|
||||
import ddf.minim.*;
|
||||
|
||||
Minim minim;
|
||||
AudioSample kick;
|
||||
|
||||
void setup()
|
||||
{
|
||||
size(512, 200, P2D);
|
||||
// always start Minim before you do anything with it
|
||||
minim = new Minim(this);
|
||||
// load BD.mp3 from the data folder with a 1024 sample buffer
|
||||
// kick = Minim.loadSample("BD.mp3");
|
||||
// load BD.mp3 from the data folder, with a 512 sample buffer
|
||||
kick = minim.loadSample("BD.mp3", 2048);
|
||||
}
|
||||
|
||||
void draw()
|
||||
{
|
||||
background(0);
|
||||
stroke(255);
|
||||
// use the mix buffer to draw the waveforms.
|
||||
// because these are MONO files, we could have used the left or right buffers and got the same data
|
||||
for (int i = 0; i < kick.bufferSize() - 1; i++)
|
||||
{
|
||||
line(i, 100 - kick.left.get(i)*50, i+1, 100 - kick.left.get(i+1)*50);
|
||||
}
|
||||
}
|
||||
|
||||
void keyPressed()
|
||||
{
|
||||
if ( key == 'k' ) kick.trigger();
|
||||
}
|
||||
|
||||
void stop()
|
||||
{
|
||||
// always close Minim audio classes when you are done with them
|
||||
kick.close();
|
||||
minim.stop();
|
||||
|
||||
super.stop();
|
||||
}
|
||||
BIN
Binary file not shown.
@@ -0,0 +1,68 @@
|
||||
/**
|
||||
* Load Snippet
|
||||
* by Damien Di Fede.
|
||||
*
|
||||
* This sketch demonstrates how to use the <code>loadSnippet</code>
|
||||
* method of <code>Minim</code>. The <code>loadSnippet</code> method
|
||||
* allows you to specify the file you want to load with a
|
||||
* <code>String</code>. Unlike with <code>loadFile</code> and <code>loadSample</code>,
|
||||
* you are not able to specify a buffer size because an <code>AudioSnippet</code>
|
||||
* doesn't give you access to the samples as they are played.
|
||||
*
|
||||
* Minim is able to load wav files, au files, aif files, snd files, and mp3
|
||||
* files. When you call <code>loadSnippet</code>, if you just specify the
|
||||
* filename it will try to load the file from the data folder of your sketch.
|
||||
* However, you can also specify an absolute path (such as "C:\foo\bar\thing.wav")
|
||||
* and the file will be loaded from that location (keep in mind that won't
|
||||
* work from an applet). You can also specify a URL (such as
|
||||
* "http://www.mysite.com/mp3/song.mp3") but keep in mind that if you run the
|
||||
* sketch as an applet you may run in to security restrictions if the applet
|
||||
* is not on the same domain as the file you want to load. You can get around the
|
||||
* restriction by signing the applet.
|
||||
*
|
||||
* <code>AudioSnippet</code> is a simple wrapper around a JavaSound <code>Clip</code>
|
||||
* (It isn't called AudioClip because that's an interface defined in the package
|
||||
* java.applet). It provides almost the exact same functionality, the main
|
||||
* difference being that length, position, and cue are expressed in milliseconds
|
||||
* instead of microseconds. One of the limitations of <code>AudioSnippet</code> is
|
||||
* that you do not have access to the audio samples as they are played. However,
|
||||
* you are spared all of the overhead associated with making samples available.
|
||||
* An <code>AudioSnippet</code> is a good choice if all you need to do is play
|
||||
* a short sound at some point. If your aim is to repeatedly trigger a sound, you
|
||||
* should use an <code>AudioSample</code> instead.
|
||||
*
|
||||
* Before you exit your sketch make sure you call the <code>close</code>
|
||||
* method of any <code>AudioSnippet</code>'s you have received from
|
||||
* <code>loadSnippet</code>.
|
||||
*/
|
||||
|
||||
import ddf.minim.*;
|
||||
|
||||
Minim minim;
|
||||
AudioSnippet snip;
|
||||
|
||||
void setup()
|
||||
{
|
||||
size(512, 200);
|
||||
|
||||
minim = new Minim(this);
|
||||
snip = minim.loadSnippet("groove.mp3");
|
||||
// play the file
|
||||
snip.play();
|
||||
}
|
||||
|
||||
void draw()
|
||||
{
|
||||
background(0);
|
||||
// there are no waveforms to draw
|
||||
}
|
||||
|
||||
void stop()
|
||||
{
|
||||
// always close Minim audio classes when you are done with them
|
||||
snip.close();
|
||||
// always stop Minim before exiting
|
||||
minim.stop();
|
||||
|
||||
super.stop();
|
||||
}
|
||||
Binary file not shown.
+101
@@ -0,0 +1,101 @@
|
||||
/**
|
||||
* Record Line In
|
||||
* by Damien Di Fede.
|
||||
*
|
||||
* This sketch demonstrates how to an <code>AudioRecorder</code>
|
||||
* to record audio to disk. To use this sketch you need to have
|
||||
* something plugged into the line-in on your computer. Press 'r'
|
||||
* to toggle recording on and off and the press 's' to save to disk.
|
||||
* The recorded file will be placed in the sketch folder of
|
||||
* the sketch.
|
||||
*/
|
||||
|
||||
import ddf.minim.*;
|
||||
|
||||
Minim minim;
|
||||
AudioInput in;
|
||||
AudioRecorder recorder;
|
||||
|
||||
void setup()
|
||||
{
|
||||
size(512, 200, P2D);
|
||||
textMode(SCREEN);
|
||||
|
||||
minim = new Minim(this);
|
||||
|
||||
// get a stereo line-in: sample buffer length of 2048
|
||||
// default sample rate is 44100, default bit depth is 16
|
||||
in = minim.getLineIn(Minim.STEREO, 2048);
|
||||
// create a recorder that will record from the input to the filename specified, using buffered recording
|
||||
// buffered recording means that all captured audio will be written into a sample buffer
|
||||
// then when save() is called, the contents of the buffer will actually be written to a file
|
||||
// the file will be located in the sketch's root folder.
|
||||
recorder = minim.createRecorder(in, "myrecording.wav", true);
|
||||
|
||||
textFont(createFont("SanSerif", 12));
|
||||
}
|
||||
|
||||
void draw()
|
||||
{
|
||||
background(0);
|
||||
stroke(255);
|
||||
// draw the waveforms
|
||||
// the values returned by left.get() and right.get() will be between -1 and 1,
|
||||
// so we need to scale them up to see the waveform
|
||||
for(int i = 0; i < in.bufferSize() - 1; i++)
|
||||
{
|
||||
line(i, 50 + in.left.get(i)*50, i+1, 50 + in.left.get(i+1)*50);
|
||||
line(i, 150 + in.right.get(i)*50, i+1, 150 + in.right.get(i+1)*50);
|
||||
}
|
||||
|
||||
if ( recorder.isRecording() )
|
||||
{
|
||||
text("Currently recording...", 5, 15);
|
||||
}
|
||||
else
|
||||
{
|
||||
text("Not recording.", 5, 15);
|
||||
}
|
||||
}
|
||||
|
||||
void keyReleased()
|
||||
{
|
||||
if ( key == 'r' )
|
||||
{
|
||||
// to indicate that you want to start or stop capturing audio data, you must call
|
||||
// beginRecord() and endRecord() on the AudioRecorder object. You can start and stop
|
||||
// as many times as you like, the audio data will be appended to the end of the buffer
|
||||
// (in the case of buffered recording) or to the end of the file (in the case of streamed recording).
|
||||
if ( recorder.isRecording() )
|
||||
{
|
||||
recorder.endRecord();
|
||||
}
|
||||
else
|
||||
{
|
||||
recorder.beginRecord();
|
||||
}
|
||||
}
|
||||
if ( key == 's' )
|
||||
{
|
||||
// we've filled the file out buffer,
|
||||
// now write it to the file we specified in createRecorder
|
||||
// in the case of buffered recording, if the buffer is large,
|
||||
// this will appear to freeze the sketch for sometime
|
||||
// in the case of streamed recording,
|
||||
// it will not freeze as the data is already in the file and all that is being done
|
||||
// is closing the file.
|
||||
// the method returns the recorded audio as an AudioRecording,
|
||||
// see the example AudioRecorder >> RecordAndPlayback for more about that
|
||||
recorder.save();
|
||||
println("Done saving.");
|
||||
}
|
||||
}
|
||||
|
||||
void stop()
|
||||
{
|
||||
// always close Minim audio classes when you are done with them
|
||||
in.close();
|
||||
minim.stop();
|
||||
|
||||
super.stop();
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
/**
|
||||
* Sine Wave Signal
|
||||
* by Damien Di Fede.
|
||||
*
|
||||
* This sketch demonstrates how to use a <code>SineWave</code> with
|
||||
* an <code>AudioOutput</code>. Move the mouse up and down to change
|
||||
* the frequency, left and right to change the panning.
|
||||
*
|
||||
* <code>SineWave</code> is a subclass of <code>Oscillator</code>, which
|
||||
* is an abstract class that implements the interface <code>AudioSignal</code>.
|
||||
* This means that it can be added to an <code>AudioOutput</code> and the
|
||||
* <code>AudioOutput</code> will call one of the two <code>generate()</code>
|
||||
* functions, depending on whether the AudioOutput is STEREO or MONO.
|
||||
* Since it is an abstract class, it can't be directly instantiated, it
|
||||
* merely provides the functionality of smoothly changing frequency, amplitude
|
||||
* and pan. In order to have an <code>Oscillator</code> that actually
|
||||
* produces sound, you have to extend <code>Oscillator</code> and define
|
||||
* the value function. This function takes a <b>step</b> value and returns
|
||||
* a sample value between -1 and 1. In the case of the SineWave,
|
||||
* the value function returns this: <b>sin(freq * TWO_PI * step)</b>
|
||||
* <b>freq</b> is the current frequency (in Hertz) of the <code>Oscillator</code>.
|
||||
* It is multiplied by <b>TWO_PI</b> to set the period of the sine wave
|
||||
* properly and then that sine wave is sampled at <b>step</b>.
|
||||
*/
|
||||
|
||||
import ddf.minim.*;
|
||||
import ddf.minim.signals.*;
|
||||
|
||||
Minim minim;
|
||||
AudioOutput out;
|
||||
SineWave sine;
|
||||
|
||||
void setup()
|
||||
{
|
||||
size(512, 200, P2D);
|
||||
|
||||
minim = new Minim(this);
|
||||
// get a line out from Minim, default bufferSize is 1024, default sample rate is 44100, bit depth is 16
|
||||
out = minim.getLineOut(Minim.STEREO);
|
||||
// create a sine wave Oscillator, set to 440 Hz, at 0.5 amplitude, sample rate from line out
|
||||
sine = new SineWave(440, 0.5, out.sampleRate());
|
||||
// set the portamento speed on the oscillator to 200 milliseconds
|
||||
sine.portamento(200);
|
||||
// add the oscillator to the line out
|
||||
out.addSignal(sine);
|
||||
}
|
||||
|
||||
void draw()
|
||||
{
|
||||
background(0);
|
||||
stroke(255);
|
||||
// draw the waveforms
|
||||
for(int i = 0; i < out.bufferSize() - 1; i++)
|
||||
{
|
||||
float x1 = map(i, 0, out.bufferSize(), 0, width);
|
||||
float x2 = map(i+1, 0, out.bufferSize(), 0, width);
|
||||
line(x1, 50 + out.left.get(i)*50, x2, 50 + out.left.get(i+1)*50);
|
||||
line(x1, 150 + out.right.get(i)*50, x2, 150 + out.right.get(i+1)*50);
|
||||
}
|
||||
}
|
||||
|
||||
void mouseMoved()
|
||||
{
|
||||
// with portamento on the frequency will change smoothly
|
||||
float freq = map(mouseY, 0, height, 1500, 60);
|
||||
sine.setFreq(freq);
|
||||
// pan always changes smoothly to avoid crackles getting into the signal
|
||||
// note that we could call setPan on out, instead of on sine
|
||||
// this would sound the same, but the waveforms in out would not reflect the panning
|
||||
float pan = map(mouseX, 0, width, -1, 1);
|
||||
sine.setPan(pan);
|
||||
}
|
||||
|
||||
void stop()
|
||||
{
|
||||
out.close();
|
||||
minim.stop();
|
||||
|
||||
super.stop();
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
// this is a really straightforward effect that just reverses the order of the samples it receives
|
||||
// it doesn't sound like how you think ;-)
|
||||
class ReverseEffect implements AudioEffect
|
||||
{
|
||||
void process(float[] samp)
|
||||
{
|
||||
float[] reversed = new float[samp.length];
|
||||
int i = samp.length - 1;
|
||||
for (int j = 0; j < reversed.length; i--, j++)
|
||||
{
|
||||
reversed[j] = samp[i];
|
||||
}
|
||||
// we have to copy the values back into samp for this to work
|
||||
arraycopy(reversed, samp);
|
||||
}
|
||||
|
||||
void process(float[] left, float[] right)
|
||||
{
|
||||
process(left);
|
||||
process(right);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
/**
|
||||
* User Defined Effect
|
||||
* by Damien Di Fede.
|
||||
*
|
||||
* This sketch demonstrates how to write your own AudioEffect.
|
||||
* See NoiseEffect.pde for the implementation.
|
||||
*/
|
||||
|
||||
import ddf.minim.*;
|
||||
import ddf.minim.effects.*;
|
||||
|
||||
Minim minim;
|
||||
AudioPlayer groove;
|
||||
ReverseEffect reffect;
|
||||
|
||||
void setup()
|
||||
{
|
||||
size(512, 200, P2D);
|
||||
|
||||
minim = new Minim(this);
|
||||
// try changing the buffer size to see how it changes the effect
|
||||
groove = minim.loadFile("groove.mp3", 2048);
|
||||
groove.loop();
|
||||
reffect = new ReverseEffect();
|
||||
groove.addEffect(reffect);
|
||||
}
|
||||
|
||||
void draw()
|
||||
{
|
||||
background(0);
|
||||
stroke(255);
|
||||
// we multiply the values returned by get by 50 so we can see the waveform
|
||||
for ( int i = 0; i < groove.bufferSize() - 1; i++ )
|
||||
{
|
||||
float x1 = map(i, 0, groove.bufferSize(), 0, width);
|
||||
float x2 = map(i+1, 0, groove.bufferSize(), 0, width);
|
||||
line(x1, height/4 - groove.left.get(i)*50, x2, height/4 - groove.left.get(i+1)*50);
|
||||
line(x1, 3*height/4 - groove.right.get(i)*50, x2, 3*height/4 - groove.right.get(i+1)*50);
|
||||
}
|
||||
}
|
||||
|
||||
void stop()
|
||||
{
|
||||
// always close Minim audio classes when you finish with them
|
||||
groove.close();
|
||||
// always stop Minim before exiting
|
||||
minim.stop();
|
||||
|
||||
super.stop();
|
||||
}
|
||||
Binary file not shown.
@@ -0,0 +1,24 @@
|
||||
// this signal uses the mouseX and mouseY position to build a signal
|
||||
class MouseSaw implements AudioSignal
|
||||
{
|
||||
void generate(float[] samp)
|
||||
{
|
||||
float range = map(mouseX, 0, width, 0, 1);
|
||||
float peaks = map(mouseY, 0, height, 1, 20);
|
||||
float inter = float(samp.length) / peaks;
|
||||
for ( int i = 0; i < samp.length; i += inter )
|
||||
{
|
||||
for ( int j = 0; j < inter && (i+j) < samp.length; j++ )
|
||||
{
|
||||
samp[i + j] = map(j, 0, inter, -range, range);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// this is a stricly mono signal
|
||||
void generate(float[] left, float[] right)
|
||||
{
|
||||
generate(left);
|
||||
generate(right);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
/**
|
||||
* User Defined Signal
|
||||
* by Damien Di Fede.
|
||||
*
|
||||
* This sketch demonstrates how to implement your own AudioSignal
|
||||
* for Minim. See MouseSaw.pde for the implementation.
|
||||
*/
|
||||
|
||||
import ddf.minim.*;
|
||||
import ddf.minim.signals.*;
|
||||
|
||||
Minim minim;
|
||||
AudioOutput out;
|
||||
MouseSaw msaw;
|
||||
|
||||
void setup()
|
||||
{
|
||||
size(512, 200, P2D);
|
||||
|
||||
minim = new Minim(this);
|
||||
|
||||
out = minim.getLineOut(Minim.STEREO, 2048);
|
||||
msaw = new MouseSaw();
|
||||
// adds the signal to the output
|
||||
out.addSignal(msaw);
|
||||
}
|
||||
|
||||
void draw()
|
||||
{
|
||||
background(0);
|
||||
stroke(255);
|
||||
// draw the waveforms
|
||||
for(int i = 0; i < out.bufferSize()-1; i++)
|
||||
{
|
||||
float x1 = map(i, 0, out.bufferSize(), 0, width);
|
||||
float x2 = map(i+1, 0, out.bufferSize(), 0, width);
|
||||
line(x1, 50 + out.left.get(i)*50, x2, 50 + out.left.get(i+1)*50);
|
||||
line(x1, 150 + out.right.get(i)*50, x2, 150 + out.right.get(i+1)*50);
|
||||
}
|
||||
}
|
||||
|
||||
void stop()
|
||||
{
|
||||
out.close();
|
||||
minim.stop();
|
||||
|
||||
super.stop();
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
/**
|
||||
* Carnivore Client
|
||||
* by Alexander R. Galloway.
|
||||
|
||||
* The Carnivore library for Processing allows the programmer to run a packet
|
||||
* sniffer from within the Processing environment. A packet sniffer is any
|
||||
* application that is able to indiscriminately eavesdrop on data traffic
|
||||
* traveling through a local area network (LAN).
|
||||
*
|
||||
* Note: requires Carnivore Library for Processing v2.2 (http://r-s-g.org/carnivore)
|
||||
* Windows, first install winpcap (http://winpcap.org)
|
||||
* Mac, first open a Terminal and execute this commmand: sudo chmod 777 /dev/bpf*
|
||||
* (must be done each time you reboot your mac)
|
||||
*/
|
||||
|
||||
|
||||
import java.util.Iterator;
|
||||
import org.rsg.carnivore.*;
|
||||
import org.rsg.carnivore.net.*;
|
||||
|
||||
HashMap nodes = new HashMap();
|
||||
float startDiameter = 100.0;
|
||||
float shrinkSpeed = 0.97;
|
||||
int splitter, x, y;
|
||||
PFont font;
|
||||
|
||||
void setup()
|
||||
{
|
||||
size(800, 600);
|
||||
background(255);
|
||||
frameRate(10);
|
||||
Log.setDebug(true); // Uncomment this for verbose mode
|
||||
CarnivoreP5 c = new CarnivoreP5(this);
|
||||
//c.setVolumeLimit(4);
|
||||
// Use the "Create Font" tool to add a 12 point font to your sketch,
|
||||
// then use its name as the parameter to loadFont().
|
||||
font = loadFont("CourierNew-12.vlw");
|
||||
textFont(font);
|
||||
}
|
||||
|
||||
void draw()
|
||||
{
|
||||
background(255);
|
||||
drawNodes();
|
||||
}
|
||||
|
||||
// Iterate through each node
|
||||
synchronized void drawNodes() {
|
||||
Iterator it = nodes.keySet().iterator();
|
||||
while (it.hasNext()) {
|
||||
String ip = (String)it.next();
|
||||
float d = float(nodes.get(ip).toString());
|
||||
|
||||
// Use last two IP address bytes for x/y coords
|
||||
splitter = ip.lastIndexOf(".");
|
||||
y = int(ip.substring(splitter + 1)) * height / 255; // Scale to applet size
|
||||
String tmp = ip.substring(0, splitter);
|
||||
splitter = tmp.lastIndexOf(".");
|
||||
x = int(tmp.substring(splitter + 1)) * width / 255; // Scale to applet size
|
||||
|
||||
// Draw the node
|
||||
stroke(0);
|
||||
fill(color(100, 200)); // Rim
|
||||
ellipse(x, y, d, d); // Node circle
|
||||
noStroke();
|
||||
fill(color(100, 50)); // Halo
|
||||
ellipse(x, y, d + 20, d + 20);
|
||||
|
||||
// Draw the text
|
||||
fill(0);
|
||||
text(ip, x, y);
|
||||
|
||||
// Shrink the nodes a little
|
||||
nodes.put(ip, str(d * shrinkSpeed));
|
||||
}
|
||||
}
|
||||
|
||||
// Called each time a new packet arrives
|
||||
synchronized void packetEvent(CarnivorePacket packet)
|
||||
{
|
||||
println("[PDE] packetEvent: " + packet);
|
||||
// Remember these nodes in our hash map
|
||||
nodes.put(packet.receiverAddress.toString(), str(startDiameter));
|
||||
nodes.put(packet.senderAddress.toString(), str(startDiameter));
|
||||
}
|
||||
Binary file not shown.
@@ -0,0 +1,52 @@
|
||||
/**
|
||||
* Chat Server
|
||||
* by Tom Igoe.
|
||||
*
|
||||
* Press the mouse to stop the server.
|
||||
*/
|
||||
|
||||
|
||||
import processing.net.*;
|
||||
|
||||
int port = 10002;
|
||||
boolean myServerRunning = true;
|
||||
int bgColor = 0;
|
||||
int direction = 1;
|
||||
int textLine = 60;
|
||||
|
||||
Server myServer;
|
||||
|
||||
void setup()
|
||||
{
|
||||
size(400, 400);
|
||||
textFont(createFont("SanSerif", 16));
|
||||
myServer = new Server(this, port); // Starts a myServer on port 10002
|
||||
background(0);
|
||||
}
|
||||
|
||||
void mousePressed()
|
||||
{
|
||||
// If the mouse clicked the myServer stops
|
||||
myServer.stop();
|
||||
myServerRunning = false;
|
||||
}
|
||||
|
||||
void draw()
|
||||
{
|
||||
if (myServerRunning == true)
|
||||
{
|
||||
text("server", 15, 45);
|
||||
Client thisClient = myServer.available();
|
||||
if (thisClient != null) {
|
||||
if (thisClient.available() > 0) {
|
||||
text("mesage from: " + thisClient.ip() + " : " + thisClient.readString(), 15, textLine);
|
||||
textLine = textLine + 35;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
text("server", 15, 45);
|
||||
text("stopped", 15, 65);
|
||||
}
|
||||
}
|
||||
Binary file not shown.
@@ -0,0 +1,29 @@
|
||||
/**
|
||||
* HTTP Client.
|
||||
*
|
||||
* Starts a network client that connects to a server on port 80,
|
||||
* sends an HTTP 1.1 GET request, and prints the results.
|
||||
*/
|
||||
|
||||
|
||||
import processing.net.*;
|
||||
|
||||
Client c;
|
||||
String data;
|
||||
|
||||
void setup() {
|
||||
size(200, 200);
|
||||
background(50);
|
||||
fill(200);
|
||||
c = new Client(this, "www.processing.org", 80); // Connect to server on port 80
|
||||
c.write("GET / HTTP/1.1\n"); // Use the HTTP "GET" command to ask for a Web page
|
||||
c.write("Host: my_domain_name.com\n\n"); // Be polite and say who we are
|
||||
}
|
||||
|
||||
void draw() {
|
||||
if (c.available() > 0) { // If there's incoming data from the client...
|
||||
data = c.readString(); // ...then grab it and print it
|
||||
println(data);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
/**
|
||||
* Shared Drawing Canvas (Client)
|
||||
* by Alexander R. Galloway.
|
||||
*
|
||||
* The Processing Client class is instantiated by specifying a remote
|
||||
* address and port number to which the socket connection should be made.
|
||||
* Once the connection is made, the client may read (or write) data to the server.
|
||||
* Before running this program, start the Shared Drawing Canvas (Server) program.
|
||||
*/
|
||||
|
||||
|
||||
import processing.net.*;
|
||||
|
||||
Client c;
|
||||
String input;
|
||||
int data[];
|
||||
|
||||
void setup()
|
||||
{
|
||||
size(450, 255);
|
||||
background(204);
|
||||
stroke(0);
|
||||
frameRate(5); // Slow it down a little
|
||||
// Connect to the server's IP address and port
|
||||
c = new Client(this, "127.0.0.1", 12345); // Replace with your server's IP and port
|
||||
}
|
||||
|
||||
void draw()
|
||||
{
|
||||
if (mousePressed == true) {
|
||||
// Draw our line
|
||||
stroke(255);
|
||||
line(pmouseX, pmouseY, mouseX, mouseY);
|
||||
// Send mouse coords to other person
|
||||
c.write(pmouseX + " " + pmouseY + " " + mouseX + " " + mouseY + "\n");
|
||||
}
|
||||
// Receive data from server
|
||||
if (c.available() > 0) {
|
||||
input = c.readString();
|
||||
input = input.substring(0, input.indexOf("\n")); // Only up to the newline
|
||||
data = int(split(input, ' ')); // Split values into an array
|
||||
// Draw line using received coords
|
||||
stroke(0);
|
||||
line(data[0], data[1], data[2], data[3]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
/**
|
||||
* Shared Drawing Canvas (Server)
|
||||
* by Alexander R. Galloway.
|
||||
*
|
||||
* A server that shares a drawing canvas between two computers.
|
||||
* In order to open a socket connection, a server must select a
|
||||
* port on which to listen for incoming clients and through which
|
||||
* to communicate. Once the socket is established, a client may
|
||||
* connect to the server and send or receive commands and data.
|
||||
* Get this program running and then start the Shared Drawing
|
||||
* Canvas (Client) program so see how they interact.
|
||||
*/
|
||||
|
||||
|
||||
import processing.net.*;
|
||||
|
||||
Server s;
|
||||
Client c;
|
||||
String input;
|
||||
int data[];
|
||||
|
||||
void setup()
|
||||
{
|
||||
size(450, 255);
|
||||
background(204);
|
||||
stroke(0);
|
||||
frameRate(5); // Slow it down a little
|
||||
s = new Server(this, 12345); // Start a simple server on a port
|
||||
}
|
||||
|
||||
void draw()
|
||||
{
|
||||
if (mousePressed == true) {
|
||||
// Draw our line
|
||||
stroke(255);
|
||||
line(pmouseX, pmouseY, mouseX, mouseY);
|
||||
// Send mouse coords to other person
|
||||
s.write(pmouseX + " " + pmouseY + " " + mouseX + " " + mouseY + "\n");
|
||||
}
|
||||
// Receive data from client
|
||||
c = s.available();
|
||||
if (c != null) {
|
||||
input = c.readString();
|
||||
input = input.substring(0, input.indexOf("\n")); // Only up to the newline
|
||||
data = int(split(input, ' ')); // Split values into an array
|
||||
// Draw line using received coords
|
||||
stroke(0);
|
||||
line(data[0], data[1], data[2], data[3]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
/**
|
||||
* Yahoo! Search.
|
||||
*
|
||||
* Download the Yahoo! Search SDK from http://developer.yahoo.com/download
|
||||
* Inside the download, find the yahoo_search-2.X.X.jar file somewhere inside
|
||||
* the "Java" subdirectory. Drag the jar file to your sketch and it will be
|
||||
* added to your 'code' folder for use.
|
||||
*
|
||||
* This example is based on the based on Yahoo! API example.
|
||||
*/
|
||||
|
||||
|
||||
// Replace this with a developer key from http://developer.yahoo.com
|
||||
String appid = "YOUR_DEVELOPER_KEY_HERE";
|
||||
|
||||
SearchClient client = new SearchClient(appid);
|
||||
String query = "processing.org";
|
||||
WebSearchRequest request = new WebSearchRequest(query);
|
||||
|
||||
// (Optional) Set the maximum number of results to download
|
||||
//request.setResults(30);
|
||||
|
||||
try {
|
||||
WebSearchResults results = client.webSearch(request);
|
||||
// Print out how many hits were found
|
||||
println("Displaying " + results.getTotalResultsReturned() +
|
||||
" out of " + results.getTotalResultsAvailable() + " hits.");
|
||||
println();
|
||||
// Get a list of the search results
|
||||
WebSearchResult[] resultList = results.listResults();
|
||||
// Loop through the results and print them to the console
|
||||
|
||||
for (int i = 0; i < resultList.length; i++) {
|
||||
// Print out the document title and URL.
|
||||
println((i + 1) + ".");
|
||||
println(resultList[i].getTitle());
|
||||
println(resultList[i].getUrl());
|
||||
println();
|
||||
}
|
||||
|
||||
// Error handling below, see the documentation of the Yahoo! API for details
|
||||
}
|
||||
catch (IOException e) {
|
||||
println("Error calling Yahoo! Search Service: " + e.toString());
|
||||
e.printStackTrace();
|
||||
}
|
||||
catch (SearchException e) {
|
||||
println("Error calling Yahoo! Search Service: " + e.toString());
|
||||
e.printStackTrace();
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
/**
|
||||
* Esfera
|
||||
* by David Pena.
|
||||
*
|
||||
* Distribucion aleatoria uniforme sobre la superficie de una esfera.
|
||||
*/
|
||||
|
||||
import processing.opengl.*;
|
||||
|
||||
int cuantos = 8000;
|
||||
pelo[] lista ;
|
||||
float[] z = new float[cuantos];
|
||||
float[] phi = new float[cuantos];
|
||||
float[] largos = new float[cuantos];
|
||||
float radio = 200;
|
||||
float rx = 0;
|
||||
float ry =0;
|
||||
|
||||
void setup() {
|
||||
size(1024, 768, OPENGL);
|
||||
radio = height/3.5;
|
||||
|
||||
lista = new pelo[cuantos];
|
||||
for (int i=0; i<cuantos; i++){
|
||||
lista[i] = new pelo();
|
||||
}
|
||||
noiseDetail(3);
|
||||
|
||||
}
|
||||
|
||||
void draw() {
|
||||
background(0);
|
||||
translate(width/2,height/2);
|
||||
|
||||
float rxp = ((mouseX-(width/2))*0.005);
|
||||
float ryp = ((mouseY-(height/2))*0.005);
|
||||
rx = (rx*0.9)+(rxp*0.1);
|
||||
ry = (ry*0.9)+(ryp*0.1);
|
||||
rotateY(rx);
|
||||
rotateX(ry);
|
||||
fill(0);
|
||||
noStroke();
|
||||
sphere(radio);
|
||||
|
||||
for (int i=0;i<cuantos;i++){
|
||||
lista[i].dibujar();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class pelo
|
||||
{
|
||||
float z = random(-radio,radio);
|
||||
float phi = random(TWO_PI);
|
||||
float largo = random(1.15,1.2);
|
||||
float theta = asin(z/radio);
|
||||
|
||||
void dibujar(){
|
||||
|
||||
float off = (noise(millis() * 0.0005,sin(phi))-0.5) * 0.3;
|
||||
float offb = (noise(millis() * 0.0007,sin(z) * 0.01)-0.5) * 0.3;
|
||||
|
||||
float thetaff = theta+off;
|
||||
float phff = phi+offb;
|
||||
float x = radio * cos(theta) * cos(phi);
|
||||
float y = radio * cos(theta) * sin(phi);
|
||||
float z = radio * sin(theta);
|
||||
float msx= screenX(x,y,z);
|
||||
float msy= screenY(x,y,z);
|
||||
|
||||
float xo = radio * cos(thetaff) * cos(phff);
|
||||
float yo = radio * cos(thetaff) * sin(phff);
|
||||
float zo = radio * sin(thetaff);
|
||||
|
||||
float xb = xo * largo;
|
||||
float yb = yo * largo;
|
||||
float zb = zo * largo;
|
||||
|
||||
beginShape(LINES);
|
||||
stroke(0);
|
||||
vertex(x,y,z);
|
||||
stroke(200,150);
|
||||
vertex(xb,yb,zb);
|
||||
endShape();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
/**
|
||||
* Extrusion.
|
||||
*
|
||||
* Converts a flat image into spatial data points and rotates the points
|
||||
* around the center.
|
||||
*/
|
||||
|
||||
|
||||
import processing.opengl.*;
|
||||
|
||||
PImage a;
|
||||
boolean onetime = true;
|
||||
int[][] aPixels;
|
||||
int[][] values;
|
||||
float angle;
|
||||
|
||||
void setup() {
|
||||
size(1024, 768, OPENGL);
|
||||
|
||||
aPixels = new int[width][height];
|
||||
values = new int[width][height];
|
||||
noFill();
|
||||
|
||||
// Load the image into a new array
|
||||
// Extract the values and store in an array
|
||||
a = loadImage("ystone08.jpg");
|
||||
a.loadPixels();
|
||||
for (int i = 0; i < a.height; i++) {
|
||||
for (int j = 0; j < a.width; j++) {
|
||||
aPixels[j][i] = a.pixels[i*a.width + j];
|
||||
values[j][i] = int(blue(aPixels[j][i]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void draw() {
|
||||
background(255);
|
||||
translate(width/2, height/2, 0);
|
||||
scale(2.0);
|
||||
|
||||
// Update and constrain the angle
|
||||
angle += 0.005;
|
||||
rotateY(angle);
|
||||
|
||||
// Display the image mass
|
||||
for (int i = 0; i < a.height; i += 2) {
|
||||
for (int j = 0; j < a.width; j += 2) {
|
||||
stroke(values[j][i], 153);
|
||||
line(j-a.width/2, i-a.height/2, -values[j][i], j-a.width/2, i-a.height/2, -values[j][i]-10);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,165 @@
|
||||
/**
|
||||
* Geometry
|
||||
* by Marius Watz.
|
||||
*
|
||||
* Using sin/cos lookup tables, blends colors, and draws a series of
|
||||
* rotating arcs on the screen.
|
||||
*/
|
||||
|
||||
|
||||
import processing.opengl.*;
|
||||
|
||||
// Trig lookup tables borrowed from Toxi; cryptic but effective.
|
||||
float sinLUT[];
|
||||
float cosLUT[];
|
||||
float SINCOS_PRECISION=1.0;
|
||||
int SINCOS_LENGTH= int((360.0/SINCOS_PRECISION));
|
||||
|
||||
// System data
|
||||
boolean dosave=false;
|
||||
int num;
|
||||
float pt[];
|
||||
int style[];
|
||||
|
||||
|
||||
void setup() {
|
||||
size(1024, 768, OPENGL);
|
||||
background(255);
|
||||
|
||||
// Fill the tables
|
||||
sinLUT=new float[SINCOS_LENGTH];
|
||||
cosLUT=new float[SINCOS_LENGTH];
|
||||
for (int i = 0; i < SINCOS_LENGTH; i++) {
|
||||
sinLUT[i]= (float)Math.sin(i*DEG_TO_RAD*SINCOS_PRECISION);
|
||||
cosLUT[i]= (float)Math.cos(i*DEG_TO_RAD*SINCOS_PRECISION);
|
||||
}
|
||||
|
||||
num = 150;
|
||||
pt = new float[6*num]; // rotx, roty, deg, rad, w, speed
|
||||
style = new int[2*num]; // color, render style
|
||||
|
||||
// Set up arc shapes
|
||||
int index=0;
|
||||
float prob;
|
||||
for (int i=0; i<num; i++) {
|
||||
pt[index++] = random(PI*2); // Random X axis rotation
|
||||
pt[index++] = random(PI*2); // Random Y axis rotation
|
||||
|
||||
pt[index++] = random(60,80); // Short to quarter-circle arcs
|
||||
if(random(100)>90) pt[index]=(int)random(8,27)*10;
|
||||
|
||||
pt[index++] = int(random(2,50)*5); // Radius. Space them out nicely
|
||||
|
||||
pt[index++] = random(4,32); // Width of band
|
||||
if(random(100)>90) pt[index]=random(40,60); // Width of band
|
||||
|
||||
pt[index++] = radians(random(5,30))/5; // Speed of rotation
|
||||
|
||||
// get colors
|
||||
prob = random(100);
|
||||
if(prob<30) style[i*2]=colorBlended(random(1), 255,0,100, 255,0,0, 210);
|
||||
else if(prob<70) style[i*2]=colorBlended(random(1), 0,153,255, 170,225,255, 210);
|
||||
else if(prob<90) style[i*2]=colorBlended(random(1), 200,255,0, 150,255,0, 210);
|
||||
else style[i*2]=color(255,255,255, 220);
|
||||
|
||||
if(prob<50) style[i*2]=colorBlended(random(1), 200,255,0, 50,120,0, 210);
|
||||
else if(prob<90) style[i*2]=colorBlended(random(1), 255,100,0, 255,255,0, 210);
|
||||
else style[i*2]=color(255,255,255, 220);
|
||||
|
||||
style[i*2+1]=(int)(random(100))%3;
|
||||
}
|
||||
}
|
||||
|
||||
void draw() {
|
||||
|
||||
background(0);
|
||||
|
||||
int index=0;
|
||||
translate(width/2, height/2, 0);
|
||||
rotateX(PI/6);
|
||||
rotateY(PI/6);
|
||||
|
||||
for (int i = 0; i < num; i++) {
|
||||
pushMatrix();
|
||||
|
||||
rotateX(pt[index++]);
|
||||
rotateY(pt[index++]);
|
||||
|
||||
if(style[i*2+1]==0) {
|
||||
stroke(style[i*2]);
|
||||
noFill();
|
||||
strokeWeight(1);
|
||||
arcLine(0,0, pt[index++],pt[index++],pt[index++]);
|
||||
}
|
||||
else if(style[i*2+1]==1) {
|
||||
fill(style[i*2]);
|
||||
noStroke();
|
||||
arcLineBars(0,0, pt[index++],pt[index++],pt[index++]);
|
||||
}
|
||||
else {
|
||||
fill(style[i*2]);
|
||||
noStroke();
|
||||
arc(0,0, pt[index++],pt[index++],pt[index++]);
|
||||
}
|
||||
|
||||
// increase rotation
|
||||
pt[index-5]+=pt[index]/10;
|
||||
pt[index-4]+=pt[index++]/20;
|
||||
|
||||
popMatrix();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Get blend of two colors
|
||||
int colorBlended(float fract,
|
||||
float r, float g, float b,
|
||||
float r2, float g2, float b2, float a) {
|
||||
|
||||
r2 = (r2 - r);
|
||||
g2 = (g2 - g);
|
||||
b2 = (b2 - b);
|
||||
return color(r + r2 * fract, g + g2 * fract, b + b2 * fract, a);
|
||||
}
|
||||
|
||||
|
||||
// Draw arc line
|
||||
void arcLine(float x,float y,float deg,float rad,float w) {
|
||||
int a=(int)(min (deg/SINCOS_PRECISION,SINCOS_LENGTH-1));
|
||||
int numlines=(int)(w/2);
|
||||
|
||||
for (int j=0; j<numlines; j++) {
|
||||
beginShape();
|
||||
for (int i=0; i<a; i++) {
|
||||
vertex(cosLUT[i]*rad+x,sinLUT[i]*rad+y);
|
||||
}
|
||||
endShape();
|
||||
rad += 2;
|
||||
}
|
||||
}
|
||||
|
||||
// Draw arc line with bars
|
||||
void arcLineBars(float x,float y,float deg,float rad,float w) {
|
||||
int a = int((min (deg/SINCOS_PRECISION,SINCOS_LENGTH-1)));
|
||||
a /= 4;
|
||||
|
||||
beginShape(QUADS);
|
||||
for (int i=0; i<a; i+=4) {
|
||||
vertex(cosLUT[i]*(rad)+x,sinLUT[i]*(rad)+y);
|
||||
vertex(cosLUT[i]*(rad+w)+x,sinLUT[i]*(rad+w)+y);
|
||||
vertex(cosLUT[i+2]*(rad+w)+x,sinLUT[i+2]*(rad+w)+y);
|
||||
vertex(cosLUT[i+2]*(rad)+x,sinLUT[i+2]*(rad)+y);
|
||||
}
|
||||
endShape();
|
||||
}
|
||||
|
||||
// Draw solid arc
|
||||
void arc(float x,float y,float deg,float rad,float w) {
|
||||
int a = int(min (deg/SINCOS_PRECISION,SINCOS_LENGTH-1));
|
||||
beginShape(QUAD_STRIP);
|
||||
for (int i = 0; i < a; i++) {
|
||||
vertex(cosLUT[i]*(rad)+x,sinLUT[i]*(rad)+y);
|
||||
vertex(cosLUT[i]*(rad+w)+x,sinLUT[i]*(rad+w)+y);
|
||||
}
|
||||
endShape();
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
/**
|
||||
* LightsGL.
|
||||
* Modified from an example by Simon Greenwold.
|
||||
*
|
||||
* Display a box with three different kinds of lights.
|
||||
*/
|
||||
|
||||
|
||||
import processing.opengl.*;
|
||||
|
||||
void setup()
|
||||
{
|
||||
size(1024, 768, OPENGL);
|
||||
noStroke();
|
||||
}
|
||||
|
||||
void draw()
|
||||
{
|
||||
defineLights();
|
||||
background(0);
|
||||
|
||||
for (int x = 0; x <= width; x += 100) {
|
||||
for (int y = 0; y <= height; y += 100) {
|
||||
pushMatrix();
|
||||
translate(x, y);
|
||||
rotateY(map(mouseX, 0, width, 0, PI));
|
||||
rotateX(map(mouseY, 0, height, 0, PI));
|
||||
box(90);
|
||||
popMatrix();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void defineLights() {
|
||||
// Orange point light on the right
|
||||
pointLight(150, 100, 0, // Color
|
||||
200, -150, 0); // Position
|
||||
|
||||
// Blue directional light from the left
|
||||
directionalLight(0, 102, 255, // Color
|
||||
1, 0, 0); // The x-, y-, z-axis direction
|
||||
|
||||
// Yellow spotlight from the front
|
||||
spotLight(255, 255, 109, // Color
|
||||
0, 40, 200, // Position
|
||||
0, -0.5, -0.5, // Direction
|
||||
PI / 2, 2); // Angle, concentration
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
|
||||
class Cube {
|
||||
|
||||
// Properties
|
||||
int w, h, d;
|
||||
int shiftX, shiftY, shiftZ;
|
||||
|
||||
// Constructor
|
||||
Cube(int w, int h, int d, int shiftX, int shiftY, int shiftZ){
|
||||
this.w = w;
|
||||
this.h = h;
|
||||
this.d = d;
|
||||
this.shiftX = shiftX;
|
||||
this.shiftY = shiftY;
|
||||
this.shiftZ = shiftZ;
|
||||
}
|
||||
|
||||
// Main cube drawing method, which looks
|
||||
// more confusing than it really is. It's
|
||||
// just a bunch of rectangles drawn for
|
||||
// each cube face
|
||||
void drawCube(){
|
||||
beginShape(QUADS);
|
||||
// Front face
|
||||
vertex(-w/2 + shiftX, -h/2 + shiftY, -d/2 + shiftZ);
|
||||
vertex(w + shiftX, -h/2 + shiftY, -d/2 + shiftZ);
|
||||
vertex(w + shiftX, h + shiftY, -d/2 + shiftZ);
|
||||
vertex(-w/2 + shiftX, h + shiftY, -d/2 + shiftZ);
|
||||
|
||||
// Back face
|
||||
vertex(-w/2 + shiftX, -h/2 + shiftY, d + shiftZ);
|
||||
vertex(w + shiftX, -h/2 + shiftY, d + shiftZ);
|
||||
vertex(w + shiftX, h + shiftY, d + shiftZ);
|
||||
vertex(-w/2 + shiftX, h + shiftY, d + shiftZ);
|
||||
|
||||
// Left face
|
||||
vertex(-w/2 + shiftX, -h/2 + shiftY, -d/2 + shiftZ);
|
||||
vertex(-w/2 + shiftX, -h/2 + shiftY, d + shiftZ);
|
||||
vertex(-w/2 + shiftX, h + shiftY, d + shiftZ);
|
||||
vertex(-w/2 + shiftX, h + shiftY, -d/2 + shiftZ);
|
||||
|
||||
// Right face
|
||||
vertex(w + shiftX, -h/2 + shiftY, -d/2 + shiftZ);
|
||||
vertex(w + shiftX, -h/2 + shiftY, d + shiftZ);
|
||||
vertex(w + shiftX, h + shiftY, d + shiftZ);
|
||||
vertex(w + shiftX, h + shiftY, -d/2 + shiftZ);
|
||||
|
||||
// Top face
|
||||
vertex(-w/2 + shiftX, -h/2 + shiftY, -d/2 + shiftZ);
|
||||
vertex(w + shiftX, -h/2 + shiftY, -d/2 + shiftZ);
|
||||
vertex(w + shiftX, -h/2 + shiftY, d + shiftZ);
|
||||
vertex(-w/2 + shiftX, -h/2 + shiftY, d + shiftZ);
|
||||
|
||||
// Bottom face
|
||||
vertex(-w/2 + shiftX, h + shiftY, -d/2 + shiftZ);
|
||||
vertex(w + shiftX, h + shiftY, -d/2 + shiftZ);
|
||||
vertex(w + shiftX, h + shiftY, d + shiftZ);
|
||||
vertex(-w/2 + shiftX, h + shiftY, d + shiftZ);
|
||||
|
||||
endShape();
|
||||
|
||||
// Add some rotation to each box for pizazz.
|
||||
rotateY(radians(1));
|
||||
rotateX(radians(1));
|
||||
rotateZ(radians(1));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
/**
|
||||
* Space Junk
|
||||
* by Ira Greenberg.
|
||||
* Zoom suggestion
|
||||
* by Danny Greenberg.
|
||||
*
|
||||
* Rotating cubes in space using a custom Cube class.
|
||||
* Color controlled by light sources. Move the mouse left
|
||||
* and right to zoom.
|
||||
*/
|
||||
|
||||
import processing.opengl.*;
|
||||
|
||||
// Used for oveall rotation
|
||||
float ang;
|
||||
|
||||
// Cube count-lower/raise to test P3D/OPENGL performance
|
||||
int limit = 500;
|
||||
|
||||
// Array for all cubes
|
||||
Cube[]cubes = new Cube[limit];
|
||||
|
||||
void setup() {
|
||||
size(1024, 768, OPENGL);
|
||||
background(0);
|
||||
noStroke();
|
||||
|
||||
// Instantiate cubes, passing in random vals for size and postion
|
||||
for (int i = 0; i< cubes.length; i++){
|
||||
cubes[i] = new Cube(int(random(-10, 10)), int(random(-10, 10)),
|
||||
int(random(-10, 10)), int(random(-140, 140)), int(random(-140, 140)),
|
||||
int(random(-140, 140)));
|
||||
}
|
||||
}
|
||||
|
||||
void draw(){
|
||||
background(0);
|
||||
fill(200);
|
||||
|
||||
// Set up some different colored lights
|
||||
pointLight(51, 102, 255, 65, 60, 100);
|
||||
pointLight(200, 40, 60, -65, -60, -150);
|
||||
|
||||
// Raise overall light in scene
|
||||
ambientLight(70, 70, 10);
|
||||
|
||||
// Center geometry in display windwow.
|
||||
// you can change 3rd argument ('0')
|
||||
// to move block group closer(+)/further(-)
|
||||
translate(width/2, height/2, -200 + mouseX * 0.65);
|
||||
|
||||
// Rotate around y and x axes
|
||||
rotateY(radians(ang));
|
||||
rotateX(radians(ang));
|
||||
|
||||
// Draw cubes
|
||||
for (int i = 0; i < cubes.length; i++){
|
||||
cubes[i].drawCube();
|
||||
}
|
||||
|
||||
// Used in rotate function calls above
|
||||
ang++;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,174 @@
|
||||
/**
|
||||
* Textured Sphere
|
||||
* by Mike 'Flux' Chang (cleaned up by Aaron Koblin).
|
||||
* Based on code by Toxi.
|
||||
*
|
||||
* A 3D textured sphere with simple rotation control.
|
||||
* Note: Controls will be inverted when sphere is upside down.
|
||||
* Use an "arc ball" to deal with this appropriately.
|
||||
*/
|
||||
|
||||
import processing.opengl.*;
|
||||
|
||||
PImage bg;
|
||||
PImage texmap;
|
||||
|
||||
int sDetail = 35; // Sphere detail setting
|
||||
float rotationX = 0;
|
||||
float rotationY = 0;
|
||||
float velocityX = 0;
|
||||
float velocityY = 0;
|
||||
float globeRadius = 450;
|
||||
float pushBack = 0;
|
||||
|
||||
float[] cx, cz, sphereX, sphereY, sphereZ;
|
||||
float sinLUT[];
|
||||
float cosLUT[];
|
||||
float SINCOS_PRECISION = 0.5;
|
||||
int SINCOS_LENGTH = int(360.0 / SINCOS_PRECISION);
|
||||
|
||||
|
||||
void setup() {
|
||||
size(1024, 768, OPENGL);
|
||||
texmap = loadImage("world32k.jpg");
|
||||
initializeSphere(sDetail);
|
||||
}
|
||||
|
||||
void draw() {
|
||||
background(0);
|
||||
renderGlobe();
|
||||
}
|
||||
|
||||
void renderGlobe() {
|
||||
pushMatrix();
|
||||
translate(width/2.0, height/2.0, pushBack);
|
||||
pushMatrix();
|
||||
noFill();
|
||||
stroke(255,200);
|
||||
strokeWeight(2);
|
||||
smooth();
|
||||
popMatrix();
|
||||
lights();
|
||||
pushMatrix();
|
||||
rotateX( radians(-rotationX) );
|
||||
rotateY( radians(270 - rotationY) );
|
||||
fill(200);
|
||||
noStroke();
|
||||
textureMode(IMAGE);
|
||||
texturedSphere(globeRadius, texmap);
|
||||
popMatrix();
|
||||
popMatrix();
|
||||
rotationX += velocityX;
|
||||
rotationY += velocityY;
|
||||
velocityX *= 0.95;
|
||||
velocityY *= 0.95;
|
||||
|
||||
// Implements mouse control (interaction will be inverse when sphere is upside down)
|
||||
if(mousePressed){
|
||||
velocityX += (mouseY-pmouseY) * 0.01;
|
||||
velocityY -= (mouseX-pmouseX) * 0.01;
|
||||
}
|
||||
}
|
||||
|
||||
void initializeSphere(int res)
|
||||
{
|
||||
sinLUT = new float[SINCOS_LENGTH];
|
||||
cosLUT = new float[SINCOS_LENGTH];
|
||||
|
||||
for (int i = 0; i < SINCOS_LENGTH; i++) {
|
||||
sinLUT[i] = (float) Math.sin(i * DEG_TO_RAD * SINCOS_PRECISION);
|
||||
cosLUT[i] = (float) Math.cos(i * DEG_TO_RAD * SINCOS_PRECISION);
|
||||
}
|
||||
|
||||
float delta = (float)SINCOS_LENGTH/res;
|
||||
float[] cx = new float[res];
|
||||
float[] cz = new float[res];
|
||||
|
||||
// Calc unit circle in XZ plane
|
||||
for (int i = 0; i < res; i++) {
|
||||
cx[i] = -cosLUT[(int) (i*delta) % SINCOS_LENGTH];
|
||||
cz[i] = sinLUT[(int) (i*delta) % SINCOS_LENGTH];
|
||||
}
|
||||
|
||||
// Computing vertexlist vertexlist starts at south pole
|
||||
int vertCount = res * (res-1) + 2;
|
||||
int currVert = 0;
|
||||
|
||||
// Re-init arrays to store vertices
|
||||
sphereX = new float[vertCount];
|
||||
sphereY = new float[vertCount];
|
||||
sphereZ = new float[vertCount];
|
||||
float angle_step = (SINCOS_LENGTH*0.5f)/res;
|
||||
float angle = angle_step;
|
||||
|
||||
// Step along Y axis
|
||||
for (int i = 1; i < res; i++) {
|
||||
float curradius = sinLUT[(int) angle % SINCOS_LENGTH];
|
||||
float currY = -cosLUT[(int) angle % SINCOS_LENGTH];
|
||||
for (int j = 0; j < res; j++) {
|
||||
sphereX[currVert] = cx[j] * curradius;
|
||||
sphereY[currVert] = currY;
|
||||
sphereZ[currVert++] = cz[j] * curradius;
|
||||
}
|
||||
angle += angle_step;
|
||||
}
|
||||
sDetail = res;
|
||||
}
|
||||
|
||||
// Generic routine to draw textured sphere
|
||||
void texturedSphere(float r, PImage t)
|
||||
{
|
||||
int v1,v11,v2;
|
||||
r = (r + 240 ) * 0.33;
|
||||
beginShape(TRIANGLE_STRIP);
|
||||
texture(t);
|
||||
float iu=(float)(t.width-1)/(sDetail);
|
||||
float iv=(float)(t.height-1)/(sDetail);
|
||||
float u=0,v=iv;
|
||||
for (int i = 0; i < sDetail; i++) {
|
||||
vertex(0, -r, 0,u,0);
|
||||
vertex(sphereX[i]*r, sphereY[i]*r, sphereZ[i]*r, u, v);
|
||||
u+=iu;
|
||||
}
|
||||
vertex(0, -r, 0,u,0);
|
||||
vertex(sphereX[0]*r, sphereY[0]*r, sphereZ[0]*r, u, v);
|
||||
endShape();
|
||||
|
||||
// Middle rings
|
||||
int voff = 0;
|
||||
for(int i = 2; i < sDetail; i++) {
|
||||
v1=v11=voff;
|
||||
voff += sDetail;
|
||||
v2=voff;
|
||||
u=0;
|
||||
beginShape(TRIANGLE_STRIP);
|
||||
texture(t);
|
||||
for (int j = 0; j < sDetail; j++) {
|
||||
vertex(sphereX[v1]*r, sphereY[v1]*r, sphereZ[v1++]*r, u, v);
|
||||
vertex(sphereX[v2]*r, sphereY[v2]*r, sphereZ[v2++]*r, u, v+iv);
|
||||
u+=iu;
|
||||
}
|
||||
|
||||
// Close each ring
|
||||
v1=v11;
|
||||
v2=voff;
|
||||
vertex(sphereX[v1]*r, sphereY[v1]*r, sphereZ[v1]*r, u, v);
|
||||
vertex(sphereX[v2]*r, sphereY[v2]*r, sphereZ[v2]*r, u, v+iv);
|
||||
endShape();
|
||||
v+=iv;
|
||||
}
|
||||
u=0;
|
||||
|
||||
// Add the northern cap
|
||||
beginShape(TRIANGLE_STRIP);
|
||||
texture(t);
|
||||
for (int i = 0; i < sDetail; i++) {
|
||||
v2 = voff + i;
|
||||
vertex(sphereX[v2]*r, sphereY[v2]*r, sphereZ[v2]*r, u, v);
|
||||
vertex(0, r, 0,u,v+iv);
|
||||
u+=iu;
|
||||
}
|
||||
vertex(sphereX[voff]*r, sphereY[voff]*r, sphereZ[voff]*r, u, v);
|
||||
endShape();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,256 @@
|
||||
class Gesture {
|
||||
|
||||
float damp = 5.0;
|
||||
float dampInv = 1.0 / damp;
|
||||
float damp1 = damp - 1;
|
||||
|
||||
int w;
|
||||
int h;
|
||||
int capacity;
|
||||
|
||||
Vec3f path[];
|
||||
int crosses[];
|
||||
Polygon polygons[];
|
||||
int nPoints;
|
||||
int nPolys;
|
||||
|
||||
float jumpDx, jumpDy;
|
||||
boolean exists;
|
||||
float INIT_TH = 14;
|
||||
float thickness = INIT_TH;
|
||||
|
||||
Gesture(int mw, int mh) {
|
||||
w = mw;
|
||||
h = mh;
|
||||
capacity = 600;
|
||||
path = new Vec3f[capacity];
|
||||
polygons = new Polygon[capacity];
|
||||
crosses = new int[capacity];
|
||||
for (int i=0;i<capacity;i++) {
|
||||
polygons[i] = new Polygon();
|
||||
polygons[i].npoints = 4;
|
||||
path[i] = new Vec3f();
|
||||
crosses[i] = 0;
|
||||
}
|
||||
nPoints = 0;
|
||||
nPolys = 0;
|
||||
|
||||
exists = false;
|
||||
jumpDx = 0;
|
||||
jumpDy = 0;
|
||||
}
|
||||
|
||||
void clear() {
|
||||
nPoints = 0;
|
||||
exists = false;
|
||||
thickness = INIT_TH;
|
||||
}
|
||||
|
||||
void clearPolys() {
|
||||
nPolys = 0;
|
||||
}
|
||||
|
||||
void addPoint(float x, float y) {
|
||||
|
||||
if (nPoints >= capacity) {
|
||||
// there are all sorts of possible solutions here,
|
||||
// but for abject simplicity, I don't do anything.
|
||||
}
|
||||
else {
|
||||
float v = distToLast(x, y);
|
||||
float p = getPressureFromVelocity(v);
|
||||
path[nPoints++].set(x,y,p);
|
||||
|
||||
if (nPoints > 1) {
|
||||
exists = true;
|
||||
jumpDx = path[nPoints-1].x - path[0].x;
|
||||
jumpDy = path[nPoints-1].y - path[0].y;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
float getPressureFromVelocity(float v) {
|
||||
final float scale = 18;
|
||||
final float minP = 0.02;
|
||||
final float oldP = (nPoints > 0) ? path[nPoints-1].p : 0;
|
||||
return ((minP + max(0, 1.0 - v/scale)) + (damp1*oldP))*dampInv;
|
||||
}
|
||||
|
||||
void setPressures() {
|
||||
// pressures vary from 0...1
|
||||
float pressure;
|
||||
Vec3f tmp;
|
||||
float t = 0;
|
||||
float u = 1.0 / (nPoints - 1)*TWO_PI;
|
||||
for (int i = 0; i < nPoints; i++) {
|
||||
pressure = sqrt((1.0 - cos(t))*0.5);
|
||||
path[i].p = pressure;
|
||||
t += u;
|
||||
}
|
||||
}
|
||||
|
||||
float distToLast(float ix, float iy) {
|
||||
if (nPoints > 0) {
|
||||
Vec3f v = path[nPoints-1];
|
||||
float dx = v.x - ix;
|
||||
float dy = v.y - iy;
|
||||
return mag(dx, dy);
|
||||
}
|
||||
else {
|
||||
return 30;
|
||||
}
|
||||
}
|
||||
|
||||
void compile() {
|
||||
// compute the polygons from the path of Vec3f's
|
||||
if (exists) {
|
||||
clearPolys();
|
||||
|
||||
Vec3f p0, p1, p2;
|
||||
float radius0, radius1;
|
||||
float ax, bx, cx, dx;
|
||||
float ay, by, cy, dy;
|
||||
int axi, bxi, cxi, dxi, axip, axid;
|
||||
int ayi, byi, cyi, dyi, ayip, ayid;
|
||||
float p1x, p1y;
|
||||
float dx01, dy01, hp01, si01, co01;
|
||||
float dx02, dy02, hp02, si02, co02;
|
||||
float dx13, dy13, hp13, si13, co13;
|
||||
float taper = 1.0;
|
||||
|
||||
int nPathPoints = nPoints - 1;
|
||||
int lastPolyIndex = nPathPoints - 1;
|
||||
float npm1finv = 1.0 / max(1, nPathPoints - 1);
|
||||
|
||||
// handle the first point
|
||||
p0 = path[0];
|
||||
p1 = path[1];
|
||||
radius0 = p0.p * thickness;
|
||||
dx01 = p1.x - p0.x;
|
||||
dy01 = p1.y - p0.y;
|
||||
hp01 = sqrt(dx01*dx01 + dy01*dy01);
|
||||
if (hp01 == 0) {
|
||||
hp02 = 0.0001;
|
||||
}
|
||||
co01 = radius0 * dx01 / hp01;
|
||||
si01 = radius0 * dy01 / hp01;
|
||||
ax = p0.x - si01;
|
||||
ay = p0.y + co01;
|
||||
bx = p0.x + si01;
|
||||
by = p0.y - co01;
|
||||
|
||||
int xpts[];
|
||||
int ypts[];
|
||||
|
||||
int LC = 20;
|
||||
int RC = w-LC;
|
||||
int TC = 20;
|
||||
int BC = h-TC;
|
||||
float mint = 0.618;
|
||||
float tapow = 0.4;
|
||||
|
||||
// handle the middle points
|
||||
int i = 1;
|
||||
Polygon apoly;
|
||||
for (i = 1; i < nPathPoints; i++) {
|
||||
taper = pow((lastPolyIndex-i)*npm1finv,tapow);
|
||||
|
||||
p0 = path[i-1];
|
||||
p1 = path[i ];
|
||||
p2 = path[i+1];
|
||||
p1x = p1.x;
|
||||
p1y = p1.y;
|
||||
radius1 = Math.max(mint,taper*p1.p*thickness);
|
||||
|
||||
// assumes all segments are roughly the same length...
|
||||
dx02 = p2.x - p0.x;
|
||||
dy02 = p2.y - p0.y;
|
||||
hp02 = (float) Math.sqrt(dx02*dx02 + dy02*dy02);
|
||||
if (hp02 != 0) {
|
||||
hp02 = radius1/hp02;
|
||||
}
|
||||
co02 = dx02 * hp02;
|
||||
si02 = dy02 * hp02;
|
||||
|
||||
// translate the integer coordinates to the viewing rectangle
|
||||
axi = axip = (int)ax;
|
||||
ayi = ayip = (int)ay;
|
||||
axi=(axi<0)?(w-((-axi)%w)):axi%w;
|
||||
axid = axi-axip;
|
||||
ayi=(ayi<0)?(h-((-ayi)%h)):ayi%h;
|
||||
ayid = ayi-ayip;
|
||||
|
||||
// set the vertices of the polygon
|
||||
apoly = polygons[nPolys++];
|
||||
xpts = apoly.xpoints;
|
||||
ypts = apoly.ypoints;
|
||||
xpts[0] = axi = axid + axip;
|
||||
xpts[1] = bxi = axid + (int) bx;
|
||||
xpts[2] = cxi = axid + (int)(cx = p1x + si02);
|
||||
xpts[3] = dxi = axid + (int)(dx = p1x - si02);
|
||||
ypts[0] = ayi = ayid + ayip;
|
||||
ypts[1] = byi = ayid + (int) by;
|
||||
ypts[2] = cyi = ayid + (int)(cy = p1y - co02);
|
||||
ypts[3] = dyi = ayid + (int)(dy = p1y + co02);
|
||||
|
||||
// keep a record of where we cross the edge of the screen
|
||||
crosses[i] = 0;
|
||||
if ((axi<=LC)||(bxi<=LC)||(cxi<=LC)||(dxi<=LC)) {
|
||||
crosses[i]|=1;
|
||||
}
|
||||
if ((axi>=RC)||(bxi>=RC)||(cxi>=RC)||(dxi>=RC)) {
|
||||
crosses[i]|=2;
|
||||
}
|
||||
if ((ayi<=TC)||(byi<=TC)||(cyi<=TC)||(dyi<=TC)) {
|
||||
crosses[i]|=4;
|
||||
}
|
||||
if ((ayi>=BC)||(byi>=BC)||(cyi>=BC)||(dyi>=BC)) {
|
||||
crosses[i]|=8;
|
||||
}
|
||||
|
||||
//swap data for next time
|
||||
ax = dx;
|
||||
ay = dy;
|
||||
bx = cx;
|
||||
by = cy;
|
||||
}
|
||||
|
||||
// handle the last point
|
||||
p2 = path[nPathPoints];
|
||||
apoly = polygons[nPolys++];
|
||||
xpts = apoly.xpoints;
|
||||
ypts = apoly.ypoints;
|
||||
|
||||
xpts[0] = (int)ax;
|
||||
xpts[1] = (int)bx;
|
||||
xpts[2] = (int)(p2.x);
|
||||
xpts[3] = (int)(p2.x);
|
||||
|
||||
ypts[0] = (int)ay;
|
||||
ypts[1] = (int)by;
|
||||
ypts[2] = (int)(p2.y);
|
||||
ypts[3] = (int)(p2.y);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void smooth() {
|
||||
// average neighboring points
|
||||
|
||||
final float weight = 18;
|
||||
final float scale = 1.0 / (weight + 2);
|
||||
int nPointsMinusTwo = nPoints - 2;
|
||||
Vec3f lower, upper, center;
|
||||
|
||||
for (int i = 1; i < nPointsMinusTwo; i++) {
|
||||
lower = path[i-1];
|
||||
center = path[i];
|
||||
upper = path[i+1];
|
||||
|
||||
center.x = (lower.x + weight*center.x + upper.x)*scale;
|
||||
center.y = (lower.y + weight*center.y + upper.y)*scale;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
class Vec3f {
|
||||
float x;
|
||||
float y;
|
||||
float p; // Pressure
|
||||
|
||||
Vec3f() {
|
||||
set(0, 0, 0);
|
||||
}
|
||||
|
||||
Vec3f(float ix, float iy, float ip) {
|
||||
set(ix, iy, ip);
|
||||
}
|
||||
|
||||
void set(float ix, float iy, float ip) {
|
||||
x = ix;
|
||||
y = iy;
|
||||
p = ip;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,190 @@
|
||||
/**
|
||||
* Yellowtail
|
||||
* by Golan Levin (www.flong.com).
|
||||
*
|
||||
* Click, drag, and release to create a kinetic gesture.
|
||||
*
|
||||
* Yellowtail (1998-2000) is an interactive software system for the gestural
|
||||
* creation and performance of real-time abstract animation. Yellowtail repeats
|
||||
* a user's strokes end-over-end, enabling simultaneous specification of a
|
||||
* line's shape and quality of movement. Each line repeats according to its
|
||||
* own period, producing an ever-changing and responsive display of lively,
|
||||
* worm-like textures.
|
||||
*/
|
||||
|
||||
|
||||
import processing.opengl.*;
|
||||
import java.awt.Polygon;
|
||||
|
||||
Gesture gestureArray[];
|
||||
final int nGestures = 36; // Number of gestures
|
||||
final int minMove = 3; // Minimum travel for a new point
|
||||
int currentGestureID;
|
||||
|
||||
Polygon tempP;
|
||||
int tmpXp[];
|
||||
int tmpYp[];
|
||||
|
||||
|
||||
void setup() {
|
||||
size(1024, 768, OPENGL);
|
||||
background(0, 0, 0);
|
||||
noStroke();
|
||||
|
||||
currentGestureID = -1;
|
||||
gestureArray = new Gesture[nGestures];
|
||||
for (int i = 0; i < nGestures; i++) {
|
||||
gestureArray[i] = new Gesture(width, height);
|
||||
}
|
||||
clearGestures();
|
||||
}
|
||||
|
||||
|
||||
void draw() {
|
||||
background(0);
|
||||
|
||||
updateGeometry();
|
||||
fill(255, 255, 245);
|
||||
for (int i = 0; i < nGestures; i++) {
|
||||
renderGesture(gestureArray[i], width, height);
|
||||
}
|
||||
}
|
||||
|
||||
void mousePressed() {
|
||||
currentGestureID = (currentGestureID+1) % nGestures;
|
||||
Gesture G = gestureArray[currentGestureID];
|
||||
G.clear();
|
||||
G.clearPolys();
|
||||
G.addPoint(mouseX, mouseY);
|
||||
}
|
||||
|
||||
|
||||
void mouseDragged() {
|
||||
if (currentGestureID >= 0) {
|
||||
Gesture G = gestureArray[currentGestureID];
|
||||
if (G.distToLast(mouseX, mouseY) > minMove) {
|
||||
G.addPoint(mouseX, mouseY);
|
||||
G.smooth();
|
||||
G.compile();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void keyPressed() {
|
||||
if (key == '+' || key == '=') {
|
||||
if (currentGestureID >= 0) {
|
||||
float th = gestureArray[currentGestureID].thickness;
|
||||
gestureArray[currentGestureID].thickness = min(96, th+1);
|
||||
gestureArray[currentGestureID].compile();
|
||||
}
|
||||
} else if (key == '-') {
|
||||
if (currentGestureID >= 0) {
|
||||
float th = gestureArray[currentGestureID].thickness;
|
||||
gestureArray[currentGestureID].thickness = max(2, th-1);
|
||||
gestureArray[currentGestureID].compile();
|
||||
}
|
||||
} else if (key == ' ') {
|
||||
clearGestures();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void renderGesture(Gesture gesture, int w, int h) {
|
||||
if (gesture.exists) {
|
||||
if (gesture.nPolys > 0) {
|
||||
Polygon polygons[] = gesture.polygons;
|
||||
int crosses[] = gesture.crosses;
|
||||
|
||||
int xpts[];
|
||||
int ypts[];
|
||||
Polygon p;
|
||||
int cr;
|
||||
|
||||
beginShape(QUADS);
|
||||
int gnp = gesture.nPolys;
|
||||
for (int i=0; i<gnp; i++) {
|
||||
|
||||
p = polygons[i];
|
||||
xpts = p.xpoints;
|
||||
ypts = p.ypoints;
|
||||
|
||||
vertex(xpts[0], ypts[0]);
|
||||
vertex(xpts[1], ypts[1]);
|
||||
vertex(xpts[2], ypts[2]);
|
||||
vertex(xpts[3], ypts[3]);
|
||||
|
||||
if ((cr = crosses[i]) > 0) {
|
||||
if ((cr & 3)>0) {
|
||||
vertex(xpts[0]+w, ypts[0]);
|
||||
vertex(xpts[1]+w, ypts[1]);
|
||||
vertex(xpts[2]+w, ypts[2]);
|
||||
vertex(xpts[3]+w, ypts[3]);
|
||||
|
||||
vertex(xpts[0]-w, ypts[0]);
|
||||
vertex(xpts[1]-w, ypts[1]);
|
||||
vertex(xpts[2]-w, ypts[2]);
|
||||
vertex(xpts[3]-w, ypts[3]);
|
||||
}
|
||||
if ((cr & 12)>0) {
|
||||
vertex(xpts[0], ypts[0]+h);
|
||||
vertex(xpts[1], ypts[1]+h);
|
||||
vertex(xpts[2], ypts[2]+h);
|
||||
vertex(xpts[3], ypts[3]+h);
|
||||
|
||||
vertex(xpts[0], ypts[0]-h);
|
||||
vertex(xpts[1], ypts[1]-h);
|
||||
vertex(xpts[2], ypts[2]-h);
|
||||
vertex(xpts[3], ypts[3]-h);
|
||||
}
|
||||
|
||||
// I have knowingly retained the small flaw of not
|
||||
// completely dealing with the corner conditions
|
||||
// (the case in which both of the above are true).
|
||||
}
|
||||
}
|
||||
endShape();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void updateGeometry() {
|
||||
Gesture J;
|
||||
for (int g=0; g<nGestures; g++) {
|
||||
if ((J=gestureArray[g]).exists) {
|
||||
if (g!=currentGestureID) {
|
||||
advanceGesture(J);
|
||||
} else if (!mousePressed) {
|
||||
advanceGesture(J);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void advanceGesture(Gesture gesture) {
|
||||
// Move a Gesture one step
|
||||
if (gesture.exists) { // check
|
||||
int nPts = gesture.nPoints;
|
||||
int nPts1 = nPts-1;
|
||||
Vec3f path[];
|
||||
float jx = gesture.jumpDx;
|
||||
float jy = gesture.jumpDy;
|
||||
|
||||
if (nPts > 0) {
|
||||
path = gesture.path;
|
||||
for (int i = nPts1; i > 0; i--) {
|
||||
path[i].x = path[i-1].x;
|
||||
path[i].y = path[i-1].y;
|
||||
}
|
||||
path[0].x = path[nPts1].x - jx;
|
||||
path[0].y = path[nPts1].y - jy;
|
||||
gesture.compile();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void clearGestures() {
|
||||
for (int i = 0; i < nGestures; i++) {
|
||||
gestureArray[i].clear();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,194 @@
|
||||
/**
|
||||
* PDF Complex
|
||||
* by Marius Watz (workshop.evolutionzone.com).
|
||||
*
|
||||
* Example using PDF to output complex 3D geometry for print.
|
||||
* Press "s" to save a PDF.
|
||||
*/
|
||||
|
||||
|
||||
import processing.opengl.*;
|
||||
import processing.pdf.*;
|
||||
|
||||
// Trig lookup tables borrowed from Toxi. Cryptic but effective
|
||||
float sinLUT[];
|
||||
float cosLUT[];
|
||||
float SINCOS_PRECISION=1.0;
|
||||
int SINCOS_LENGTH= int((360.0/SINCOS_PRECISION));
|
||||
|
||||
// System data
|
||||
boolean dosave=false;
|
||||
int num;
|
||||
float pt[];
|
||||
int style[];
|
||||
|
||||
|
||||
void setup() {
|
||||
size(600, 600, OPENGL);
|
||||
frameRate(24);
|
||||
background(255);
|
||||
|
||||
// Fill the tables
|
||||
sinLUT=new float[SINCOS_LENGTH];
|
||||
cosLUT=new float[SINCOS_LENGTH];
|
||||
for (int i = 0; i < SINCOS_LENGTH; i++) {
|
||||
sinLUT[i]= (float)Math.sin(i*DEG_TO_RAD*SINCOS_PRECISION);
|
||||
cosLUT[i]= (float)Math.cos(i*DEG_TO_RAD*SINCOS_PRECISION);
|
||||
}
|
||||
|
||||
num = 150;
|
||||
pt = new float[6*num]; // rotx, roty, deg, rad, w, speed
|
||||
style = new int[2*num]; // color, render style
|
||||
|
||||
// Set up arc shapes
|
||||
int index=0;
|
||||
float prob;
|
||||
for (int i=0; i<num; i++) {
|
||||
pt[index++] = random(PI*2); // Random X axis rotation
|
||||
pt[index++] = random(PI*2); // Random Y axis rotation
|
||||
|
||||
pt[index++] = random(60,80); // Short to quarter-circle arcs
|
||||
if(random(100)>90) pt[index]=(int)random(8,27)*10;
|
||||
|
||||
pt[index++] = int(random(2,50)*5); // Radius. Space them out nicely
|
||||
|
||||
pt[index++] = random(4,32); // Width of band
|
||||
if(random(100)>90) pt[index]=random(40,60); // Width of band
|
||||
|
||||
pt[index++] = radians(random(5,30))/5; // Speed of rotation
|
||||
|
||||
// get colors
|
||||
prob = random(100);
|
||||
if(prob<30) style[i*2]=colorBlended(random(1), 255,0,100, 255,0,0, 210);
|
||||
else if(prob<70) style[i*2]=colorBlended(random(1), 0,153,255, 170,225,255, 210);
|
||||
else if(prob<90) style[i*2]=colorBlended(random(1), 200,255,0, 150,255,0, 210);
|
||||
else style[i*2]=color(255,255,255, 220);
|
||||
|
||||
if(prob<50) style[i*2]=colorBlended(random(1), 200,255,0, 50,120,0, 210);
|
||||
else if(prob<90) style[i*2]=colorBlended(random(1), 255,100,0, 255,255,0, 210);
|
||||
else style[i*2]=color(255,255,255, 220);
|
||||
|
||||
style[i*2+1]=(int)(random(100))%3;
|
||||
}
|
||||
}
|
||||
|
||||
void draw() {
|
||||
|
||||
if(dosave) {
|
||||
// set up PGraphicsPDF for use with beginRaw()
|
||||
PGraphicsPDF pdf = (PGraphicsPDF)beginRaw(PDF, "pdf_complex_out.pdf");
|
||||
|
||||
// set default Illustrator stroke styles and paint background rect.
|
||||
pdf.strokeJoin(MITER);
|
||||
pdf.strokeCap(SQUARE);
|
||||
pdf.fill(0);
|
||||
pdf.noStroke();
|
||||
pdf.rect(0,0, width,height);
|
||||
}
|
||||
|
||||
background(0);
|
||||
|
||||
int index=0;
|
||||
translate(width/2,height/2,0);
|
||||
rotateX(PI/6);
|
||||
rotateY(PI/6);
|
||||
|
||||
for (int i=0; i<num; i++) {
|
||||
pushMatrix();
|
||||
|
||||
rotateX(pt[index++]);
|
||||
rotateY(pt[index++]);
|
||||
|
||||
if(style[i*2+1]==0) {
|
||||
stroke(style[i*2]);
|
||||
noFill();
|
||||
strokeWeight(1);
|
||||
arcLine(0,0, pt[index++],pt[index++],pt[index++]);
|
||||
}
|
||||
else if(style[i*2+1]==1) {
|
||||
fill(style[i*2]);
|
||||
noStroke();
|
||||
arcLineBars(0,0, pt[index++],pt[index++],pt[index++]);
|
||||
}
|
||||
else {
|
||||
fill(style[i*2]);
|
||||
noStroke();
|
||||
arc(0,0, pt[index++],pt[index++],pt[index++]);
|
||||
}
|
||||
|
||||
// increase rotation
|
||||
pt[index-5]+=pt[index]/10;
|
||||
pt[index-4]+=pt[index++]/20;
|
||||
|
||||
popMatrix();
|
||||
}
|
||||
|
||||
if(dosave) {
|
||||
endRaw();
|
||||
dosave=false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Get blend of two colors
|
||||
public int colorBlended(float fract,
|
||||
float r, float g, float b,
|
||||
float r2, float g2, float b2, float a) {
|
||||
|
||||
r2 = (r2 - r);
|
||||
g2 = (g2 - g);
|
||||
b2 = (b2 - b);
|
||||
return color(r + r2 * fract, g + g2 * fract, b + b2 * fract, a);
|
||||
}
|
||||
|
||||
|
||||
// Draw arc line
|
||||
public void arcLine(float x,float y,float deg,float rad,float w) {
|
||||
int a=(int)(min (deg/SINCOS_PRECISION,SINCOS_LENGTH-1));
|
||||
int numlines=(int)(w/2);
|
||||
|
||||
for (int j=0; j<numlines; j++) {
|
||||
beginShape();
|
||||
for (int i=0; i<a; i++) {
|
||||
vertex(cosLUT[i]*rad+x,sinLUT[i]*rad+y);
|
||||
}
|
||||
endShape();
|
||||
rad += 2;
|
||||
}
|
||||
}
|
||||
|
||||
// Draw arc line with bars
|
||||
public void arcLineBars(float x,float y,float deg,float rad,float w) {
|
||||
int a = int((min (deg/SINCOS_PRECISION,SINCOS_LENGTH-1)));
|
||||
a /= 4;
|
||||
|
||||
beginShape(QUADS);
|
||||
for (int i=0; i<a; i+=4) {
|
||||
vertex(cosLUT[i]*(rad)+x,sinLUT[i]*(rad)+y);
|
||||
vertex(cosLUT[i]*(rad+w)+x,sinLUT[i]*(rad+w)+y);
|
||||
vertex(cosLUT[i+2]*(rad+w)+x,sinLUT[i+2]*(rad+w)+y);
|
||||
vertex(cosLUT[i+2]*(rad)+x,sinLUT[i+2]*(rad)+y);
|
||||
}
|
||||
endShape();
|
||||
}
|
||||
|
||||
// Draw solid arc
|
||||
public void arc(float x,float y,float deg,float rad,float w) {
|
||||
int a = int(min (deg/SINCOS_PRECISION,SINCOS_LENGTH-1));
|
||||
beginShape(QUAD_STRIP);
|
||||
for (int i = 0; i < a; i++) {
|
||||
vertex(cosLUT[i]*(rad)+x,sinLUT[i]*(rad)+y);
|
||||
vertex(cosLUT[i]*(rad+w)+x,sinLUT[i]*(rad+w)+y);
|
||||
}
|
||||
endShape();
|
||||
}
|
||||
|
||||
void keyPressed() {
|
||||
if (key == 's') {
|
||||
dosave=true;
|
||||
}
|
||||
}
|
||||
|
||||
void mouseReleased() {
|
||||
background(255);
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
/**
|
||||
* Large Page.
|
||||
*
|
||||
* Saves one frame as a PDF with a size larger
|
||||
* than the screen. When PDF is used as the renderer
|
||||
* (the third parameter of size) the display window
|
||||
* does not open. The file is saved to the sketch folder.
|
||||
*/
|
||||
|
||||
|
||||
import processing.pdf.*;
|
||||
|
||||
void setup()
|
||||
{
|
||||
size(2000, 2000, PDF, "Line.pdf");
|
||||
}
|
||||
|
||||
void draw()
|
||||
{
|
||||
background(255);
|
||||
stroke(0, 20);
|
||||
strokeWeight(20.0);
|
||||
line(200, 0, width/2, height);
|
||||
|
||||
exit(); // Quit the program
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
/**
|
||||
* Many PDFs.
|
||||
*
|
||||
* Saves one PDF file each each frame while the mouse is pressed.
|
||||
* When the mouse is released, the PDF creation stops.
|
||||
*/
|
||||
|
||||
|
||||
import processing.pdf.*;
|
||||
|
||||
boolean savePDF = false;
|
||||
|
||||
void setup() {
|
||||
size(600, 600);
|
||||
frameRate(24);
|
||||
}
|
||||
|
||||
void draw() {
|
||||
if(savePDF == true) {
|
||||
beginRecord(PDF, "lines" + frameCount + ".pdf");
|
||||
}
|
||||
background(255);
|
||||
stroke(0, 20);
|
||||
strokeWeight(20.0);
|
||||
line(mouseX, 0, width-mouseY, height);
|
||||
if(savePDF == true) {
|
||||
endRecord();
|
||||
}
|
||||
}
|
||||
|
||||
void mousePressed() {
|
||||
savePDF = true;
|
||||
}
|
||||
|
||||
void mouseReleased() {
|
||||
savePDF = false;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
/**
|
||||
* Many Pages.
|
||||
*
|
||||
* Saves a new page into a PDF file each loop through draw().
|
||||
* Pressing the mouse finishes writing the file and exits the program.
|
||||
*/
|
||||
|
||||
|
||||
import processing.pdf.*;
|
||||
|
||||
PGraphicsPDF pdf;
|
||||
|
||||
void setup() {
|
||||
size(600, 600);
|
||||
frameRate(4);
|
||||
pdf = (PGraphicsPDF)beginRecord(PDF, "Lines.pdf");
|
||||
beginRecord(pdf);
|
||||
}
|
||||
|
||||
void draw() {
|
||||
background(255);
|
||||
stroke(0, 20);
|
||||
strokeWeight(20.0);
|
||||
line(mouseX, 0, width-mouseY, height);
|
||||
pdf.nextPage();
|
||||
}
|
||||
|
||||
void mousePressed() {
|
||||
endRecord();
|
||||
exit();
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
/**
|
||||
* Mouse Press.
|
||||
*
|
||||
* Saves one PDF of the contents of the display window
|
||||
* each time the mouse is pressed.
|
||||
*/
|
||||
|
||||
|
||||
import processing.pdf.*;
|
||||
|
||||
boolean saveOneFrame = false;
|
||||
|
||||
void setup() {
|
||||
size(600, 600);
|
||||
frameRate(24);
|
||||
}
|
||||
|
||||
void draw() {
|
||||
if(saveOneFrame == true) {
|
||||
beginRecord(PDF, "Line.pdf");
|
||||
}
|
||||
|
||||
background(255);
|
||||
stroke(0, 20);
|
||||
strokeWeight(20.0);
|
||||
line(mouseX, 0, width-mouseY, height);
|
||||
|
||||
if(saveOneFrame == true) {
|
||||
endRecord();
|
||||
saveOneFrame = false;
|
||||
}
|
||||
}
|
||||
|
||||
void mousePressed() {
|
||||
saveOneFrame = true;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
/**
|
||||
* Multiple Frames.
|
||||
*
|
||||
* Saves one PDF document of many frames drawn to the screen.
|
||||
* Starts the file when the mouse is pressed and end the file
|
||||
* when the mouse is released.
|
||||
*/
|
||||
|
||||
|
||||
import processing.pdf.*;
|
||||
|
||||
void setup() {
|
||||
size(600, 600);
|
||||
frameRate(24);
|
||||
background(255);
|
||||
}
|
||||
|
||||
void draw() {
|
||||
stroke(0, 20);
|
||||
strokeWeight(20.0);
|
||||
line(mouseX, 0, width-mouseY, height);
|
||||
}
|
||||
|
||||
void mousePressed() {
|
||||
beginRecord(PDF, "Lines.pdf");
|
||||
background(255);
|
||||
}
|
||||
|
||||
void mouseReleased() {
|
||||
endRecord();
|
||||
background(255);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
/**
|
||||
* One Frame.
|
||||
*
|
||||
* Saves one PDF with the contents of the display window.
|
||||
* Because this example uses beginRecord, the image is shown
|
||||
* on the display window and is saved to the file.
|
||||
*/
|
||||
|
||||
|
||||
import processing.pdf.*;
|
||||
|
||||
size(600, 600);
|
||||
|
||||
beginRecord(PDF, "line.pdf");
|
||||
|
||||
background(255);
|
||||
stroke(0, 20);
|
||||
strokeWeight(20.0);
|
||||
line(200, 0, 400, height);
|
||||
|
||||
endRecord();
|
||||
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
/**
|
||||
* RandomBook
|
||||
*
|
||||
* Creates a 768 page book of random lines.
|
||||
*/
|
||||
|
||||
import processing.pdf.*;
|
||||
|
||||
PGraphicsPDF pdf;
|
||||
|
||||
void setup() {
|
||||
size(594, 842);
|
||||
// randomSeed(0); // Uncomment to make the same book each time
|
||||
pdf = (PGraphicsPDF)beginRecord(PDF, "RandomBook.pdf");
|
||||
beginRecord(pdf);
|
||||
}
|
||||
|
||||
void draw() {
|
||||
background(255);
|
||||
|
||||
for (int i=0; i<100; i++) {
|
||||
float r = random(1.0);
|
||||
if(r < 0.2) {
|
||||
stroke(255);
|
||||
} else {
|
||||
stroke(0);
|
||||
}
|
||||
float sw = pow(random(1.0), 12);
|
||||
strokeWeight(sw * 260);
|
||||
float x1 = random(-200, -100);
|
||||
float x2 = random(width+100, width+200);
|
||||
float y1 = random(-100, height+100);
|
||||
float y2 = random(-100, height+100);
|
||||
line(x1, y1, x2, y2);
|
||||
}
|
||||
|
||||
if(frameCount == 768) {
|
||||
endRecord();
|
||||
exit(); // Quit
|
||||
} else {
|
||||
pdf.nextPage(); // Tell it to go to the next page
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,150 @@
|
||||
/**
|
||||
* Serial Call-Response
|
||||
* by Tom Igoe.
|
||||
*
|
||||
* Sends a byte out the serial port, and reads 3 bytes in.
|
||||
* Sets foregound color, xpos, and ypos of a circle onstage
|
||||
* using the values returned from the serial port.
|
||||
* Thanks to Daniel Shiffman and Greg Shakar for the improvements.
|
||||
*
|
||||
* Note: This sketch assumes that the device on the other end of the serial
|
||||
* port is going to send a single byte of value 65 (ASCII A) on startup.
|
||||
* The sketch waits for that byte, then sends an ASCII A whenever
|
||||
* it wants more data.
|
||||
*/
|
||||
|
||||
|
||||
import processing.serial.*;
|
||||
|
||||
int bgcolor; // Background color
|
||||
int fgcolor; // Fill color
|
||||
Serial myPort; // The serial port
|
||||
int[] serialInArray = new int[3]; // Where we'll put what we receive
|
||||
int serialCount = 0; // A count of how many bytes we receive
|
||||
int xpos, ypos; // Starting position of the ball
|
||||
boolean firstContact = false; // Whether we've heard from the microcontroller
|
||||
|
||||
void setup() {
|
||||
size(256, 256); // Stage size
|
||||
noStroke(); // No border on the next thing drawn
|
||||
|
||||
// Set the starting position of the ball (middle of the stage)
|
||||
xpos = width/2;
|
||||
ypos = height/2;
|
||||
|
||||
// Print a list of the serial ports, for debugging purposes:
|
||||
println(Serial.list());
|
||||
|
||||
// I know that the first port in the serial list on my mac
|
||||
// is always my FTDI adaptor, so I open Serial.list()[0].
|
||||
// On Windows machines, this generally opens COM1.
|
||||
// Open whatever port is the one you're using.
|
||||
String portName = Serial.list()[0];
|
||||
myPort = new Serial(this, portName, 9600);
|
||||
}
|
||||
|
||||
void draw() {
|
||||
background(bgcolor);
|
||||
fill(fgcolor);
|
||||
// Draw the shape
|
||||
ellipse(xpos, ypos, 20, 20);
|
||||
}
|
||||
|
||||
void serialEvent(Serial myPort) {
|
||||
// read a byte from the serial port:
|
||||
int inByte = myPort.read();
|
||||
// if this is the first byte received, and it's an A,
|
||||
// clear the serial buffer and note that you've
|
||||
// had first contact from the microcontroller.
|
||||
// Otherwise, add the incoming byte to the array:
|
||||
if (firstContact == false) {
|
||||
if (inByte == 'A') {
|
||||
myPort.clear(); // clear the serial port buffer
|
||||
firstContact = true; // you've had first contact from the microcontroller
|
||||
myPort.write('A'); // ask for more
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Add the latest byte from the serial port to array:
|
||||
serialInArray[serialCount] = inByte;
|
||||
serialCount++;
|
||||
|
||||
// If we have 3 bytes:
|
||||
if (serialCount > 2 ) {
|
||||
xpos = serialInArray[0];
|
||||
ypos = serialInArray[1];
|
||||
fgcolor = serialInArray[2];
|
||||
|
||||
// print the values (for debugging purposes only):
|
||||
println(xpos + "\t" + ypos + "\t" + fgcolor);
|
||||
|
||||
// Send a capital A to request new sensor readings:
|
||||
myPort.write('A');
|
||||
// Reset serialCount:
|
||||
serialCount = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
|
||||
// Serial Call and Response
|
||||
// by Tom Igoe
|
||||
// Language: Wiring/Arduino
|
||||
|
||||
// This program sends an ASCII A (byte of value 65) on startup
|
||||
// and repeats that until it gets some data in.
|
||||
// Then it waits for a byte in the serial port, and
|
||||
// sends three sensor values whenever it gets a byte in.
|
||||
|
||||
// Thanks to Greg Shakar for the improvements
|
||||
|
||||
// Created 26 Sept. 2005
|
||||
// Updated 18 April 2008
|
||||
|
||||
|
||||
int firstSensor = 0; // first analog sensor
|
||||
int secondSensor = 0; // second analog sensor
|
||||
int thirdSensor = 0; // digital sensor
|
||||
int inByte = 0; // incoming serial byte
|
||||
|
||||
void setup()
|
||||
{
|
||||
// start serial port at 9600 bps:
|
||||
Serial.begin(9600);
|
||||
pinMode(2, INPUT); // digital sensor is on digital pin 2
|
||||
establishContact(); // send a byte to establish contact until Processing responds
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
// if we get a valid byte, read analog ins:
|
||||
if (Serial.available() > 0) {
|
||||
// get incoming byte:
|
||||
inByte = Serial.read();
|
||||
// read first analog input, divide by 4 to make the range 0-255:
|
||||
firstSensor = analogRead(0)/4;
|
||||
// delay 10ms to let the ADC recover:
|
||||
delay(10);
|
||||
// read second analog input, divide by 4 to make the range 0-255:
|
||||
secondSensor = analogRead(1)/4;
|
||||
// read switch, multiply by 155 and add 100
|
||||
// so that you're sending 100 or 255:
|
||||
thirdSensor = 100 + (155 * digitalRead(2));
|
||||
// send sensor values:
|
||||
Serial.print(firstSensor, BYTE);
|
||||
Serial.print(secondSensor, BYTE);
|
||||
Serial.print(thirdSensor, BYTE);
|
||||
}
|
||||
}
|
||||
|
||||
void establishContact() {
|
||||
while (Serial.available() <= 0) {
|
||||
Serial.print('A', BYTE); // send a capital A
|
||||
delay(300);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
*/
|
||||
@@ -0,0 +1,50 @@
|
||||
/**
|
||||
* Serial Duplex
|
||||
* by Tom Igoe.
|
||||
*
|
||||
* Sends a byte out the serial port when you type a key
|
||||
* listens for bytes received, and displays their value.
|
||||
* This is just a quick application for testing serial data
|
||||
* in both directions.
|
||||
*/
|
||||
|
||||
|
||||
import processing.serial.*;
|
||||
|
||||
Serial myPort; // The serial port
|
||||
int whichKey = -1; // Variable to hold keystoke values
|
||||
int inByte = -1; // Incoming serial data
|
||||
|
||||
void setup() {
|
||||
size(400, 300);
|
||||
// create a font with the third font available to the system:
|
||||
PFont myFont = createFont(PFont.list()[2], 14);
|
||||
textFont(myFont);
|
||||
|
||||
// List all the available serial ports:
|
||||
println(Serial.list());
|
||||
|
||||
// I know that the first port in the serial list on my mac
|
||||
// is always my FTDI adaptor, so I open Serial.list()[0].
|
||||
// In Windows, this usually opens COM1.
|
||||
// Open whatever port is the one you're using.
|
||||
String portName = Serial.list()[0];
|
||||
myPort = new Serial(this, portName, 9600);
|
||||
}
|
||||
|
||||
void draw() {
|
||||
background(0);
|
||||
text("Last Received: " + inByte, 10, 130);
|
||||
text("Last Sent: " + whichKey, 10, 100);
|
||||
}
|
||||
|
||||
void serialEvent(Serial myPort) {
|
||||
inByte = myPort.read();
|
||||
}
|
||||
|
||||
void keyPressed() {
|
||||
// Send the keystroke out:
|
||||
myPort.write(key);
|
||||
whichKey = key;
|
||||
}
|
||||
|
||||
Binary file not shown.
@@ -0,0 +1,86 @@
|
||||
/**
|
||||
* Many Serial Ports
|
||||
*
|
||||
* Read data from the multiple Serial Ports
|
||||
*/
|
||||
|
||||
|
||||
import processing.serial.*;
|
||||
|
||||
Serial[] myPorts = new Serial[2]; // Create a list of objects from Serial class
|
||||
int[] dataIn = new int[2]; // a list to hold data from the serial ports
|
||||
|
||||
void setup() {
|
||||
size(400, 300);
|
||||
// print a list of the serial ports:
|
||||
println(Serial.list());
|
||||
// On my machine, the first and third ports in the list
|
||||
// were the serial ports that my microcontrollers were
|
||||
// attached to.
|
||||
// Open whatever ports ares the ones you're using.
|
||||
|
||||
// get the ports' names:
|
||||
String portOne = Serial.list()[0];
|
||||
String portTwo = Serial.list()[2];
|
||||
// open the ports:
|
||||
myPorts[0] = new Serial(this, portOne, 9600);
|
||||
myPorts[1] = new Serial(this, portTwo, 9600);
|
||||
}
|
||||
|
||||
|
||||
void draw() {
|
||||
// clear the screen:
|
||||
background(0);
|
||||
// use the latest byte from port 0 for the first circle
|
||||
fill(dataIn[0]);
|
||||
ellipse(width/3, height/2, 40, 40);
|
||||
// use the latest byte from port 1 for the second circle
|
||||
fill(dataIn[1]);
|
||||
ellipse(2*width/3, height/2, 40, 40);
|
||||
}
|
||||
|
||||
/**
|
||||
* When SerialEvent is generated, it'll also give you
|
||||
* the port that generated it. Check that against a list
|
||||
* of the ports you know you opened to find out where
|
||||
* the data came from
|
||||
*/
|
||||
void serialEvent(Serial thisPort) {
|
||||
// variable to hold the number of the port:
|
||||
int portNumber = -1;
|
||||
|
||||
// iterate over the list of ports opened, and match the
|
||||
// one that generated this event:
|
||||
for (int p = 0; p < myPorts.length; p++) {
|
||||
if (thisPort == myPorts[p]) {
|
||||
portNumber = p;
|
||||
}
|
||||
}
|
||||
// read a byte from the port:
|
||||
int inByte = thisPort.read();
|
||||
// put it in the list that holds the latest data from each port:
|
||||
dataIn[portNumber] = inByte;
|
||||
// tell us who sent what:
|
||||
println("Got " + inByte + " from serial port " + portNumber);
|
||||
}
|
||||
|
||||
/*
|
||||
The following Wiring/Arduino code runs on both microcontrollers that
|
||||
were used to send data to this sketch:
|
||||
|
||||
void setup()
|
||||
{
|
||||
// start serial port at 9600 bps:
|
||||
Serial.begin(9600);
|
||||
}
|
||||
|
||||
void loop() {
|
||||
// read analog input, divide by 4 to make the range 0-255:
|
||||
int analogValue = analogRead(0)/4;
|
||||
Serial.print(analogValue, BYTE);
|
||||
// pause for 10 milliseconds:
|
||||
delay(10);
|
||||
}
|
||||
|
||||
|
||||
*/
|
||||
@@ -0,0 +1,64 @@
|
||||
/**
|
||||
* Simple Read
|
||||
*
|
||||
* Read data from the serial port and change the color of a rectangle
|
||||
* when a switch connected to a Wiring or Arduino board is pressed and released.
|
||||
* This example works with the Wiring / Arduino program that follows below.
|
||||
*/
|
||||
|
||||
|
||||
import processing.serial.*;
|
||||
|
||||
Serial myPort; // Create object from Serial class
|
||||
int val; // Data received from the serial port
|
||||
|
||||
void setup()
|
||||
{
|
||||
size(200, 200);
|
||||
// I know that the first port in the serial list on my mac
|
||||
// is always my FTDI adaptor, so I open Serial.list()[0].
|
||||
// On Windows machines, this generally opens COM1.
|
||||
// Open whatever port is the one you're using.
|
||||
String portName = Serial.list()[0];
|
||||
myPort = new Serial(this, portName, 9600);
|
||||
}
|
||||
|
||||
void draw()
|
||||
{
|
||||
if ( myPort.available() > 0) { // If data is available,
|
||||
val = myPort.read(); // read it and store it in val
|
||||
}
|
||||
background(255); // Set background to white
|
||||
if (val == 0) { // If the serial value is 0,
|
||||
fill(0); // set fill to black
|
||||
}
|
||||
else { // If the serial value is not 0,
|
||||
fill(204); // set fill to light gray
|
||||
}
|
||||
rect(50, 50, 100, 100);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
|
||||
// Wiring / Arduino Code
|
||||
// Code for sensing a switch status and writing the value to the serial port.
|
||||
|
||||
int switchPin = 4; // Switch connected to pin 4
|
||||
|
||||
void setup() {
|
||||
pinMode(switchPin, INPUT); // Set pin 0 as an input
|
||||
Serial.begin(9600); // Start serial communication at 9600 bps
|
||||
}
|
||||
|
||||
void loop() {
|
||||
if (digitalRead(switchPin) == HIGH) { // If switch is ON,
|
||||
Serial.print(1, BYTE); // send 1 to Processing
|
||||
} else { // If the switch is not ON,
|
||||
Serial.print(0, BYTE); // send 0 to Processing
|
||||
}
|
||||
delay(100); // Wait 100 milliseconds
|
||||
}
|
||||
|
||||
*/
|
||||
@@ -0,0 +1,67 @@
|
||||
/**
|
||||
* Simple Write.
|
||||
*
|
||||
* Check if the mouse is over a rectangle and writes the status to the serial port.
|
||||
* This example works with the Wiring / Arduino program that follows below.
|
||||
*/
|
||||
|
||||
|
||||
import processing.serial.*;
|
||||
|
||||
Serial myPort; // Create object from Serial class
|
||||
int val; // Data received from the serial port
|
||||
|
||||
void setup()
|
||||
{
|
||||
size(200, 200);
|
||||
// I know that the first port in the serial list on my mac
|
||||
// is always my FTDI adaptor, so I open Serial.list()[0].
|
||||
// On Windows machines, this generally opens COM1.
|
||||
// Open whatever port is the one you're using.
|
||||
String portName = Serial.list()[0];
|
||||
myPort = new Serial(this, portName, 9600);
|
||||
}
|
||||
|
||||
void draw() {
|
||||
background(255);
|
||||
if (mouseOverRect() == true) { // If mouse is over square,
|
||||
fill(204); // change color and
|
||||
myPort.write('H'); // send an H to indicate mouse is over square
|
||||
}
|
||||
else { // If mouse is not over square,
|
||||
fill(0); // change color and
|
||||
myPort.write('L'); // send an L otherwise
|
||||
}
|
||||
rect(50, 50, 100, 100); // Draw a square
|
||||
}
|
||||
|
||||
boolean mouseOverRect() { // Test if mouse is over square
|
||||
return ((mouseX >= 50) && (mouseX <= 150) && (mouseY >= 50) && (mouseY <= 150));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
// Wiring/Arduino code:
|
||||
// Read data from the serial and turn ON or OFF a light depending on the value
|
||||
|
||||
char val; // Data received from the serial port
|
||||
int ledPin = 4; // Set the pin to digital I/O 4
|
||||
|
||||
void setup() {
|
||||
pinMode(ledPin, OUTPUT); // Set pin as OUTPUT
|
||||
Serial.begin(9600); // Start serial communication at 9600 bps
|
||||
}
|
||||
|
||||
void loop() {
|
||||
if (Serial.available()) { // If data is available to read,
|
||||
val = Serial.read(); // read it and store it in val
|
||||
}
|
||||
if (val == 'H') { // If H was received
|
||||
digitalWrite(ledPin, HIGH); // turn the LED on
|
||||
} else {
|
||||
digitalWrite(ledPin, LOW); // Otherwise turn it OFF
|
||||
}
|
||||
delay(100); // Wait 100 milliseconds for next reading
|
||||
}
|
||||
|
||||
*/
|
||||
@@ -0,0 +1,134 @@
|
||||
/**
|
||||
* ASCII Video
|
||||
* by Ben Fry.
|
||||
*
|
||||
* Text characters have been used to represent images since the earliest computers.
|
||||
* This sketch is a simple homage that re-interprets live video as ASCII text.
|
||||
* See the keyPressed function for more options, like changing the font size.
|
||||
*/
|
||||
|
||||
import processing.video.*;
|
||||
|
||||
Capture video;
|
||||
boolean cheatScreen;
|
||||
|
||||
// All ASCII characters, sorted according to their visual density
|
||||
String letterOrder =
|
||||
" .`-_':,;^=+/\"|)\\<>)iv%xclrs{*}I?!][1taeo7zjLu" +
|
||||
"nT#JCwfy325Fp6mqSghVd4EgXPGZbYkOA&8U$@KHDBWNMR0Q";
|
||||
char[] letters;
|
||||
|
||||
float[] bright;
|
||||
char[] chars;
|
||||
|
||||
PFont font;
|
||||
float fontSize = 1.5;
|
||||
|
||||
|
||||
public void setup() {
|
||||
size(640, 480, P2D);
|
||||
// Or run full screen, more fun! Use with Sketch -> Present
|
||||
//size(screen.width, screen.height, OPENGL);
|
||||
|
||||
// Uses the default video input, see the reference if this causes an error
|
||||
video = new Capture(this, 80, 60, 15);
|
||||
int count = video.width * video.height;
|
||||
|
||||
font = loadFont("UniversLTStd-Light-48.vlw");
|
||||
|
||||
// for the 256 levels of brightness, distribute the letters across
|
||||
// the an array of 256 elements to use for the lookup
|
||||
letters = new char[256];
|
||||
for (int i = 0; i < 256; i++) {
|
||||
int index = int(map(i, 0, 256, 0, letterOrder.length()));
|
||||
letters[i] = letterOrder.charAt(index);
|
||||
}
|
||||
|
||||
// current characters for each position in the video
|
||||
chars = new char[count];
|
||||
|
||||
// current brightness for each point
|
||||
bright = new float[count];
|
||||
for (int i = 0; i < count; i++) {
|
||||
// set each brightness at the midpoint to start
|
||||
bright[i] = 128;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void captureEvent(Capture c) {
|
||||
c.read();
|
||||
}
|
||||
|
||||
|
||||
void draw() {
|
||||
background(0);
|
||||
|
||||
pushMatrix();
|
||||
|
||||
float hgap = width / float(video.width);
|
||||
float vgap = height / float(video.height);
|
||||
|
||||
scale(max(hgap, vgap) * fontSize);
|
||||
textFont(font, fontSize);
|
||||
|
||||
int index = 0;
|
||||
for (int y = 1; y < video.height; y++) {
|
||||
|
||||
// Move down for next line
|
||||
translate(0, 1.0 / fontSize);
|
||||
|
||||
pushMatrix();
|
||||
for (int x = 0; x < video.width; x++) {
|
||||
int pixelColor = video.pixels[index];
|
||||
// Faster method of calculating r, g, b than red(), green(), blue()
|
||||
int r = (pixelColor >> 16) & 0xff;
|
||||
int g = (pixelColor >> 8) & 0xff;
|
||||
int b = pixelColor & 0xff;
|
||||
|
||||
// Another option would be to properly calculate brightness as luminance:
|
||||
// luminance = 0.3*red + 0.59*green + 0.11*blue
|
||||
// Or you could instead red + green + blue, and make the the values[] array
|
||||
// 256*3 elements long instead of just 256.
|
||||
int pixelBright = max(r, g, b);
|
||||
|
||||
// The 0.1 value is used to damp the changes so that letters flicker less
|
||||
float diff = pixelBright - bright[index];
|
||||
bright[index] += diff * 0.1;
|
||||
|
||||
fill(pixelColor);
|
||||
int num = int(bright[index]);
|
||||
text(letters[num], 0, 0);
|
||||
|
||||
// Move to the next pixel
|
||||
index++;
|
||||
|
||||
// Move over for next character
|
||||
translate(1.0 / fontSize, 0);
|
||||
}
|
||||
popMatrix();
|
||||
}
|
||||
popMatrix();
|
||||
|
||||
if (cheatScreen) {
|
||||
//image(video, 0, height - video.height);
|
||||
// set() is faster than image() when drawing untransformed images
|
||||
set(0, height - video.height, video);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Handle key presses:
|
||||
* 'c' toggles the cheat screen that shows the original image in the corner
|
||||
* 'g' grabs an image and saves the frame to a tiff image
|
||||
* 'f' and 'F' increase and decrease the font size
|
||||
*/
|
||||
public void keyPressed() {
|
||||
switch (key) {
|
||||
case 'g': saveFrame(); break;
|
||||
case 'c': cheatScreen = !cheatScreen; break;
|
||||
case 'f': fontSize *= 1.1; break;
|
||||
case 'F': fontSize *= 0.9; break;
|
||||
}
|
||||
}
|
||||
Binary file not shown.
@@ -0,0 +1,69 @@
|
||||
/**
|
||||
* Background Subtraction
|
||||
* by Golan Levin.
|
||||
*
|
||||
* Detect the presence of people and objects in the frame using a simple
|
||||
* background-subtraction technique. To initialize the background, press a key.
|
||||
*/
|
||||
|
||||
|
||||
import processing.video.*;
|
||||
|
||||
int numPixels;
|
||||
int[] backgroundPixels;
|
||||
Capture video;
|
||||
|
||||
void setup() {
|
||||
// Change size to 320 x 240 if too slow at 640 x 480
|
||||
size(640, 480, P2D);
|
||||
|
||||
video = new Capture(this, width, height, 24);
|
||||
numPixels = video.width * video.height;
|
||||
// Create array to store the background image
|
||||
backgroundPixels = new int[numPixels];
|
||||
// Make the pixels[] array available for direct manipulation
|
||||
loadPixels();
|
||||
}
|
||||
|
||||
void draw() {
|
||||
if (video.available()) {
|
||||
video.read(); // Read a new video frame
|
||||
video.loadPixels(); // Make the pixels of video available
|
||||
// Difference between the current frame and the stored background
|
||||
int presenceSum = 0;
|
||||
for (int i = 0; i < numPixels; i++) { // For each pixel in the video frame...
|
||||
// Fetch the current color in that location, and also the color
|
||||
// of the background in that spot
|
||||
color currColor = video.pixels[i];
|
||||
color bkgdColor = backgroundPixels[i];
|
||||
// Extract the red, green, and blue components of the current pixel’s color
|
||||
int currR = (currColor >> 16) & 0xFF;
|
||||
int currG = (currColor >> 8) & 0xFF;
|
||||
int currB = currColor & 0xFF;
|
||||
// Extract the red, green, and blue components of the background pixel’s color
|
||||
int bkgdR = (bkgdColor >> 16) & 0xFF;
|
||||
int bkgdG = (bkgdColor >> 8) & 0xFF;
|
||||
int bkgdB = bkgdColor & 0xFF;
|
||||
// Compute the difference of the red, green, and blue values
|
||||
int diffR = abs(currR - bkgdR);
|
||||
int diffG = abs(currG - bkgdG);
|
||||
int diffB = abs(currB - bkgdB);
|
||||
// Add these differences to the running tally
|
||||
presenceSum += diffR + diffG + diffB;
|
||||
// Render the difference image to the screen
|
||||
//pixels[i] = color(diffR, diffG, diffB);
|
||||
// The following line does the same thing much faster, but is more technical
|
||||
pixels[i] = 0xFF000000 | (diffR << 16) | (diffG << 8) | diffB;
|
||||
}
|
||||
updatePixels(); // Notify that the pixels[] array has changed
|
||||
println(presenceSum); // Print out the total amount of movement
|
||||
}
|
||||
}
|
||||
|
||||
// When a key is pressed, capture the background image into the backgroundPixels
|
||||
// buffer, by copying each of the current frame’s pixels into it.
|
||||
void keyPressed() {
|
||||
video.loadPixels();
|
||||
arraycopy(video.pixels, backgroundPixels);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
/**
|
||||
* Brightness Thresholding
|
||||
* by Golan Levin.
|
||||
*
|
||||
* Determines whether a test location (such as the cursor) is contained within
|
||||
* the silhouette of a dark object.
|
||||
*/
|
||||
|
||||
|
||||
import processing.video.*;
|
||||
|
||||
color black = color(0);
|
||||
color white = color(255);
|
||||
int numPixels;
|
||||
Capture video;
|
||||
|
||||
void setup() {
|
||||
size(640, 480); // Change size to 320 x 240 if too slow at 640 x 480
|
||||
strokeWeight(5);
|
||||
// Uses the default video input, see the reference if this causes an error
|
||||
video = new Capture(this, width, height, 24);
|
||||
numPixels = video.width * video.height;
|
||||
noCursor();
|
||||
smooth();
|
||||
}
|
||||
|
||||
void draw() {
|
||||
if (video.available()) {
|
||||
video.read();
|
||||
video.loadPixels();
|
||||
int threshold = 127; // Set the threshold value
|
||||
float pixelBrightness; // Declare variable to store a pixel's color
|
||||
// Turn each pixel in the video frame black or white depending on its brightness
|
||||
loadPixels();
|
||||
for (int i = 0; i < numPixels; i++) {
|
||||
pixelBrightness = brightness(video.pixels[i]);
|
||||
if (pixelBrightness > threshold) { // If the pixel is brighter than the
|
||||
pixels[i] = white; // threshold value, make it white
|
||||
}
|
||||
else { // Otherwise,
|
||||
pixels[i] = black; // make it black
|
||||
}
|
||||
}
|
||||
updatePixels();
|
||||
// Test a location to see where it is contained. Fetch the pixel at the test
|
||||
// location (the cursor), and compute its brightness
|
||||
int testValue = get(mouseX, mouseY);
|
||||
float testBrightness = brightness(testValue);
|
||||
if (testBrightness > threshold) { // If the test location is brighter than
|
||||
fill(black); // the threshold set the fill to black
|
||||
}
|
||||
else { // Otherwise,
|
||||
fill(white); // set the fill to white
|
||||
}
|
||||
ellipse(mouseX, mouseY, 20, 20);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
/**
|
||||
* Brightness Tracking
|
||||
* by Golan Levin.
|
||||
*
|
||||
* Tracks the brightest pixel in a live video signal.
|
||||
*/
|
||||
|
||||
|
||||
import processing.video.*;
|
||||
|
||||
Capture video;
|
||||
|
||||
void setup() {
|
||||
size(640, 480); // Change size to 320 x 240 if too slow at 640 x 480
|
||||
// Uses the default video input, see the reference if this causes an error
|
||||
video = new Capture(this, width, height, 30);
|
||||
noStroke();
|
||||
smooth();
|
||||
}
|
||||
|
||||
void draw() {
|
||||
if (video.available()) {
|
||||
video.read();
|
||||
image(video, 0, 0, width, height); // Draw the webcam video onto the screen
|
||||
int brightestX = 0; // X-coordinate of the brightest video pixel
|
||||
int brightestY = 0; // Y-coordinate of the brightest video pixel
|
||||
float brightestValue = 0; // Brightness of the brightest video pixel
|
||||
// Search for the brightest pixel: For each row of pixels in the video image and
|
||||
// for each pixel in the yth row, compute each pixel's index in the video
|
||||
video.loadPixels();
|
||||
int index = 0;
|
||||
for (int y = 0; y < video.height; y++) {
|
||||
for (int x = 0; x < video.width; x++) {
|
||||
// Get the color stored in the pixel
|
||||
int pixelValue = video.pixels[index];
|
||||
// Determine the brightness of the pixel
|
||||
float pixelBrightness = brightness(pixelValue);
|
||||
// If that value is brighter than any previous, then store the
|
||||
// brightness of that pixel, as well as its (x,y) location
|
||||
if (pixelBrightness > brightestValue) {
|
||||
brightestValue = pixelBrightness;
|
||||
brightestY = y;
|
||||
brightestX = x;
|
||||
}
|
||||
index++;
|
||||
}
|
||||
}
|
||||
// Draw a large, yellow circle at the brightest pixel
|
||||
fill(255, 204, 0, 128);
|
||||
ellipse(brightestX, brightestY, 200, 200);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,145 @@
|
||||
/**
|
||||
* Color Sorting
|
||||
* by Ben Fry.
|
||||
*
|
||||
* Example that sorts all colors from the incoming video
|
||||
* and arranges them into vertical bars.
|
||||
*/
|
||||
|
||||
|
||||
import processing.video.*;
|
||||
|
||||
Capture video;
|
||||
boolean cheatScreen;
|
||||
|
||||
Tuple[] captureColors;
|
||||
Tuple[] drawColors;
|
||||
int[] bright;
|
||||
|
||||
// How many pixels to skip in either direction
|
||||
int increment = 5;
|
||||
|
||||
|
||||
void setup() {
|
||||
size(800, 600, P3D);
|
||||
|
||||
noCursor();
|
||||
// Uses the default video input, see the reference if this causes an error
|
||||
video = new Capture(this, 80, 60, 15);
|
||||
|
||||
int count = (video.width * video.height) / (increment * increment);
|
||||
bright = new int[count];
|
||||
captureColors = new Tuple[count];
|
||||
drawColors = new Tuple[count];
|
||||
for (int i = 0; i < count; i++) {
|
||||
captureColors[i] = new Tuple();
|
||||
drawColors[i] = new Tuple(0.5, 0.5, 0.5);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void draw() {
|
||||
if (video.available()) {
|
||||
video.read();
|
||||
|
||||
background(0);
|
||||
noStroke();
|
||||
|
||||
int index = 0;
|
||||
for (int j = 0; j < video.height; j += increment) {
|
||||
for (int i = 0; i < video.width; i += increment) {
|
||||
int pixelColor = video.pixels[j*video.width + i];
|
||||
|
||||
int r = (pixelColor >> 16) & 0xff;
|
||||
int g = (pixelColor >> 8) & 0xff;
|
||||
int b = pixelColor & 0xff;
|
||||
|
||||
// Technically would be sqrt of the following, but no need to do
|
||||
// sqrt before comparing the elements since we're only ordering
|
||||
bright[index] = r*r + g*g + b*b;
|
||||
captureColors[index].set(r, g, b);
|
||||
|
||||
index++;
|
||||
}
|
||||
}
|
||||
sort(index, bright, captureColors);
|
||||
|
||||
beginShape(QUAD_STRIP);
|
||||
for (int i = 0; i < index; i++) {
|
||||
drawColors[i].target(captureColors[i], 0.1);
|
||||
drawColors[i].phil();
|
||||
|
||||
float x = map(i, 0, index, 0, width);
|
||||
vertex(x, 0);
|
||||
vertex(x, height);
|
||||
}
|
||||
endShape();
|
||||
|
||||
if (cheatScreen) {
|
||||
//image(video, 0, height - video.height);
|
||||
// Faster method of displaying pixels array on screen
|
||||
set(0, height - video.height, video);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void keyPressed() {
|
||||
if (key == 'g') {
|
||||
saveFrame();
|
||||
}
|
||||
else if (key == 'c') {
|
||||
cheatScreen = !cheatScreen;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Functions to handle sorting the color data
|
||||
|
||||
|
||||
void sort(int length, int[] a, Tuple[] stuff) {
|
||||
sortSub(a, stuff, 0, length - 1);
|
||||
}
|
||||
|
||||
|
||||
void sortSwap(int[] a, Tuple[] stuff, int i, int j) {
|
||||
int T = a[i];
|
||||
a[i] = a[j];
|
||||
a[j] = T;
|
||||
|
||||
Tuple v = stuff[i];
|
||||
stuff[i] = stuff[j];
|
||||
stuff[j] = v;
|
||||
}
|
||||
|
||||
|
||||
void sortSub(int[] a, Tuple[] stuff, int lo0, int hi0) {
|
||||
int lo = lo0;
|
||||
int hi = hi0;
|
||||
int mid;
|
||||
|
||||
if (hi0 > lo0) {
|
||||
mid = a[(lo0 + hi0) / 2];
|
||||
|
||||
while (lo <= hi) {
|
||||
while ((lo < hi0) && (a[lo] < mid)) {
|
||||
++lo;
|
||||
}
|
||||
while ((hi > lo0) && (a[hi] > mid)) {
|
||||
--hi;
|
||||
}
|
||||
if (lo <= hi) {
|
||||
sortSwap(a, stuff, lo, hi);
|
||||
++lo;
|
||||
--hi;
|
||||
}
|
||||
}
|
||||
|
||||
if (lo0 < hi)
|
||||
sortSub(a, stuff, lo0, hi);
|
||||
|
||||
if (lo < hi0)
|
||||
sortSub(a, stuff, lo, hi0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
// Simple vector class that holds an x,y,z position.
|
||||
|
||||
class Tuple {
|
||||
float x, y, z;
|
||||
|
||||
Tuple() { }
|
||||
|
||||
Tuple(float x, float y, float z) {
|
||||
set(x, y, z);
|
||||
}
|
||||
|
||||
void set(float x, float y, float z) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
}
|
||||
|
||||
void target(Tuple another, float amount) {
|
||||
float amount1 = 1.0 - amount;
|
||||
x = x*amount1 + another.x*amount;
|
||||
y = y*amount1 + another.y*amount;
|
||||
z = z*amount1 + another.z*amount;
|
||||
}
|
||||
|
||||
void phil() {
|
||||
fill(x, y, z);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
/**
|
||||
* Frame Differencing
|
||||
* by Golan Levin.
|
||||
*
|
||||
* Quantify the amount of movement in the video frame using frame-differencing.
|
||||
*/
|
||||
|
||||
|
||||
import processing.video.*;
|
||||
|
||||
int numPixels;
|
||||
int[] previousFrame;
|
||||
Capture video;
|
||||
|
||||
void setup() {
|
||||
size(640, 480); // Change size to 320 x 240 if too slow at 640 x 480
|
||||
// Uses the default video input, see the reference if this causes an error
|
||||
video = new Capture(this, width, height, 24);
|
||||
numPixels = video.width * video.height;
|
||||
// Create an array to store the previously captured frame
|
||||
previousFrame = new int[numPixels];
|
||||
loadPixels();
|
||||
}
|
||||
|
||||
void draw() {
|
||||
if (video.available()) {
|
||||
// When using video to manipulate the screen, use video.available() and
|
||||
// video.read() inside the draw() method so that it's safe to draw to the screen
|
||||
video.read(); // Read the new frame from the camera
|
||||
video.loadPixels(); // Make its pixels[] array available
|
||||
|
||||
int movementSum = 0; // Amount of movement in the frame
|
||||
for (int i = 0; i < numPixels; i++) { // For each pixel in the video frame...
|
||||
color currColor = video.pixels[i];
|
||||
color prevColor = previousFrame[i];
|
||||
// Extract the red, green, and blue components from current pixel
|
||||
int currR = (currColor >> 16) & 0xFF; // Like red(), but faster
|
||||
int currG = (currColor >> 8) & 0xFF;
|
||||
int currB = currColor & 0xFF;
|
||||
// Extract red, green, and blue components from previous pixel
|
||||
int prevR = (prevColor >> 16) & 0xFF;
|
||||
int prevG = (prevColor >> 8) & 0xFF;
|
||||
int prevB = prevColor & 0xFF;
|
||||
// Compute the difference of the red, green, and blue values
|
||||
int diffR = abs(currR - prevR);
|
||||
int diffG = abs(currG - prevG);
|
||||
int diffB = abs(currB - prevB);
|
||||
// Add these differences to the running tally
|
||||
movementSum += diffR + diffG + diffB;
|
||||
// Render the difference image to the screen
|
||||
pixels[i] = color(diffR, diffG, diffB);
|
||||
// The following line is much faster, but more confusing to read
|
||||
//pixels[i] = 0xff000000 | (diffR << 16) | (diffG << 8) | diffB;
|
||||
// Save the current color into the 'previous' buffer
|
||||
previousFrame[i] = currColor;
|
||||
}
|
||||
// To prevent flicker from frames that are all black (no movement),
|
||||
// only update the screen if the image has changed.
|
||||
if (movementSum > 0) {
|
||||
updatePixels();
|
||||
println(movementSum); // Print the total amount of movement to the console
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
/**
|
||||
* Framingham
|
||||
* by Ben Fry.
|
||||
*
|
||||
* Show subsequent frames from video input as a grid. Also fun with movie files.
|
||||
*/
|
||||
|
||||
|
||||
import processing.video.*;
|
||||
|
||||
Capture video;
|
||||
int column;
|
||||
int columnCount;
|
||||
int lastRow;
|
||||
|
||||
// Buffer used to move all the pixels up
|
||||
int[] scoot;
|
||||
|
||||
|
||||
void setup() {
|
||||
size(640, 480, P2D);
|
||||
|
||||
// Uses the default video input, see the reference if this causes an error
|
||||
video = new Capture(this, 32, 24);
|
||||
// Also try with other video sizes
|
||||
|
||||
column = 0;
|
||||
columnCount = width / video.width;
|
||||
int rowCount = height / video.height;
|
||||
lastRow = rowCount - 1;
|
||||
|
||||
scoot = new int[lastRow*video.height * width];
|
||||
background(0);
|
||||
}
|
||||
|
||||
|
||||
void draw() {
|
||||
// By using video.available, only the frame rate need be set inside setup()
|
||||
if (video.available()) {
|
||||
video.read();
|
||||
set(video.width*column, video.height*lastRow, video);
|
||||
column++;
|
||||
if (column == columnCount) {
|
||||
loadPixels();
|
||||
|
||||
// Scoot everybody up one row
|
||||
arraycopy(pixels, video.height*width, scoot, 0, scoot.length);
|
||||
arraycopy(scoot, 0, pixels, 0, scoot.length);
|
||||
|
||||
// Set the moved row to black
|
||||
for (int i = scoot.length; i < width*height; i++) {
|
||||
pixels[i] = #000000;
|
||||
}
|
||||
column = 0;
|
||||
updatePixels();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
/**
|
||||
* Getting Started with Capture.
|
||||
*
|
||||
* Reading and displaying an image from an attached Capture device.
|
||||
*/
|
||||
|
||||
import processing.video.*;
|
||||
|
||||
Capture cam;
|
||||
|
||||
void setup() {
|
||||
size(640, 480);
|
||||
|
||||
// If no device is specified, will just use the default.
|
||||
cam = new Capture(this, 320, 240);
|
||||
|
||||
// To use another device (i.e. if the default device causes an error),
|
||||
// list all available capture devices to the console to find your camera.
|
||||
//String[] devices = Capture.list();
|
||||
//println(devices);
|
||||
|
||||
// Change devices[0] to the proper index for your camera.
|
||||
//cam = new Capture(this, width, height, devices[0]);
|
||||
|
||||
// Opens the settings page for this capture device.
|
||||
//camera.settings();
|
||||
}
|
||||
|
||||
|
||||
void draw() {
|
||||
if (cam.available() == true) {
|
||||
cam.read();
|
||||
image(cam, 160, 100);
|
||||
// The following does the same, and is faster when just drawing the image
|
||||
// without any additional resizing, transformations, or tint.
|
||||
//set(160, 100, cam);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,206 @@
|
||||
/**
|
||||
* HSV Space
|
||||
* by Ben Fry.
|
||||
*
|
||||
* Arrange the pixels from live video into the HSV Color Cone.
|
||||
*/
|
||||
|
||||
|
||||
import processing.opengl.*;
|
||||
import processing.video.*;
|
||||
|
||||
Capture video;
|
||||
int count;
|
||||
boolean cheatScreen = true;
|
||||
|
||||
static final float BOX_SIZE = 0.75;
|
||||
static final float CONE_HEIGHT = 1.2;
|
||||
static final float MAX_RADIUS = 10;
|
||||
static final float ROT_INCREMENT = 3.0;
|
||||
static final float TRANS_INCREMENT = 1;
|
||||
static final float STEP_AMOUNT = 0.1;
|
||||
|
||||
Tuple[] farbe;
|
||||
Tuple[] trans;
|
||||
|
||||
float[] hsb = new float[3];
|
||||
|
||||
float leftRightAngle;
|
||||
float upDownAngle;
|
||||
float fwdBackTrans;
|
||||
float upDownTrans;
|
||||
float leftRightTrans;
|
||||
boolean motion;
|
||||
|
||||
boolean blobby = false;
|
||||
|
||||
|
||||
void setup() {
|
||||
size(640, 480, P3D);
|
||||
//size(screen.width, screen.height, OPENGL);
|
||||
|
||||
video = new Capture(this, 40, 30, 15);
|
||||
count = video.width * video.height;
|
||||
|
||||
sphereDetail(60);
|
||||
|
||||
upDownTrans = 0;
|
||||
leftRightTrans = 0;
|
||||
motion = false;
|
||||
|
||||
leftRightAngle = 101.501297;
|
||||
upDownAngle = -180.098694;
|
||||
fwdBackTrans = 14.800003;
|
||||
|
||||
farbe = new Tuple[count];
|
||||
trans = new Tuple[count];
|
||||
for (int i = 0; i < count; i++) {
|
||||
farbe[i] = new Tuple();
|
||||
trans[i] = new Tuple();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void draw() {
|
||||
background(0);
|
||||
|
||||
if (!blobby) lights();
|
||||
|
||||
pushMatrix();
|
||||
translate(width/2, height/2);
|
||||
scale(min(width, height) / 10.0);
|
||||
|
||||
translate(0, 0, -20 + fwdBackTrans);
|
||||
rotateY(radians(36 + leftRightAngle)); //, 0, 1, 0);
|
||||
rotateX(radians(-228 + upDownAngle)); //, 1, 0, 0);
|
||||
|
||||
if (blobby) {
|
||||
stroke(0.35, 0.35, 0.25, 0.15);
|
||||
wireCone(MAX_RADIUS, MAX_RADIUS * CONE_HEIGHT, 18, 18);
|
||||
}
|
||||
else {
|
||||
stroke(0.35, 0.35, 0.25, 0.25);
|
||||
wireCone(MAX_RADIUS, MAX_RADIUS * CONE_HEIGHT, 180, 18);
|
||||
}
|
||||
|
||||
noStroke();
|
||||
for (int i = 0; i < count; i++) {
|
||||
int pixelColor = video.pixels[i];
|
||||
int r = (pixelColor >> 16) & 0xff;
|
||||
int g = (pixelColor >> 8) & 0xff;
|
||||
int b = pixelColor & 0xff;
|
||||
Color.RGBtoHSB(r, g, b, hsb);
|
||||
|
||||
float radius = hsb[1] * hsb[2];
|
||||
float angle = hsb[0] * 360.0 * DEG_TO_RAD;
|
||||
float nx = MAX_RADIUS * radius * cos(angle);
|
||||
float ny = MAX_RADIUS * radius * sin(angle);
|
||||
float nz = hsb[2] * MAX_RADIUS * CONE_HEIGHT;
|
||||
|
||||
trans[i].set(trans[i].x - (trans[i].x - nx)*STEP_AMOUNT,
|
||||
trans[i].y - (trans[i].y - ny)*STEP_AMOUNT,
|
||||
trans[i].z - (trans[i].z - nz)*STEP_AMOUNT);
|
||||
|
||||
farbe[i].set(farbe[i].x - (farbe[i].x - r)*STEP_AMOUNT,
|
||||
farbe[i].y - (farbe[i].y - g)*STEP_AMOUNT,
|
||||
farbe[i].z - (farbe[i].z - b)*STEP_AMOUNT);
|
||||
|
||||
pushMatrix();
|
||||
farbe[i].phil();
|
||||
trans[i].tran();
|
||||
|
||||
rotate(radians(45), 1, 1, 0);
|
||||
if (blobby) {
|
||||
sphere(BOX_SIZE * 2); //, 20, 20);
|
||||
} else {
|
||||
box(BOX_SIZE);
|
||||
}
|
||||
|
||||
popMatrix();
|
||||
}
|
||||
popMatrix();
|
||||
|
||||
if (motion) {
|
||||
upDownAngle--;
|
||||
leftRightAngle--;
|
||||
}
|
||||
|
||||
if (cheatScreen) {
|
||||
image(video, 0, height - video.height);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void captureEvent(Capture c) {
|
||||
c.read();
|
||||
c.loadPixels();
|
||||
}
|
||||
|
||||
|
||||
void keyPressed() {
|
||||
switch (key) {
|
||||
case 'g':
|
||||
saveFrame();
|
||||
break;
|
||||
case 'c':
|
||||
cheatScreen = !cheatScreen;
|
||||
break;
|
||||
|
||||
case 'm':
|
||||
motion = !motion;
|
||||
break;
|
||||
case '=':
|
||||
fwdBackTrans += TRANS_INCREMENT;
|
||||
break;
|
||||
case '-':
|
||||
fwdBackTrans -= TRANS_INCREMENT;
|
||||
break;
|
||||
case 'b':
|
||||
blobby = !blobby;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void mouseDragged() {
|
||||
float dX, dY;
|
||||
|
||||
switch (mouseButton) {
|
||||
case LEFT: // left right up down
|
||||
dX = pmouseX - mouseX;
|
||||
dY = pmouseY - mouseY;
|
||||
leftRightAngle -= dX * 0.2;
|
||||
upDownAngle += dY * 0.4;
|
||||
break;
|
||||
|
||||
case CENTER:
|
||||
dX = pmouseX - mouseX;
|
||||
dY = pmouseY - mouseY;
|
||||
leftRightTrans -= TRANS_INCREMENT * dX;
|
||||
upDownTrans -= TRANS_INCREMENT * dY;
|
||||
break;
|
||||
|
||||
case RIGHT: // in and out
|
||||
dY = (float) (pmouseY - mouseY);
|
||||
fwdBackTrans -= TRANS_INCREMENT * dY;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void wireCone(float radius, float height, int stepX, int stepY) {
|
||||
int steps = 10;
|
||||
stroke(40);
|
||||
for (int i = 0; i < steps; i++) {
|
||||
float angle = map(i, 0, steps, 0, TWO_PI);
|
||||
float x = radius * cos(angle);
|
||||
float y = radius * sin(angle);
|
||||
line(x, y, height, 0, 0, 0);
|
||||
}
|
||||
noFill();
|
||||
pushMatrix();
|
||||
translate(0, 0, height);
|
||||
ellipseMode(CENTER_RADIUS);
|
||||
ellipse(0, 0, radius, radius);
|
||||
popMatrix();
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
// Simple vector class that holds an x,y,z position.
|
||||
|
||||
class Tuple {
|
||||
float x, y, z;
|
||||
|
||||
Tuple() { }
|
||||
|
||||
Tuple(float x, float y, float z) {
|
||||
set(x, y, z);
|
||||
}
|
||||
|
||||
void set(float x, float y, float z) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
}
|
||||
|
||||
void target(Tuple another, float amount) {
|
||||
float amount1 = 1.0 - amount;
|
||||
x = x*amount1 + another.x*amount;
|
||||
y = y*amount1 + another.y*amount;
|
||||
z = z*amount1 + another.z*amount;
|
||||
}
|
||||
|
||||
void phil() {
|
||||
fill(x, y, z);
|
||||
}
|
||||
|
||||
void tran() {
|
||||
translate(x, y, z);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
/**
|
||||
* Live Pocky
|
||||
* by Ben Fry.
|
||||
*
|
||||
* Unwrap each frame of live video into a single line of pixels.
|
||||
*/
|
||||
|
||||
import processing.video.*;
|
||||
|
||||
Capture video;
|
||||
int count;
|
||||
int writeRow;
|
||||
int maxRows;
|
||||
int topRow;
|
||||
int buffer[];
|
||||
|
||||
|
||||
void setup() {
|
||||
size(600, 400);
|
||||
|
||||
// Uses the default video input, see the reference if this causes an error
|
||||
video = new Capture(this, 30, 20);
|
||||
|
||||
maxRows = height * 2;
|
||||
buffer = new int[width * maxRows];
|
||||
writeRow = height - 1;
|
||||
topRow = 0;
|
||||
|
||||
//frameRate(10);
|
||||
background(0);
|
||||
loadPixels();
|
||||
}
|
||||
|
||||
|
||||
void draw() {
|
||||
for (int y = 0; y < height; y++) {
|
||||
int row = (topRow + y) % maxRows;
|
||||
arraycopy(buffer, row * width, g.pixels, y*width, width);
|
||||
}
|
||||
updatePixels();
|
||||
}
|
||||
|
||||
|
||||
void captureEvent(Capture c) {
|
||||
c.read();
|
||||
c.loadPixels();
|
||||
arraycopy(c.pixels, 0, buffer, writeRow * width, width);
|
||||
writeRow++;
|
||||
if (writeRow == maxRows) {
|
||||
writeRow = 0;
|
||||
}
|
||||
topRow++;
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
/**
|
||||
* Mirror
|
||||
* by Daniel Shiffman.
|
||||
*
|
||||
* Each pixel from the video source is drawn as a rectangle with rotation based on brightness.
|
||||
*/
|
||||
|
||||
|
||||
import processing.video.*;
|
||||
|
||||
// Size of each cell in the grid
|
||||
int cellSize = 20;
|
||||
// Number of columns and rows in our system
|
||||
int cols, rows;
|
||||
// Variable for capture device
|
||||
Capture video;
|
||||
|
||||
|
||||
void setup() {
|
||||
size(640, 480, P2D);
|
||||
frameRate(30);
|
||||
cols = width / cellSize;
|
||||
rows = height / cellSize;
|
||||
colorMode(RGB, 255, 255, 255, 100);
|
||||
|
||||
// Uses the default video input, see the reference if this causes an error
|
||||
video = new Capture(this, width, height, 12);
|
||||
|
||||
background(0);
|
||||
}
|
||||
|
||||
|
||||
void draw() {
|
||||
if (video.available()) {
|
||||
video.read();
|
||||
video.loadPixels();
|
||||
|
||||
// Not bothering to clear background
|
||||
// background(0);
|
||||
|
||||
// Begin loop for columns
|
||||
for (int i = 0; i < cols; i++) {
|
||||
// Begin loop for rows
|
||||
for (int j = 0; j < rows; j++) {
|
||||
|
||||
// Where are we, pixel-wise?
|
||||
int x = i*cellSize;
|
||||
int y = j*cellSize;
|
||||
int loc = (video.width - x - 1) + y*video.width; // Reversing x to mirror the image
|
||||
|
||||
float r = red(video.pixels[loc]);
|
||||
float g = green(video.pixels[loc]);
|
||||
float b = blue(video.pixels[loc]);
|
||||
// Make a new color with an alpha component
|
||||
color c = color(r, g, b, 75);
|
||||
|
||||
// Code for drawing a single rect
|
||||
// Using translate in order for rotation to work properly
|
||||
pushMatrix();
|
||||
translate(x+cellSize/2, y+cellSize/2);
|
||||
// Rotation formula based on brightness
|
||||
rotate((2 * PI * brightness(c) / 255.0));
|
||||
rectMode(CENTER);
|
||||
fill(c);
|
||||
noStroke();
|
||||
// Rects are larger than the cell for some overlap
|
||||
rect(0, 0, cellSize+6, cellSize+6);
|
||||
popMatrix();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
/**
|
||||
* Mirror 2
|
||||
* by Daniel Shiffman.
|
||||
*
|
||||
* Each pixel from the video source is drawn as a rectangle with size based on brightness.
|
||||
*/
|
||||
|
||||
import processing.video.*;
|
||||
|
||||
// Size of each cell in the grid
|
||||
int cellSize = 15;
|
||||
// Number of columns and rows in our system
|
||||
int cols, rows;
|
||||
// Variable for capture device
|
||||
Capture video;
|
||||
|
||||
|
||||
void setup() {
|
||||
size(630, 480, P2D);
|
||||
//set up columns and rows
|
||||
cols = width / cellSize;
|
||||
rows = height / cellSize;
|
||||
colorMode(RGB, 255, 255, 255, 100);
|
||||
rectMode(CENTER);
|
||||
|
||||
// Uses the default video input, see the reference if this causes an error
|
||||
video = new Capture(this, width, height, 15);
|
||||
|
||||
background(0);
|
||||
}
|
||||
|
||||
|
||||
void draw() {
|
||||
if (video.available()) {
|
||||
video.read();
|
||||
video.loadPixels();
|
||||
|
||||
background(0, 0, 255);
|
||||
|
||||
// Begin loop for columns
|
||||
for (int i = 0; i < cols;i++) {
|
||||
// Begin loop for rows
|
||||
for (int j = 0; j < rows;j++) {
|
||||
|
||||
// Where are we, pixel-wise?
|
||||
int x = i * cellSize;
|
||||
int y = j * cellSize;
|
||||
int loc = (video.width - x - 1) + y*video.width; // Reversing x to mirror the image
|
||||
|
||||
// Each rect is colored white with a size determined by brightness
|
||||
color c = video.pixels[loc];
|
||||
float sz = (brightness(c) / 255.0) * cellSize;
|
||||
fill(255);
|
||||
noStroke();
|
||||
rect(x + cellSize/2, y + cellSize/2, sz, sz);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
/**
|
||||
* Radial Pocky
|
||||
* by Ben Fry.
|
||||
*
|
||||
* Unwrap each frame of live video into a single line of pixels along a circle
|
||||
*/
|
||||
|
||||
|
||||
import processing.video.*;
|
||||
|
||||
Capture video;
|
||||
int videoCount;
|
||||
int currentAngle;
|
||||
int pixelCount;
|
||||
int angleCount = 200; // how many divisions
|
||||
|
||||
int radii[];
|
||||
int angles[];
|
||||
|
||||
void setup() {
|
||||
// size must be set to video.width*video.height*2 in both directions
|
||||
size(960, 540);
|
||||
|
||||
// Uses the default video input, see the reference if this causes an error
|
||||
video = new Capture(this, 24, 16);
|
||||
videoCount = video.width * video.height;
|
||||
|
||||
pixelCount = width*height;
|
||||
int centerX = width / 2;
|
||||
int centerY = height / 2;
|
||||
radii = new int[pixelCount];
|
||||
angles = new int[pixelCount];
|
||||
|
||||
int offset = 0;
|
||||
for (int y = 0; y < height; y++) {
|
||||
for (int x = 0; x < width; x++) {
|
||||
int dx = centerX - x;
|
||||
int dy = centerY - y;
|
||||
|
||||
float angle = atan2(dy, dx);
|
||||
if (angle < 0) angle += TWO_PI;
|
||||
angles[offset] = (int) (angleCount * (angle / TWO_PI));
|
||||
|
||||
int radius = (int) mag(dx, dy);
|
||||
if (radius >= videoCount) {
|
||||
radius = -1;
|
||||
angles[offset] = -1;
|
||||
}
|
||||
radii[offset] = radius;
|
||||
|
||||
offset++;
|
||||
}
|
||||
}
|
||||
background(0);
|
||||
}
|
||||
|
||||
|
||||
void draw() {
|
||||
if (video.available()) {
|
||||
video.read();
|
||||
video.loadPixels();
|
||||
|
||||
loadPixels();
|
||||
for (int i = 0; i < pixelCount; i++) {
|
||||
if (angles[i] == currentAngle) {
|
||||
pixels[i] = video.pixels[radii[i]];
|
||||
}
|
||||
}
|
||||
updatePixels();
|
||||
|
||||
currentAngle++;
|
||||
if (currentAngle == angleCount) currentAngle = 0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
/**
|
||||
* Simple Real-Time Slit-Scan Program.
|
||||
* By Golan Levin.
|
||||
*
|
||||
* This demonstration depends on the canvas height being equal
|
||||
* to the video capture height. If you would prefer otherwise,
|
||||
* consider using the image copy() function rather than the
|
||||
* direct pixel-accessing approach I have used here.
|
||||
*
|
||||
* Created December 2006.
|
||||
* Updated June 2007 by fry.
|
||||
*/
|
||||
import processing.video.*;
|
||||
|
||||
Capture video;
|
||||
|
||||
int videoSliceX;
|
||||
int drawPositionX;
|
||||
|
||||
|
||||
void setup() {
|
||||
size(600, 240, P2D);
|
||||
|
||||
// Uses the default video input, see the reference if this causes an error
|
||||
video = new Capture(this, 320, 240, 30);
|
||||
|
||||
videoSliceX = video.width / 2;
|
||||
drawPositionX = width - 1;
|
||||
background(0);
|
||||
}
|
||||
|
||||
|
||||
void draw() {
|
||||
if (video.available()) {
|
||||
video.read();
|
||||
video.loadPixels();
|
||||
|
||||
// Copy a column of pixels from the middle of the video
|
||||
// To a location moving slowly across the canvas.
|
||||
loadPixels();
|
||||
for (int y = 0; y < video.height; y++){
|
||||
int setPixelIndex = y*width + drawPositionX;
|
||||
int getPixelIndex = y*video.width + videoSliceX;
|
||||
pixels[setPixelIndex] = video.pixels[getPixelIndex];
|
||||
}
|
||||
updatePixels();
|
||||
|
||||
drawPositionX--;
|
||||
// Wrap the position back to the beginning if necessary.
|
||||
if (drawPositionX < 0) {
|
||||
drawPositionX = width - 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user