I am creating a snowflake simulation in Processing however i am not sure how to perform more than one transformation to an image as it seems you can only perform one.
class Snowflake{
float imgWidth;
float imgHeight;
PVector pos;
PVector vel;
final float firstXPos;
float a = 0.0;
float angularVel = 0.01;
float x;
float amp;
float period;
Snowflake(float xWidth, float yHeight){
imgWidth = xWidth;
imgHeight = yHeight;
pos = new PVector(random(width), 0);
vel = new PVector(0,1);
firstXPos = this.pos.x;
}
void descend(){
amp = 75;
period = 200;
x = amp * sin((frameCount/period) * TWO_PI);
This is where i am trying to rotate the image and oscillate it back and forth.
pushMatrix();
translate(firstXPos,this.pos.y);
image(snowflakeImg, x, this.pos.y, imgWidth, imgHeight);
popMatrix();
//creating a line for oscillation reference
//translate(firstXPos, this.pos.y);
//stroke(255);
//line(0,0,x,y);
}
void update(){
pos.add(vel);
a += angularVel;
}
}
Here is my sketch, just loading in assets and setting up the sketch
PImage snowflakeImg;
Snowflake snowFlake;
void setup() {
imageMode(CENTER);
snowflakeImg = loadImage("snowflake.png", "png");
snowFlake = new Snowflake(25, 25);
size(800,600);
}
void draw(){
background(0);
snowFlake.descend();
snowFlake.update();
}
You're creating a single Snowflake
instance. You need to create more, then update each one.
In your case you should initialise an array of Snowflake
objects first (at the top where you declare your variables). Here's an example allocating an array of 99 Snowflake
objects:
int numSnowflakes = 99;
Snowflake[] snowflakes = new Snowflake[numSnowflakes];
Then in setup()
you can initialise each array element as a new Snowflake
instance:
for(int i = 0 ; i < numSnowflakes; i++){
snowflakes[i] = new Snowflake(25, 25);
}
Finally in draw()
you can loop through each object so it can descend()
and update()
:
for(int i = 0 ; i < numSnowflakes; i++){
snowflakes[i].descend();
snowflakes[i].update();
}
If you're not familiar with arrays in Processing yet I can recommend the following resources:
Once you've got the hang of this you should look into ArrayList as well.
Update To address your comment, you can use push/pop matrix calls to further isolate coordinate systems and rotate the image around it's centre:
x = amp * sin((frameCount/period) * TWO_PI);
// enter local coordinate system #1
pushMatrix();
// move to flake position
translate(firstXPos,this.pos.y);
// enter local coordinate system #2
pushMatrix();
// move to updated (oscillated) x position
translate(x, this.pos.y);
// rotated from translated position (imageMode(CENTER) helps rotate around centre)
rotate(frameCount * 0.1);
// render the image at it's final transformation
image(snowflakeImg,0,0, imgWidth, imgHeight);
popMatrix();
popMatrix();
For more info check out the Coordinate Systems Processing tutorial .
For reference here's a test sketch I've used with each flake at random width:
PImage snowflakeImg;
Snowflake snowFlake;
int numSnowflakes = 99;
Snowflake[] snowflakes = new Snowflake[numSnowflakes];
void setup() {
imageMode(CENTER);
//snowflakeImg = loadImage("snowflake.png", "png");
PGraphics snowflakeG = createGraphics(25,25);
snowflakeG.beginDraw();
snowflakeG.rectMode(CENTER);
snowflakeG.rect(0,0,25,25);
snowflakeG.endDraw();
snowflakeImg = snowflakeG;
for(int i = 0 ; i < numSnowflakes; i++){
snowflakes[i] = new Snowflake(25, 25);
}
size(800,600);
}
void draw(){
background(0);
for(int i = 0 ; i < numSnowflakes; i++){
snowflakes[i].descend();
snowflakes[i].update();
}
}
class Snowflake{
float imgWidth;
float imgHeight;
PVector pos;
PVector vel;
final float firstXPos;
float a = 0.0;
float angularVel = 0.01;
float x;
float amp;
float period;
Snowflake(float xWidth, float yHeight){
imgWidth = xWidth;
imgHeight = yHeight;
pos = new PVector(random(width), 0);
vel = new PVector(0,1);
firstXPos = this.pos.x;
}
void descend(){
amp = 75;
period = 200;
x = amp * sin((frameCount/period) * TWO_PI);
// enter local coordinate system #1
pushMatrix();
// move to flake position
translate(firstXPos,this.pos.y);
// enter local coordinate system #2
pushMatrix();
// move to updated (oscillated) x position
translate(x, this.pos.y);
// rotated from translated position (imageMode(CENTER) helps rotate around centre)
rotate(frameCount * 0.1);
// render the image at it's final transformation
image(snowflakeImg,0,0, imgWidth, imgHeight);
popMatrix();
popMatrix();
//creating a line for oscillation reference
//translate(firstXPos, this.pos.y);
//stroke(255);
//line(0,0,x,y);
}
void update(){
pos.add(vel);
a += angularVel;
}
}
You should also check out Daniel Shiffman's Snowfall coding challenge . Even though it's p5.js the same logic can be easily applied in Processing.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.