问题
I'm experimenting with the following Code:
//3D Spectrogram with Microphone Input
//Modified by kylejanzen 2011 - https://kylejanzen.wordpress.com
//Based on script written by John Locke 2011 - http://gracefulspoon.com
//Output .DXF file at any time by pressing "r" on the keyboard
import processing.dxf.*;
import ddf.minim.analysis.*;
import ddf.minim.*;
import peasy.*;
PeasyCam cam;
FFT fftLin;
FFT fftLog;
Waveform audio3D;
Minim minim;
AudioInput microphone;
boolean record;
PFont font;
float camzoom;
float maxX = 0;float maxY = 0;float maxZ = 0;
float minX = 0;float minY = 0;float minZ = 0;
void setup()
{
size(1250,750,P3D); //screen proportions
noStroke();
minim = new Minim(this);
microphone = minim.getLineIn(Minim.STEREO, 4096); //repeat the song
cam = new PeasyCam(this, 0, 0, 0, 50);
cam.setMinimumDistance(50);
cam.setMaximumDistance(500);
background(255);
fftLog = new FFT(microphone.bufferSize(),microphone.sampleRate());
fftLog.logAverages(1,2); //adjust numbers to adjust spacing;
float w = float (width/fftLog.avgSize());
print(fftLog.avgSize());
float x = w;
float y = 0;
float z = 10;
float radius = 100;
audio3D = new Waveform(x,y,z,radius);
}
void draw()
{
background(0);
// ambientLight(102,102,102);
if (frameCount>0)
{
for(int i = 0; i < fftLog.avgSize(); i++){
float zoom = 1;
float jitter = (fftLog.getAvg(i)*2);
//println(jitter);
PVector foc = new PVector(audio3D.x+jitter, audio3D.y+jitter, 0);
PVector cam = new PVector(zoom, zoom, -zoom);
// camera(foc.x+cam.x+50,foc.y+cam.y+50,foc.z+cam.z+100,foc.x+30,foc.y+30,foc.z+100,0,0,1);
}
}
//play the song
fftLog.forward(microphone.mix);
audio3D.update();
// audio3D.textdraw();
if(record)
{
beginRaw(DXF, "output.dxf");
}
audio3D.plotTrace();
if(record)
{
endRaw();
record = false;
println("It's Done Bitches! Find your DXF!");
}
}
void stop()
{
// always close Minim audio classes when you finish with them
microphone.close();
// always stop Minim before exiting
minim.stop();
super.stop();
}
class Waveform
{
float x,y,z;
float radius;
PVector[] pts = new PVector[fftLog.avgSize()];
PVector[] trace = new PVector[0];
Waveform(float incomingX, float incomingY, float incomingZ, float incomingRadius)
{
x = incomingX;
y = incomingY;
z = incomingZ;
radius = incomingRadius;
}
void update()
{
plot();
}
void plot()
{
for(int i = 1; i < fftLog.avgSize(); i++)
{
int w = int(width/fftLog.avgSize());
x = i*w;
y = frameCount*5; // CHANGE THE SPEED
z = height/4-fftLog.getAvg(i)*4; //change multiplier to reduces height default '10'
stroke(0);
point(x, y, z);
pts[i] = new PVector(x, y, z);
//increase size of array trace by length+1
trace = (PVector[]) expand(trace, trace.length+1);
//always get the next to last
trace[trace.length-1] = new PVector(pts[i].x, pts[i].y, pts[i].z);
}
}
/* void textdraw()
{
for(int i =0; i<fftLog.avgSize(); i++){
pushMatrix();
translate(pts[i].x, pts[i].y, pts[i].z);
rotateY(PI/2);
rotateZ(PI/2);
fill(255,255);
text(round(fftLog.getAvg(i)*100),0,0,0);
popMatrix();
}
} */
void plotTrace()
{
stroke(255,100);
int inc = fftLog.avgSize();
for(int i=1; i<trace.length-inc; i++)
{
if(i%inc != 0)
{
beginShape(POINTS);
strokeWeight(2);
fill(0, 0, 0, 100);
vertex(trace[i].x, trace[i].y, trace[i].z);
vertex(trace[i-1].x, trace[i-1].y, trace[i-1].z);
vertex(trace[i+inc].x, trace[i+inc].y, trace[i+inc].z);
vertex(trace[i-1+inc].x, trace[i-1+inc].y, trace[i-1+inc].z);
endShape(CLOSE);
}
}
}
}
void keyPressed()
{
if (key == 'r') record = true;
}
What I currently try to achieve is to reduce the count of generated points on the (moving) (y-)axis. It seems that every frame, generates a point. My question therefore is fairly simple: How can I let it draw only e.g. every 5 frames? I just can't find the value, which manages that.
Thanks a lot.
回答1:
You've got three options:
Option 1: Call the frameRate() function to reduce the number of frames that get drawn per second.
void setup(){
size(500, 500);
frameRate(5);
}
void draw(){
background(0);
ellipse(mouseX, mouseY, 20, 20);
}
Option 2: Use the frameCount variable and the modulus % operator to determine when X
frames have elapsed.
void setup(){
size(500, 500);
}
void draw(){
if(frameCount % 5 == 0){
background(0);
ellipse(mouseX, mouseY, 20, 20);
}
}
Option 3: You could create your own variable that stores the number of frames that have elapsed.
int framesElapsed = 0;
void setup(){
size(500, 500);
}
void draw(){
framesElapsed++;
if(framesElapsed == 5){
background(0);
ellipse(mouseX, mouseY, 20, 20);
framesElapsed = 0;
}
}
Note that for the simple case, this is just doing what the modulus operator in option 2 is doing. In that case, modulus is probably better. But this becomes useful if you want, for example, different things to happen at different times. In that case you'd have multiple variables keeping track of the "lifetime" of whatever you want to track.
But for your example, option 2 is probably the best option.
来源:https://stackoverflow.com/questions/36505178/processing-how-can-i-draw-only-every-x-frames