Wave w;
int noW = 5; // No. of Waves on either side of half period
int totalwaves = (noW*2)-1;
float freq = 1; // How many repetitions
float period;
boolean inverse;
void setup() {
size(800, 800);
background(0);
stroke(255);
smooth();
noFill();
//noLoop();
period = height/freq ;
w = new Wave();
}
void draw() {
background(0);
translate(width/2, 0);
w.calcWaves();
w.display();
w.resetWave();
}
class Wave {
float halfper;
float minperiod1, maxperiod1;
float stdamp;
float spacing;
float angV;
// Height,period & angular frequency of wave in half period
float amp1, amp2;
float per1, per2;
float dx1, dx2;
ArrayList<PVector[]> waves;
float[] wavesPer;
Wave() {
halfper = period/2;
// Range of period to animate
minperiod1 = halfper - halfper*0.9;
maxperiod1 = halfper + halfper*0.9;
stdamp = (halfper)*0.35;
spacing = minperiod1/(noW-1);
angV = spacing * 0.08;
wavesPer = new float[totalwaves];
resetWave();
InitPer();
}
void resetWave() {
waves = new ArrayList<PVector[]>();
}
void InitPer() {
for (int i=0; i<totalwaves; i++) {
per1 = minperiod1 + i*spacing;
wavesPer[i] = per1;
}
}
void calcPer(int i) {
per1 = wavesPer[i]+angV;
if (per1<=minperiod1 || per1>=maxperiod1) {
angV = -angV;
}
wavesPer[i] = per1;
per2 = period - per1;
dx1 = PI/(per1);
dx2 = PI/(per2);
amp1 = per1/(halfper) * stdamp;
amp2 = per2/(halfper) * stdamp;
}
void calcWaves() {
for (int i=0; i<totalwaves; i++) {
calcPer(i);
float theta = 0;
float x = 0;
PVector[] tempV = new PVector[int(period+1)];
for (int y=0; y<=period; y++) {
if (y<=per1) {
x = amp1 * pow(sin(theta), 1);
theta+=dx1;
} else {
x = amp2 * pow(sin(theta), 1);
theta+=dx2;
}
tempV[y] = new PVector(x, y);
}
waves.add(tempV);
tempV = new PVector[int(period+1)]; // reset temp array
}
}
void display() {
for (int k=0; k<freq; k++) {
for (int i=0; i<totalwaves; i++) {
PVector[] tempV = waves.get(i);
pushMatrix();
translate(0, k*(period));
beginShape();
for (int j=0; j<tempV.length; j++) {
vertex(tempV[j].x, tempV[j].y);
}
endShape();
popMatrix();
}
}
}
}
This code implements sine wave with varying periods called per1 & per2 in the code. When wave is animating upwards, the amplitudes of per1 & per2 don’t seem to match up creating jagged lines whereas it plays out smoothly while animating downwards.
I can’t seem to figure the issue.
@glv Thanks for the reply. I realized that the jagged lines are appearing not because of the code error but because of the way processing frames are animated.
From the code , as period1 gets too small the angular frequency dx = PI/ period gets too large causing long jumps in the wave resulting in mismatch of period1 wave and period2 wave.
As a cheat way of doing it, I am drawing the small period1 wave from bottom to top which solves the problem.
Wave w;
int noW = 7; // No. of Waves on either side of half period including half period
int totalwaves = (noW*2)-1;
float freq = 2; // How many repetitions
float period;
void setup() {
size(1000, 1000);
background(0);
stroke(255);
smooth();
noFill();
//noLoop();
period = height/freq ;
w = new Wave();
}
void draw() {
background(0);
pushMatrix();
translate(width/2,0);
//line(0,0,0,height);
w.calcWaves();
w.display();
w.resetWaves();
popMatrix();
}
class Wave {
float halfper;
float minperiod1, maxperiod1;
float stdamp;
float spacing;
float angV;
float range = 1;
// Height,period & angular frequency of wave in half period
float amp1, amp2;
float per1, per2;
float dx1, dx2;
ArrayList<PVector[]> waves;
float[] wavesPer;
float angle = 0.0;
float xoff = 0.0;
Wave() {
halfper = period/2;
// Range of period to animate
minperiod1 = halfper - halfper*range;
maxperiod1 = halfper + halfper*range;
stdamp = (halfper)*0.4;
spacing = ((halfper - minperiod1)*0.45)/(noW-1);
angV = spacing * 0.08;
wavesPer = new float[totalwaves];
resetWaves();
InitPer();
}
void resetWaves() {
waves = new ArrayList<PVector[]>();
}
void InitPer() {
for (int i=0; i<totalwaves; i++) {
per1 = minperiod1 + i*spacing;
wavesPer[i] = per1;
}
}
void calcPer(int i) {
if (i==0) {
per1 = wavesPer[i] + angV + (0.013/freq); // adding more velocity to first wave as it lags over a period of time.
} else {
per1 = wavesPer[i]+angV;
}
if (per1<=minperiod1 || per1>=maxperiod1) {
angV = -angV;
}
wavesPer[i] = per1;
per2 = period - per1;
//println("wavesPer["+i+"]: " +per1);
//println("wavesPer["+i+"]: " +per2);
dx1 = PI/(per1);
dx2 = PI/(per2);
//println("dx1: "+dx1, i);
//println("dx2: " +dx2, i);
amp1 = per1/(halfper) * stdamp;
amp2 = per2/(halfper) * stdamp;
//println("["+i+"]: " +amp1);
//println("["+i+"]: " +amp2);
}
void calcWaves() {
angle += 0.004;
for (int i=0; i<totalwaves; i++) {
calcPer(i);
float theta = 0.0;
float x = 0.0;
PVector[] tempV = new PVector[int(period+1)];
if (per1<=halfper) {
for (float y = period; y>=0; y--) {
if (y<=per1) {
x = amp1 * pow(sin(theta), 1);
theta+=dx1;
} else {
x = amp2 * pow(sin(theta), 1);
theta+=dx2;
}
tempV[int(y)] = new PVector(-x, y);
}
} else {
for (int y=0; y<=period; y++) {
if (y<=per1) {
x = amp1 * pow(sin(theta), 1);
theta+=dx1;
} else {
x = amp2 * pow(sin(theta), 1);
theta+=dx2;
}
tempV[y] = new PVector(x, y);
}
}
waves.add(tempV);
tempV = new PVector[int(period+1)]; // reset temp array
}
}
void display() {
for (int k=0; k<freq; k++) {
for (int i=0; i<totalwaves; i++) {
PVector[] tempV = waves.get(i);
pushMatrix();
translate(0, k*(period));
beginShape();
for (int j=0; j<tempV.length; j++) {
vertex(tempV[j].x, tempV[j].y);
}
endShape();
popMatrix();
}
}
}
}