如何处理绘制圆圈,让圆圈破裂,并开始在其他地方绘图?

时间:2014-09-14 21:31:48

标签: geometry processing

在Processing中工作,我正在尝试构建我的第一个生成补丁。我想要发生的事情是开始在屏幕上的某个地方绘制一个圆圈(一个圆圈的路径后面的一个点),但是在一段随机的时间之后,圆圈断开,这条线在一个随机的方向上随机进行一段时间,并开始在其他地方画一个新的圈子。

现在我正在绘制圆圈,并且我有一个切换机制,可以在一段随机时间后打开和关闭。我无法弄清楚如何让它从那个原始圈子“打破”,更不用说让它在其他地方开始一个新的圈子。有人会就如何做到这一点有一些建议吗?我认为它可能会产生一种有趣的视觉效果。

Rotor r;
float timer = 0;
boolean freeze = false;

void setup() {
  size(1000,600);
  smooth();
  noFill();
  frameRate(60);
  background(255);

  timeLimit();
  r = new Rotor(random(width),random(height),random(40,100));
}

void draw() {
  float t = frameCount / 100.0;
  timer = timer + frameRate/1000;

  r.drawRotor(t);

  if(timer > timeLimit()){
    timer = 0;
    timeLimit();

    if(freeze == true){
      freeze = false; 
    }else{
      freeze = true;
    }

    background(255);
  }
}

float timeLimit(){
  float timeLimit = random(200); 
  return timeLimit;
}

转子类:

class Rotor {

  color c;
  int thickness;
  float xPoint;
  float yPoint;
  float radius;
  float angle = 0;
  float centerX;
  float centerY;

  Rotor(float cX, float cY, float rad) {
    c = color(0);
    thickness = 1;
    centerX = cX;
    centerY = cY;
    radius = rad;
  } 

  void drawRotor(float t) {
    stroke(c);
    strokeWeight(thickness);
    angle = angle + frameRate/1000;
    xPoint = centerX + cos(angle) * radius;
    yPoint = centerY + sin(angle) * radius;
    ellipse(xPoint, yPoint,thickness,thickness);
  }


}

2 个答案:

答案 0 :(得分:1)

首先回答你关于"打破"的问题circle:您需要创建新的rotor实例,或者只需更改其centerradius等属性。如果我的想法正确,您只需要一个rotor实例,所以只需更改此值:

r.centerX = newX;
r.centerY = newY
r.radius = random(40,100) //as you have in setup

但你如何计算新的位置?它可能是随机的,但您想创建路径,因此您需要计算它。这是棘手的部分。那么如何建立连接线并开始新的圈子?

首先,您需要两个mode。首先画圆圈第二个画线。实现这一目标的最简单方法是更新rotor draw方法[您可以将mode变量作为drawRotor函数的参数或全局变量传递:

if(mode == 1){
  angle += frameRate/1000;
}else{
  radius += 2;
}

正如你所看到的,我只是在增加绘制圆的角度和增加绘制直线的半径(不是随机方向而是从中心的方向)之间有所区别。然后我们需要计算圆心的新位置。为此,我们可以根据angle简单计算出它将如何继续并替换新的radius,因此整个部分将如下所示:

if(mode != 1){              
  float newR = random(40,100);
  float newX = r.centerX + cos(r.angle) * (r.radius - newR);
  float newY = r.centerY + sin(r.angle) * (r.radius - newR);      
  r.newPos(newX, newY);
  r.radius = newR; //we cant change it earlier because we need also old value
}

这将发生在您的"时间处理程序"仅在将模式更改回绘图圆时才起作用。模式可以在处理程序

中进行简单更改
 mode *= -1; //but need to be init to 1 inside setup()

如果您希望路径始终可见,只需删除background()功能,但如果您想要一些很酷的效果,请在draw()

的乞讨时添加
noStroke();              //No stroke needed and you turn it on again in drawRotor()
fill( 255,255,255, 10 ); //This will set transparency to 10%
rect(0,0,width,height);  //You put layer after each "point" you draw
noFill();                //This will restore fill settings as you have before 

enter image description here

Here我粘贴整个代码只是为了演示,你应该根据自己的目的修改它。最好编写自己的版本。

答案 1 :(得分:0)

background()的调用通常是抽奖的第一件事。这是因为绘图仅在每个循环(帧)结束时渲染。因此,在开头调用bg将清除最后一帧中绘制的所有内容。如果您需要持续绘制槽框可以移除对background()的调用或每帧绘制您的东西。或者在PGraphics中绘制内容并显示它。

另一件事就是每次转动'转子'停止你应该给它新的随机坐标。

如果你要删除background()电话,这将解决问题:

Rotor r;
float timer = 0;
boolean freeze = false;

void setup() {
  size(1000,600);
  smooth();
  noFill();
  frameRate(60);
  background(255);

  timeLimit();

  r = new Rotor(random(width),random(height),random(40,100));


}

void draw() {
  float t = frameCount / 100.0;
  timer = timer + frameRate/1000;

  r.drawRotor(t);

  if(timer > timeLimit()){
    timer = 0;
    timeLimit();


    //***** here new coordinates!!
     r = new Rotor(random(width),random(height),random(40,100));
    //*****


    if(freeze == true){
      freeze = false; 
    }else{
      freeze = true;
    }



    //***** no background()
    // background(255);
  }
}

float timeLimit(){
  float timeLimit = random(200); 
  return timeLimit;
}

class Rotor {

  color c;
  int thickness;
  float xPoint;
  float yPoint;
  float radius;
  float angle = 0;
  float centerX;
  float centerY;

  Rotor(float cX, float cY, float rad) {
    c = color(0);
    thickness = 1;
    centerX = cX;
    centerY = cY;
    radius = rad;
  } 

  void drawRotor(float t) {
    stroke(c);
    strokeWeight(thickness);
    angle = angle + frameRate/1000;
    xPoint = centerX + cos(angle) * radius;
    yPoint = centerY + sin(angle) * radius;
    ellipse(xPoint, yPoint,thickness,thickness);
  }


}

现在,如果你需要清除屏幕,你可以制作一个List(ArrayList?)并在上一个完成后添加一个新的Rotor。但是你需要管理转子才能在没有动画的情况下自我展示。所以新创建的Rotor会动画,旧的只会在没有动画的情况下显示其弧形。或者制作一个没有调用bg的PGraphis并将其显示在可以进行bg调用的主画布中......

附注,请注意,将frameRate依赖于时间使得它可以依赖于系统性能。你可以使用millis()做同样的事情来避免这种情况。到目前为止还不是问题,因为这还很轻,但如果项目进一步发展,可能会成为一个问题。