如何使椭圆的尺寸在处理过程中变得越来越小

时间:2016-02-02 14:52:11

标签: processing

我正在使用类来创建一些东西以便习惯它们,并且我试图获得我绘制的椭圆的大小以使其变得越来越大,以便它使它看起来更具交互性但是我不喜欢# 39;知道要实施的代码。

我已经展示了我在下面使用的代码;

void setup()
{
  size(640, 480);
}

void draw()
{  
  background(255); 

  for (int i = height-50; i > 0; i-= 20)
  {
    fill(random(255), random(255), random(255));
    ellipse(width/2, height/2, i, i);
  }
}

2 个答案:

答案 0 :(得分:1)

您只需将圆的宽度和高度存储在变量中,在draw()函数中使用该变量,然后在想要更改圆周大小时更改它。

以下是单击鼠标时更改圆圈大小的示例程序:

float radius = 50;

void setup(){
  size(500, 500);
  ellipseMode(RADIUS);
}

void mouseClicked(){
  radius = 250.0*mouseX/width;
}

void draw(){
  background(0);
  ellipse(width/2, height/2, radius, radius);
}

以下是一个自动增长和缩小圆圈的示例程序:

float radius = 0;
boolean grow = true;

void setup() {
  size(500, 500);
  ellipseMode(RADIUS);
}

void draw() {

  if (grow) {
    radius++;
    if (radius == 250) {
      grow = false;
    }
  } else {
    radius--;
    if (radius == 0) {
      grow = true;
    }
  }

  background(0);
  ellipse(width/2, height/2, radius, radius);
}

但两个例子中的想法都是一样的:只需将圆半径存储在变量中,更改该变量以更改大小,然后使用该变量绘制圆圈。

答案 1 :(得分:1)

只是为了补充凯文的好答案,这里有几个相同想法的变体(跟踪大小是否增加)。

第一种方法涉及使用增长速度变量,该变量在达到限制时简单地翻转符号。如果尺寸太小(下限)或太大(上限),则翻转符号(将增长速度乘以-1)将变为增长缩小,反之亦然:

//current size - continuously updated
float size = 10;
//minimum size
float minSize = 10;
//maximum size
float maxSize = 240;
//change speed for size (how much will the size increase/decrease each frame)
float sizeSpeed = 1.5;

void setup()
{
  size(640, 480);
}

void draw()
{  
  //if the size is either too small, or too big, flip the size speed sign (if it was positive (growing) - make it negative (shrink) - and vice versa)
  if(size < minSize || size > maxSize) {
    sizeSpeed *= -1;
  }
  //increment the size with the size speed (be it positive or negative)
  size += sizeSpeed;

  background(255); 
  fill(random(255), random(255), random(255));
  ellipse(width/2, height/2, size,size);

}

请注意,动作非常线性。由于您希望随着时间的推移增长和缩小一个圆,您可以使用sin()函数获得更平滑的动画。它需要一个角度作为参数,并根据角度值返回介于-1.0和1.0之间的值。您可以使用map()函数将此范围重新映射到所需的椭圆大小:

//current size - continuously updated
float size = 10;
//minimum size
float minSize = 10;
//maximum size
float maxSize = 240;
//change speed for size (how much will the size increase/decrease each frame)
float sizeSpeed = 0.025;

void setup()
{
  size(640, 480);
}

void draw()
{  
  size = map(sin(frameCount * sizeSpeed),-1.0,1.0,minSize,maxSize);

  background(255); 
  fill(random(255), random(255), random(255));
  ellipse(width/2, height/2, size,size);

}

更新就类而言,您可以开始将用于绘制椭圆的变量封装到类中。语法不复杂:

  1. 使用class关键字,然后使用类的名称(按惯例大写)并在{}中添加类成员 - 类范围
  2. 使用new关键字创建类的实例,并使用.表示法访问实例成员
  3. 这是使用上述内容的一个非常基本的例子:

    Ellipse e = new Ellipse();
    
    void setup()
    {
      size(640, 480);
    }
    
    void draw()
    {  
      e.size = map(sin(frameCount * e.sizeSpeed),-1.0,1.0,e.minSize,e.maxSize);
    
      background(255); 
      fill(random(255), random(255), random(255));
      ellipse(width/2, height/2, e.size,e.size);
    
    }
    
    class Ellipse{
      //current size - continuously updated
      float size = 10;
      //minimum size
      float minSize = 10;
      //maximum size
      float maxSize = 240;
      //change speed for size (how much will the size increase/decrease each frame)
      float sizeSpeed = 0.025;
    
    }
    

    这是一个很好而且简单的开始,但绘图部分没有被封装。 与在类中声明和使用变量的方式相同,您可以声明和使用函数。这是将椭圆绘图功能简单地移动到函数中的基本示例:

    Ellipse e = new Ellipse();
    
    void setup()
    {
      size(640, 480);
    }
    
    void draw()
    {  
    
      background(255); 
      e.render();
    
    }
    
    class Ellipse{
      //current size - continuously updated
      float size = 10;
      //minimum size
      float minSize = 10;
      //maximum size
      float maxSize = 240;
      //change speed for size (how much will the size increase/decrease each frame)
      float sizeSpeed = 0.025;
    
      void render(){
        size = map(sin(frameCount * sizeSpeed),-1.0,1.0,minSize,maxSize);
        fill(random(255), random(255), random(255));
        ellipse(width/2, height/2, size,size);
      }
    }
    

    正如您所注意到的,现在需要2行来初始化并从主草图渲染椭圆。还有一些事情可以改进。如果创建了第二个椭圆,则x和y相同,因此它们会相互模糊。将x,y属性添加到类将意味着每个实例将具有独立坐标。 在类似的说明中,frameCount是全局的,这意味着每个椭圆都使用相同的 角度/尺寸。我们也可以让它独立。

    Ellipse e1 = new Ellipse(320,240);
    Ellipse e2 = new Ellipse(20,20);
    
    void setup()
    {
      size(640, 480);
    }
    
    void draw()
    {  
    
      background(255);
      e1.render(); 
      e2.render();
    
    }
    
    class Ellipse{
      //current size - continuously updated
      float size = 10;
      //minimum size
      float minSize = 10;
      //maximum size
      float maxSize = 240;
      //change speed for size (how much will the size increase/decrease each frame)
      float sizeSpeed = 0.025;
    
      //position
      float x,y;
    
      //internal frameCount replacement
      int tick;
    
      //constructor
      Ellipse(float x,float y){
        this.x = x;//copy x argument value to the instance (this) x property 
        this.y = y;//copy x argument value to the instance (this) x property
      }
    
      void render(){
        tick++;
        size = map(sin(tick * sizeSpeed),-1.0,1.0,minSize,maxSize);
        fill(random(255), random(255), random(255));
        ellipse(x,y, size,size);
      }
    }
    

    请注意,我们还添加了构造函数。构造函数非常特殊:它就像是新实例的入口点。无论何时创建类的新实例,都会调用构造函数,通常会初始化数据。前面的示例没有明确定义构造函数,但是默认情况下,Processing提供的参数没有参数。为了使上述概念更进一步,我们创建了一个带有x,y坐标的构造函数:

    Ellipse e1 = new Ellipse(320,240);
    Ellipse e2 = new Ellipse(20,20);
    
    void setup()
    {
      size(640, 480);
    }
    
    void draw()
    {  
    
      background(255);
      e1.render(); 
      e2.render();
    
    }
    
    class Ellipse{
      //current size - continuously updated
      float size = 10;
      //minimum size
      float minSize = 10;
      //maximum size
      float maxSize = 240;
      //change speed for size (how much will the size increase/decrease each frame)
      float sizeSpeed = 0.025;
    
      //position
      float x,y;
    
      //internal frameCount replacement
      int tick;
    
      //constructor
      Ellipse(float x,float y){
        this.x = x;//copy x argument value to the instance (this) x property 
        this.y = y;//copy x argument value to the instance (this) x property
      }
    
      void render(){
        tick++;
        size = map(sin(tick * sizeSpeed),-1.0,1.0,minSize,maxSize);
        fill(random(255), random(255), random(255));
        ellipse(x,y, size,size);
      }
    }
    

    这是一个非常快速的概述。有关详细信息,请务必查看Daniel Shiffman's Objects tutorial

    考虑到这一点,你可以使用ArrayList在运行时创建新的省略号,并有一些有趣的随机椭圆参数:

    ArrayList<Ellipse> ellipses = new ArrayList<Ellipse>();
    
    void setup()
    {
      size(640, 480);
      ellipses.add(new Ellipse(width / 2, height / 2));
    }
    
    void draw()
    {  
    
      background(255);
      for(Ellipse e : ellipses){
        e.render();
      }
    }
    //add an ellipse every 5th frame if mouse is dragged
    void mouseDragged(){
      if(frameCount % 5 == 0) ellipses.add(new Ellipse(mouseX,mouseY));
    }
    //remove all ellipses if SPACE is pressed
    void keyPressed(){
      if(key == ' ') ellipses.clear();
    }
    
    //ellipse class
    class Ellipse{
      //current size - continuously updated
      float size = 10;
      //minimum size
      float minSize = 10;
      //maximum size
      float maxSize = 240;
      //change speed for size (how much will the size increase/decrease each frame)
      float sizeSpeed = 0.025;
    
      //position
      float x,y;
    
      //internal frameCount replacement
      int tick;
    
      int fill;
    
    
      //constructor
      Ellipse(float x,float y){
        this.x = x;//copy x argument value to the instance (this) x property 
        this.y = y;//copy x argument value to the instance (this) x property
        fill = color(random(32,192));
        sizeSpeed = random(0.025,0.01);
        maxSize = random(120,240);
      }
    
      void render(){
        tick++;
        size = map(sin(tick * sizeSpeed),-1.0,1.0,minSize,maxSize);
        fill(fill);
        ellipse(x,y, size,size);
      }
    }