如何在 Processing 中旋转和摆动同一个物体

How do I rotate and oscillate the same object in Processing

我正在 Processing 中创建雪花模拟,但是我不确定如何对图像执行多个转换,因为您似乎只能执行一个。

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);

这是我尝试旋转图像并来回摆动的地方。

    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;
  }

}

这是我的草图,只是加载资产并设置草图

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();  
}

您正在创建一个 Snowflake 实例。 您需要创建更多,然后更新每一个。

在你的情况下,你应该首先初始化一个 Snowflake 对象的数组(在你声明变量的顶部)。这是一个分配 99 Snowflake 个对象的数组的示例:

int numSnowflakes = 99;
Snowflake[] snowflakes = new Snowflake[numSnowflakes]; 

然后在setup()中你可以将每个数组元素初始化为一个新的Snowflake实例:

for(int i = 0 ; i < numSnowflakes; i++){
    snowflakes[i] = new Snowflake(25, 25);
  }

最后,在 draw() 中,您可以遍历每个对象,这样它就可以 descend()update():

for(int i = 0 ; i < numSnowflakes; i++){
    snowflakes[i].descend();
    snowflakes[i].update();  
  }

如果您还不熟悉 Processing 中的数组,我可以推荐以下资源:

  1. Processing arrays tutorial
  2. Processing ArrayObjects example
  3. Daniel Shiffman's Array of Objects Coding Train video tutorial along with Arrays and Loops

一旦你掌握了这个窍门,你也应该研究一下 ArrayList

更新 为了解决您的评论,您可以使用 push/pop 矩阵调用来进一步隔离坐标系并围绕其中心旋转图像:

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();

有关详细信息,请查看 Coordinate Systems Processing tutorial

作为参考,这里有一个测试草图,我使用了随机宽度的每个薄片:

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;
  }

}

您还应该查看 Daniel Shiffman's Snowfall coding challenge。 即使它是 p5.js,相同的逻辑也可以很容易地应用到处理中。