在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);
}
}
答案 0 :(得分:1)
首先回答你关于"打破"的问题circle:您需要创建新的rotor
实例,或者只需更改其center
和radius
等属性。如果我的想法正确,您只需要一个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
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()
做同样的事情来避免这种情况。到目前为止还不是问题,因为这还很轻,但如果项目进一步发展,可能会成为一个问题。