两个 "Differential Growths" 同时 - 差不多
Two "Differential Growths" simultaneously - sort of
我对 Whosebug 还是个新手,对 Processing 和 Java 的主题还很陌生,如果我不能直接说清楚我的问题,我深表歉意。
我的目标是通过每次单击鼠标创建一个“生长的形状”。您将在下面找到我当前的代码,该代码当前允许通过单击鼠标来创建这些形状之一。但是当我再次点击时,我的第一个形状停止增长而第二个开始(有点难以解释 - 最好复制代码一次并尝试一下,然后你就会明白我的意思)。
几个小时以来,我一直在尝试以某种方式生成多种形状 - 每点击一次鼠标一个 - 它们各自继续自行生长,不幸的是没有成功。目标是同时有很多不断增长的形状。
你们知道如何实现吗?
如果您需要更多信息,请与我联系!
谢谢
劳拉
代码:
// PARAMETERS
float _maxForce = 0.9;
float _maxSpeed = 1;
float _desiredSeparation = 30;
float _separationCohesionRation = 1.1;
float _maxEdgeLen = 8;
boolean seed = false;
DifferentialLine _diff_line;
void setup() {
frameRate(60);
background(0);
size(1280, 720);
}
void draw() {
if(seed == true){
//println(frameCount);
background(0);
_diff_line.run();
_diff_line.render();
}
}
void mousePressed(){
seed = true;
malewas();
}
void malewas(){
_diff_line = new DifferentialLine(_maxForce, _maxSpeed, _desiredSeparation, _separationCohesionRation, _maxEdgeLen);
//fill(0);
float nodesStart = 3;
float angInc = TWO_PI/nodesStart;
float rayStart = 5;
for (float a=0; a<TWO_PI; a+=angInc) {
float x = mouseX + cos(a) * rayStart;
float y = mouseY + sin(a) * rayStart;
_diff_line.addNode(new Node(x, y, _diff_line.maxForce, _diff_line.maxSpeed, _diff_line.desiredSeparation, _diff_line.separationCohesionRation));
//println(mouseX);
//println(mouseY);
}
}
class DifferentialLine {
ArrayList<Node> nodes;
float maxForce;
float maxSpeed;
float desiredSeparation;
float separationCohesionRation;
float maxEdgeLen;
DifferentialLine(float mF, float mS, float dS, float sCr, float eL) {
nodes = new ArrayList<Node>();
maxSpeed = mF;
maxForce = mS;
desiredSeparation = dS;
separationCohesionRation = sCr;
maxEdgeLen = eL;
}
void run() {
for (Node n : nodes) {
n.run(nodes);
}
growth();
}
void addNode(Node n) {
nodes.add(n);
}
void addNodeAt(Node n, int index) {
nodes.add(index, n);
}
void growth() {
for (int i=0; i<nodes.size()-1; i++) {
Node n1 = nodes.get(i);
Node n2 = nodes.get(i+1);
float d = PVector.dist(n1.position, n2.position);
if (d>maxEdgeLen) { // Can add more rules for inserting nodes
int index = nodes.indexOf(n2);
PVector middleNode = PVector.add(n1.position, n2.position).div(2);
addNodeAt(new Node(middleNode.x, middleNode.y, maxForce, maxSpeed, desiredSeparation, separationCohesionRation), index);
}
}
}
void render() {
for (int i=0; i<nodes.size()-1; i++) {
PVector p1 = nodes.get(i).position;
PVector p2 = nodes.get(i+1).position;
line(p1.x, p1.y, p2.x, p2.y);
colorMode(HSB);
stroke(255);
//stroke(10,frameCount*0.3,100);
//stroke(255);//Farbe
strokeWeight(1); //Strichstärke
if (i==nodes.size()-2) {
line(p2.x, p2.y, nodes.get(0).position.x, nodes.get(0).position.y);
}
}
}
}
class Node {
PVector position;
PVector velocity;
PVector acceleration;
float maxForce;
float maxSpeed;
float desiredSeparation;
float separationCohesionRation;
Node(float x, float y) {
acceleration = new PVector(0, 0);
velocity =PVector.random2D();
position = new PVector(x, y);
}
Node(float x, float y, float mF, float mS, float dS, float sCr) {
acceleration = new PVector(0, 0);
velocity =PVector.random2D();
position = new PVector(x, y);
maxSpeed = mF;
maxForce = mS;
desiredSeparation = dS;
separationCohesionRation = sCr;
}
void run(ArrayList<Node> nodes) {
differentiate(nodes);
update();
}
void applyForce(PVector force) {
acceleration.add(force);
}
void differentiate(ArrayList<Node> nodes) {
PVector separation = separate(nodes);
PVector cohesion = edgeCohesion(nodes);
separation.mult(separationCohesionRation);
//cohesion.mult(1.0);
applyForce(separation);
applyForce(cohesion);
}
void update() {
velocity.add(acceleration);
velocity.limit(maxSpeed);
position.add(velocity);
acceleration.mult(0);
}
PVector seek(PVector target) {
PVector desired = PVector.sub(target, position);
desired.setMag(maxSpeed);
PVector steer = PVector.sub(desired, velocity);
steer.limit(maxForce);
return steer;
}
PVector separate(ArrayList<Node> nodes) {
PVector steer = new PVector(0, 0);
int count = 0;
for (Node other : nodes) {
float d = PVector.dist(position, other.position);
if (d>0 && d < desiredSeparation) {
PVector diff = PVector.sub(position, other.position);
diff.normalize();
diff.div(d); // Weight by distance
steer.add(diff);
count++;
}
}
if (count>0) {
steer.div((float)count);
}
if (steer.mag() > 0) {
steer.setMag(maxSpeed);
steer.sub(velocity);
steer.limit(maxForce);
}
return steer;
}
PVector edgeCohesion (ArrayList<Node> nodes) {
PVector sum = new PVector(0, 0);
int this_index = nodes.indexOf(this);
if (this_index!=0 && this_index!=nodes.size()-1) {
sum.add(nodes.get(this_index-1).position).add(nodes.get(this_index+1).position);
} else if (this_index == 0) {
sum.add(nodes.get(nodes.size()-1).position).add(nodes.get(this_index+1).position);
} else if (this_index == nodes.size()-1) {
sum.add(nodes.get(this_index-1).position).add(nodes.get(0).position);
}
sum.div(2);
return seek(sum);
}
}
第一个答案后的代码:
// PARAMETERS
float _maxForce = 0.9;
float _maxSpeed = 1;
float _desiredSeparation = 30;
float _separationCohesionRation = 1.1;
float _maxEdgeLen = 8;
boolean seed = false;
DifferentialLine _diff_line;
ArrayList<DifferentialLine> lines = new ArrayList<DifferentialLine>();
void setup() {
frameRate(60);
background(0);
size(1280, 720);
}
void draw() {
if(seed == true){
//println(frameCount);
background(0);
//_diff_line.run();
//_diff_line.render();
for (DifferentialLine line : lines) {
line.run();
line.render();
}
}
}
void mousePressed(){
seed = true;
DifferentialLine newLine = new DifferentialLine(_maxForce, _maxSpeed, _desiredSeparation, _separationCohesionRation, _maxEdgeLen);
malewas();
lines.add(newLine);
}
void malewas(){
_diff_line = new DifferentialLine(_maxForce, _maxSpeed, _desiredSeparation, _separationCohesionRation, _maxEdgeLen);
//fill(0);
float nodesStart = 3;
float angInc = TWO_PI/nodesStart;
float rayStart = 5;
for (float a=0; a<TWO_PI; a+=angInc) {
float x = mouseX + cos(a) * rayStart;
float y = mouseY + sin(a) * rayStart;
_diff_line.addNode(new Node(x, y, _diff_line.maxForce, _diff_line.maxSpeed, _diff_line.desiredSeparation, _diff_line.separationCohesionRation));
//println(mouseX);
//println(mouseY);
}
}
class DifferentialLine {
ArrayList<Node> nodes;
float maxForce;
float maxSpeed;
float desiredSeparation;
float separationCohesionRation;
float maxEdgeLen;
DifferentialLine(float mF, float mS, float dS, float sCr, float eL) {
nodes = new ArrayList<Node>();
maxSpeed = mF;
maxForce = mS;
desiredSeparation = dS;
separationCohesionRation = sCr;
maxEdgeLen = eL;
}
void run() {
for (Node n : nodes) {
n.run(nodes);
}
growth();
}
void addNode(Node n) {
nodes.add(n);
}
void addNodeAt(Node n, int index) {
nodes.add(index, n);
}
void growth() {
for (int i=0; i<nodes.size()-1; i++) {
Node n1 = nodes.get(i);
Node n2 = nodes.get(i+1);
float d = PVector.dist(n1.position, n2.position);
if (d>maxEdgeLen) { // Can add more rules for inserting nodes
int index = nodes.indexOf(n2);
PVector middleNode = PVector.add(n1.position, n2.position).div(2);
addNodeAt(new Node(middleNode.x, middleNode.y, maxForce, maxSpeed, desiredSeparation, separationCohesionRation), index);
}
}
}
void render() {
for (int i=0; i<nodes.size()-1; i++) {
PVector p1 = nodes.get(i).position;
PVector p2 = nodes.get(i+1).position;
line(p1.x, p1.y, p2.x, p2.y);
colorMode(HSB);
stroke(255);
//stroke(10,frameCount*0.3,100);
//stroke(255);//Farbe
strokeWeight(1); //Strichstärke
if (i==nodes.size()-2) {
line(p2.x, p2.y, nodes.get(0).position.x, nodes.get(0).position.y);
}
}
}
}
class Node {
PVector position;
PVector velocity;
PVector acceleration;
float maxForce;
float maxSpeed;
float desiredSeparation;
float separationCohesionRation;
Node(float x, float y) {
acceleration = new PVector(0, 0);
velocity =PVector.random2D();
position = new PVector(x, y);
}
Node(float x, float y, float mF, float mS, float dS, float sCr) {
acceleration = new PVector(0, 0);
velocity =PVector.random2D();
position = new PVector(x, y);
maxSpeed = mF;
maxForce = mS;
desiredSeparation = dS;
separationCohesionRation = sCr;
}
void run(ArrayList<Node> nodes) {
differentiate(nodes);
update();
}
void applyForce(PVector force) {
acceleration.add(force);
}
void differentiate(ArrayList<Node> nodes) {
PVector separation = separate(nodes);
PVector cohesion = edgeCohesion(nodes);
separation.mult(separationCohesionRation);
//cohesion.mult(1.0);
applyForce(separation);
applyForce(cohesion);
}
void update() {
velocity.add(acceleration);
velocity.limit(maxSpeed);
position.add(velocity);
acceleration.mult(0);
}
PVector seek(PVector target) {
PVector desired = PVector.sub(target, position);
desired.setMag(maxSpeed);
PVector steer = PVector.sub(desired, velocity);
steer.limit(maxForce);
return steer;
}
PVector separate(ArrayList<Node> nodes) {
PVector steer = new PVector(0, 0);
int count = 0;
for (Node other : nodes) {
float d = PVector.dist(position, other.position);
if (d>0 && d < desiredSeparation) {
PVector diff = PVector.sub(position, other.position);
diff.normalize();
diff.div(d); // Weight by distance
steer.add(diff);
count++;
}
}
if (count>0) {
steer.div((float)count);
}
if (steer.mag() > 0) {
steer.setMag(maxSpeed);
steer.sub(velocity);
steer.limit(maxForce);
}
return steer;
}
PVector edgeCohesion (ArrayList<Node> nodes) {
PVector sum = new PVector(0, 0);
int this_index = nodes.indexOf(this);
if (this_index!=0 && this_index!=nodes.size()-1) {
sum.add(nodes.get(this_index-1).position).add(nodes.get(this_index+1).position);
} else if (this_index == 0) {
sum.add(nodes.get(nodes.size()-1).position).add(nodes.get(this_index+1).position);
} else if (this_index == nodes.size()-1) {
sum.add(nodes.get(this_index-1).position).add(nodes.get(0).position);
}
sum.div(2);
return seek(sum);
}
}
问题
虽然实际上每次单击鼠标都会创建一个新形状,但您总是将其分配给同一个变量 (_diff_line
):
_diff_line = new DifferentialLine(_maxForce, _maxSpeed, _desiredSeparation, _separationCohesionRation, _maxEdgeLen);
因此,当您调用 _diff_line.run()
和 _diff_line.render()
时,它只会对最近创建的那个进行操作。旧的已经不存在了。
解决方案
要解决此问题,您需要将每一行分配给不同的变量。您很可能会通过创建一个 Array or ArrayList 并在每次单击时向数组添加一个新的 DifferentialLine
来做到这一点:
// create an ArrayList to hold all the lines
ArrayList<DifferentialLine> lines = new ArrayList<DifferentialLine>();
void mousePressed(){
// create the new line
DifferentialLine newLine = new DifferentialLine(_maxForce, _maxSpeed, _desiredSeparation, _separationCohesionRation, _maxEdgeLen);
// ... do your node setup stuff
// add the new line to the ArrayList
lines.add(newLine);
}
然后,当你想渲染它们时,你可以遍历 ArrayList(或 Array)并绘制每一个:
for (DifferentialLine line : lines) {
line.run();
line.render();
}
解决方案
// PARAMETERS
float _maxForce = 0.9;
float _maxSpeed = 1;
float _desiredSeparation = 30;
float _separationCohesionRation = 1.1;
float _maxEdgeLen = 8;
boolean seed = false;
//DifferentialLine _diff_line;
ArrayList<DifferentialLine> lines = new ArrayList<DifferentialLine>();
void setup() {
frameRate(60);
background(0);
size(1280, 720);
}
void draw() {
if (seed == true) {
//println(frameCount);
background(0);
//_diff_line.run();
//_diff_line.render();
for (DifferentialLine line : lines) {
line.run();
line.render();
}
}
}
void mousePressed() {
seed = true;
DifferentialLine newLine = new DifferentialLine(_maxForce, _maxSpeed, _desiredSeparation, _separationCohesionRation, _maxEdgeLen);
//drawseed();
float nodesStart = 3;
float angInc = TWO_PI/nodesStart;
float rayStart = 5;
for (float a=0; a<TWO_PI; a+=angInc) {
float x = mouseX + cos(a) * rayStart;
float y = mouseY + sin(a) * rayStart;
newLine.addNode(new Node(x, y, newLine.maxForce, newLine.maxSpeed, newLine.desiredSeparation, newLine.separationCohesionRation));
//println(mouseX);
//println(mouseY);
}
lines.add(newLine);
}
/*void drawseed() {
_diff_line = new DifferentialLine(_maxForce, _maxSpeed, _desiredSeparation, _separationCohesionRation, _maxEdgeLen);
//fill(0);
float nodesStart = 3;
float angInc = TWO_PI/nodesStart;
float rayStart = 5;
for (float a=0; a<TWO_PI; a+=angInc) {
float x = mouseX + cos(a) * rayStart;
float y = mouseY + sin(a) * rayStart;
_diff_line.addNode(new Node(x, y, _diff_line.maxForce, _diff_line.maxSpeed, _diff_line.desiredSeparation, _diff_line.separationCohesionRation));
//println(mouseX);
//println(mouseY);
}
}*/
class DifferentialLine {
ArrayList<Node> nodes;
float maxForce;
float maxSpeed;
float desiredSeparation;
float separationCohesionRation;
float maxEdgeLen;
DifferentialLine(float mF, float mS, float dS, float sCr, float eL) {
nodes = new ArrayList<Node>();
maxSpeed = mF;
maxForce = mS;
desiredSeparation = dS;
separationCohesionRation = sCr;
maxEdgeLen = eL;
}
void run() {
for (Node n : nodes) {
n.run(nodes);
}
growth();
}
void addNode(Node n) {
nodes.add(n);
}
void addNodeAt(Node n, int index) {
nodes.add(index, n);
}
void growth() {
for (int i=0; i<nodes.size()-1; i++) {
Node n1 = nodes.get(i);
Node n2 = nodes.get(i+1);
float d = PVector.dist(n1.position, n2.position);
if (d>maxEdgeLen) { // Can add more rules for inserting nodes
int index = nodes.indexOf(n2);
PVector middleNode = PVector.add(n1.position, n2.position).div(2);
addNodeAt(new Node(middleNode.x, middleNode.y, maxForce, maxSpeed, desiredSeparation, separationCohesionRation), index);
}
}
}
void render() {
for (int i=0; i<nodes.size()-1; i++) {
PVector p1 = nodes.get(i).position;
PVector p2 = nodes.get(i+1).position;
line(p1.x, p1.y, p2.x, p2.y);
colorMode(HSB);
stroke(255);
//stroke(10,frameCount*0.3,100);
//stroke(255);//Farbe
strokeWeight(1); //Strichstärke
if (i==nodes.size()-2) {
line(p2.x, p2.y, nodes.get(0).position.x, nodes.get(0).position.y);
}
}
}
}
class Node {
PVector position;
PVector velocity;
PVector acceleration;
float maxForce;
float maxSpeed;
float desiredSeparation;
float separationCohesionRation;
Node(float x, float y) {
acceleration = new PVector(0, 0);
velocity =PVector.random2D();
position = new PVector(x, y);
}
Node(float x, float y, float mF, float mS, float dS, float sCr) {
acceleration = new PVector(0, 0);
velocity =PVector.random2D();
position = new PVector(x, y);
maxSpeed = mF;
maxForce = mS;
desiredSeparation = dS;
separationCohesionRation = sCr;
}
void run(ArrayList<Node> nodes) {
differentiate(nodes);
update();
}
void applyForce(PVector force) {
acceleration.add(force);
}
void differentiate(ArrayList<Node> nodes) {
PVector separation = separate(nodes);
PVector cohesion = edgeCohesion(nodes);
separation.mult(separationCohesionRation);
//cohesion.mult(1.0);
applyForce(separation);
applyForce(cohesion);
}
void update() {
velocity.add(acceleration);
velocity.limit(maxSpeed);
position.add(velocity);
acceleration.mult(0);
}
PVector seek(PVector target) {
PVector desired = PVector.sub(target, position);
desired.setMag(maxSpeed);
PVector steer = PVector.sub(desired, velocity);
steer.limit(maxForce);
return steer;
}
PVector separate(ArrayList<Node> nodes) {
PVector steer = new PVector(0, 0);
int count = 0;
for (Node other : nodes) {
float d = PVector.dist(position, other.position);
if (d>0 && d < desiredSeparation) {
PVector diff = PVector.sub(position, other.position);
diff.normalize();
diff.div(d); // Weight by distance
steer.add(diff);
count++;
}
}
if (count>0) {
steer.div((float)count);
}
if (steer.mag() > 0) {
steer.setMag(maxSpeed);
steer.sub(velocity);
steer.limit(maxForce);
}
return steer;
}
PVector edgeCohesion (ArrayList<Node> nodes) {
PVector sum = new PVector(0, 0);
int this_index = nodes.indexOf(this);
if (this_index!=0 && this_index!=nodes.size()-1) {
sum.add(nodes.get(this_index-1).position).add(nodes.get(this_index+1).position);
} else if (this_index == 0) {
sum.add(nodes.get(nodes.size()-1).position).add(nodes.get(this_index+1).position);
} else if (this_index == nodes.size()-1) {
sum.add(nodes.get(this_index-1).position).add(nodes.get(0).position);
}
sum.div(2);
return seek(sum);
}
}
我对 Whosebug 还是个新手,对 Processing 和 Java 的主题还很陌生,如果我不能直接说清楚我的问题,我深表歉意。
我的目标是通过每次单击鼠标创建一个“生长的形状”。您将在下面找到我当前的代码,该代码当前允许通过单击鼠标来创建这些形状之一。但是当我再次点击时,我的第一个形状停止增长而第二个开始(有点难以解释 - 最好复制代码一次并尝试一下,然后你就会明白我的意思)。
几个小时以来,我一直在尝试以某种方式生成多种形状 - 每点击一次鼠标一个 - 它们各自继续自行生长,不幸的是没有成功。目标是同时有很多不断增长的形状。
你们知道如何实现吗?
如果您需要更多信息,请与我联系!
谢谢 劳拉
代码:
// PARAMETERS
float _maxForce = 0.9;
float _maxSpeed = 1;
float _desiredSeparation = 30;
float _separationCohesionRation = 1.1;
float _maxEdgeLen = 8;
boolean seed = false;
DifferentialLine _diff_line;
void setup() {
frameRate(60);
background(0);
size(1280, 720);
}
void draw() {
if(seed == true){
//println(frameCount);
background(0);
_diff_line.run();
_diff_line.render();
}
}
void mousePressed(){
seed = true;
malewas();
}
void malewas(){
_diff_line = new DifferentialLine(_maxForce, _maxSpeed, _desiredSeparation, _separationCohesionRation, _maxEdgeLen);
//fill(0);
float nodesStart = 3;
float angInc = TWO_PI/nodesStart;
float rayStart = 5;
for (float a=0; a<TWO_PI; a+=angInc) {
float x = mouseX + cos(a) * rayStart;
float y = mouseY + sin(a) * rayStart;
_diff_line.addNode(new Node(x, y, _diff_line.maxForce, _diff_line.maxSpeed, _diff_line.desiredSeparation, _diff_line.separationCohesionRation));
//println(mouseX);
//println(mouseY);
}
}
class DifferentialLine {
ArrayList<Node> nodes;
float maxForce;
float maxSpeed;
float desiredSeparation;
float separationCohesionRation;
float maxEdgeLen;
DifferentialLine(float mF, float mS, float dS, float sCr, float eL) {
nodes = new ArrayList<Node>();
maxSpeed = mF;
maxForce = mS;
desiredSeparation = dS;
separationCohesionRation = sCr;
maxEdgeLen = eL;
}
void run() {
for (Node n : nodes) {
n.run(nodes);
}
growth();
}
void addNode(Node n) {
nodes.add(n);
}
void addNodeAt(Node n, int index) {
nodes.add(index, n);
}
void growth() {
for (int i=0; i<nodes.size()-1; i++) {
Node n1 = nodes.get(i);
Node n2 = nodes.get(i+1);
float d = PVector.dist(n1.position, n2.position);
if (d>maxEdgeLen) { // Can add more rules for inserting nodes
int index = nodes.indexOf(n2);
PVector middleNode = PVector.add(n1.position, n2.position).div(2);
addNodeAt(new Node(middleNode.x, middleNode.y, maxForce, maxSpeed, desiredSeparation, separationCohesionRation), index);
}
}
}
void render() {
for (int i=0; i<nodes.size()-1; i++) {
PVector p1 = nodes.get(i).position;
PVector p2 = nodes.get(i+1).position;
line(p1.x, p1.y, p2.x, p2.y);
colorMode(HSB);
stroke(255);
//stroke(10,frameCount*0.3,100);
//stroke(255);//Farbe
strokeWeight(1); //Strichstärke
if (i==nodes.size()-2) {
line(p2.x, p2.y, nodes.get(0).position.x, nodes.get(0).position.y);
}
}
}
}
class Node {
PVector position;
PVector velocity;
PVector acceleration;
float maxForce;
float maxSpeed;
float desiredSeparation;
float separationCohesionRation;
Node(float x, float y) {
acceleration = new PVector(0, 0);
velocity =PVector.random2D();
position = new PVector(x, y);
}
Node(float x, float y, float mF, float mS, float dS, float sCr) {
acceleration = new PVector(0, 0);
velocity =PVector.random2D();
position = new PVector(x, y);
maxSpeed = mF;
maxForce = mS;
desiredSeparation = dS;
separationCohesionRation = sCr;
}
void run(ArrayList<Node> nodes) {
differentiate(nodes);
update();
}
void applyForce(PVector force) {
acceleration.add(force);
}
void differentiate(ArrayList<Node> nodes) {
PVector separation = separate(nodes);
PVector cohesion = edgeCohesion(nodes);
separation.mult(separationCohesionRation);
//cohesion.mult(1.0);
applyForce(separation);
applyForce(cohesion);
}
void update() {
velocity.add(acceleration);
velocity.limit(maxSpeed);
position.add(velocity);
acceleration.mult(0);
}
PVector seek(PVector target) {
PVector desired = PVector.sub(target, position);
desired.setMag(maxSpeed);
PVector steer = PVector.sub(desired, velocity);
steer.limit(maxForce);
return steer;
}
PVector separate(ArrayList<Node> nodes) {
PVector steer = new PVector(0, 0);
int count = 0;
for (Node other : nodes) {
float d = PVector.dist(position, other.position);
if (d>0 && d < desiredSeparation) {
PVector diff = PVector.sub(position, other.position);
diff.normalize();
diff.div(d); // Weight by distance
steer.add(diff);
count++;
}
}
if (count>0) {
steer.div((float)count);
}
if (steer.mag() > 0) {
steer.setMag(maxSpeed);
steer.sub(velocity);
steer.limit(maxForce);
}
return steer;
}
PVector edgeCohesion (ArrayList<Node> nodes) {
PVector sum = new PVector(0, 0);
int this_index = nodes.indexOf(this);
if (this_index!=0 && this_index!=nodes.size()-1) {
sum.add(nodes.get(this_index-1).position).add(nodes.get(this_index+1).position);
} else if (this_index == 0) {
sum.add(nodes.get(nodes.size()-1).position).add(nodes.get(this_index+1).position);
} else if (this_index == nodes.size()-1) {
sum.add(nodes.get(this_index-1).position).add(nodes.get(0).position);
}
sum.div(2);
return seek(sum);
}
}
第一个答案后的代码:
// PARAMETERS
float _maxForce = 0.9;
float _maxSpeed = 1;
float _desiredSeparation = 30;
float _separationCohesionRation = 1.1;
float _maxEdgeLen = 8;
boolean seed = false;
DifferentialLine _diff_line;
ArrayList<DifferentialLine> lines = new ArrayList<DifferentialLine>();
void setup() {
frameRate(60);
background(0);
size(1280, 720);
}
void draw() {
if(seed == true){
//println(frameCount);
background(0);
//_diff_line.run();
//_diff_line.render();
for (DifferentialLine line : lines) {
line.run();
line.render();
}
}
}
void mousePressed(){
seed = true;
DifferentialLine newLine = new DifferentialLine(_maxForce, _maxSpeed, _desiredSeparation, _separationCohesionRation, _maxEdgeLen);
malewas();
lines.add(newLine);
}
void malewas(){
_diff_line = new DifferentialLine(_maxForce, _maxSpeed, _desiredSeparation, _separationCohesionRation, _maxEdgeLen);
//fill(0);
float nodesStart = 3;
float angInc = TWO_PI/nodesStart;
float rayStart = 5;
for (float a=0; a<TWO_PI; a+=angInc) {
float x = mouseX + cos(a) * rayStart;
float y = mouseY + sin(a) * rayStart;
_diff_line.addNode(new Node(x, y, _diff_line.maxForce, _diff_line.maxSpeed, _diff_line.desiredSeparation, _diff_line.separationCohesionRation));
//println(mouseX);
//println(mouseY);
}
}
class DifferentialLine {
ArrayList<Node> nodes;
float maxForce;
float maxSpeed;
float desiredSeparation;
float separationCohesionRation;
float maxEdgeLen;
DifferentialLine(float mF, float mS, float dS, float sCr, float eL) {
nodes = new ArrayList<Node>();
maxSpeed = mF;
maxForce = mS;
desiredSeparation = dS;
separationCohesionRation = sCr;
maxEdgeLen = eL;
}
void run() {
for (Node n : nodes) {
n.run(nodes);
}
growth();
}
void addNode(Node n) {
nodes.add(n);
}
void addNodeAt(Node n, int index) {
nodes.add(index, n);
}
void growth() {
for (int i=0; i<nodes.size()-1; i++) {
Node n1 = nodes.get(i);
Node n2 = nodes.get(i+1);
float d = PVector.dist(n1.position, n2.position);
if (d>maxEdgeLen) { // Can add more rules for inserting nodes
int index = nodes.indexOf(n2);
PVector middleNode = PVector.add(n1.position, n2.position).div(2);
addNodeAt(new Node(middleNode.x, middleNode.y, maxForce, maxSpeed, desiredSeparation, separationCohesionRation), index);
}
}
}
void render() {
for (int i=0; i<nodes.size()-1; i++) {
PVector p1 = nodes.get(i).position;
PVector p2 = nodes.get(i+1).position;
line(p1.x, p1.y, p2.x, p2.y);
colorMode(HSB);
stroke(255);
//stroke(10,frameCount*0.3,100);
//stroke(255);//Farbe
strokeWeight(1); //Strichstärke
if (i==nodes.size()-2) {
line(p2.x, p2.y, nodes.get(0).position.x, nodes.get(0).position.y);
}
}
}
}
class Node {
PVector position;
PVector velocity;
PVector acceleration;
float maxForce;
float maxSpeed;
float desiredSeparation;
float separationCohesionRation;
Node(float x, float y) {
acceleration = new PVector(0, 0);
velocity =PVector.random2D();
position = new PVector(x, y);
}
Node(float x, float y, float mF, float mS, float dS, float sCr) {
acceleration = new PVector(0, 0);
velocity =PVector.random2D();
position = new PVector(x, y);
maxSpeed = mF;
maxForce = mS;
desiredSeparation = dS;
separationCohesionRation = sCr;
}
void run(ArrayList<Node> nodes) {
differentiate(nodes);
update();
}
void applyForce(PVector force) {
acceleration.add(force);
}
void differentiate(ArrayList<Node> nodes) {
PVector separation = separate(nodes);
PVector cohesion = edgeCohesion(nodes);
separation.mult(separationCohesionRation);
//cohesion.mult(1.0);
applyForce(separation);
applyForce(cohesion);
}
void update() {
velocity.add(acceleration);
velocity.limit(maxSpeed);
position.add(velocity);
acceleration.mult(0);
}
PVector seek(PVector target) {
PVector desired = PVector.sub(target, position);
desired.setMag(maxSpeed);
PVector steer = PVector.sub(desired, velocity);
steer.limit(maxForce);
return steer;
}
PVector separate(ArrayList<Node> nodes) {
PVector steer = new PVector(0, 0);
int count = 0;
for (Node other : nodes) {
float d = PVector.dist(position, other.position);
if (d>0 && d < desiredSeparation) {
PVector diff = PVector.sub(position, other.position);
diff.normalize();
diff.div(d); // Weight by distance
steer.add(diff);
count++;
}
}
if (count>0) {
steer.div((float)count);
}
if (steer.mag() > 0) {
steer.setMag(maxSpeed);
steer.sub(velocity);
steer.limit(maxForce);
}
return steer;
}
PVector edgeCohesion (ArrayList<Node> nodes) {
PVector sum = new PVector(0, 0);
int this_index = nodes.indexOf(this);
if (this_index!=0 && this_index!=nodes.size()-1) {
sum.add(nodes.get(this_index-1).position).add(nodes.get(this_index+1).position);
} else if (this_index == 0) {
sum.add(nodes.get(nodes.size()-1).position).add(nodes.get(this_index+1).position);
} else if (this_index == nodes.size()-1) {
sum.add(nodes.get(this_index-1).position).add(nodes.get(0).position);
}
sum.div(2);
return seek(sum);
}
}
问题
虽然实际上每次单击鼠标都会创建一个新形状,但您总是将其分配给同一个变量 (_diff_line
):
_diff_line = new DifferentialLine(_maxForce, _maxSpeed, _desiredSeparation, _separationCohesionRation, _maxEdgeLen);
因此,当您调用 _diff_line.run()
和 _diff_line.render()
时,它只会对最近创建的那个进行操作。旧的已经不存在了。
解决方案
要解决此问题,您需要将每一行分配给不同的变量。您很可能会通过创建一个 Array or ArrayList 并在每次单击时向数组添加一个新的 DifferentialLine
来做到这一点:
// create an ArrayList to hold all the lines
ArrayList<DifferentialLine> lines = new ArrayList<DifferentialLine>();
void mousePressed(){
// create the new line
DifferentialLine newLine = new DifferentialLine(_maxForce, _maxSpeed, _desiredSeparation, _separationCohesionRation, _maxEdgeLen);
// ... do your node setup stuff
// add the new line to the ArrayList
lines.add(newLine);
}
然后,当你想渲染它们时,你可以遍历 ArrayList(或 Array)并绘制每一个:
for (DifferentialLine line : lines) {
line.run();
line.render();
}
解决方案
// PARAMETERS
float _maxForce = 0.9;
float _maxSpeed = 1;
float _desiredSeparation = 30;
float _separationCohesionRation = 1.1;
float _maxEdgeLen = 8;
boolean seed = false;
//DifferentialLine _diff_line;
ArrayList<DifferentialLine> lines = new ArrayList<DifferentialLine>();
void setup() {
frameRate(60);
background(0);
size(1280, 720);
}
void draw() {
if (seed == true) {
//println(frameCount);
background(0);
//_diff_line.run();
//_diff_line.render();
for (DifferentialLine line : lines) {
line.run();
line.render();
}
}
}
void mousePressed() {
seed = true;
DifferentialLine newLine = new DifferentialLine(_maxForce, _maxSpeed, _desiredSeparation, _separationCohesionRation, _maxEdgeLen);
//drawseed();
float nodesStart = 3;
float angInc = TWO_PI/nodesStart;
float rayStart = 5;
for (float a=0; a<TWO_PI; a+=angInc) {
float x = mouseX + cos(a) * rayStart;
float y = mouseY + sin(a) * rayStart;
newLine.addNode(new Node(x, y, newLine.maxForce, newLine.maxSpeed, newLine.desiredSeparation, newLine.separationCohesionRation));
//println(mouseX);
//println(mouseY);
}
lines.add(newLine);
}
/*void drawseed() {
_diff_line = new DifferentialLine(_maxForce, _maxSpeed, _desiredSeparation, _separationCohesionRation, _maxEdgeLen);
//fill(0);
float nodesStart = 3;
float angInc = TWO_PI/nodesStart;
float rayStart = 5;
for (float a=0; a<TWO_PI; a+=angInc) {
float x = mouseX + cos(a) * rayStart;
float y = mouseY + sin(a) * rayStart;
_diff_line.addNode(new Node(x, y, _diff_line.maxForce, _diff_line.maxSpeed, _diff_line.desiredSeparation, _diff_line.separationCohesionRation));
//println(mouseX);
//println(mouseY);
}
}*/
class DifferentialLine {
ArrayList<Node> nodes;
float maxForce;
float maxSpeed;
float desiredSeparation;
float separationCohesionRation;
float maxEdgeLen;
DifferentialLine(float mF, float mS, float dS, float sCr, float eL) {
nodes = new ArrayList<Node>();
maxSpeed = mF;
maxForce = mS;
desiredSeparation = dS;
separationCohesionRation = sCr;
maxEdgeLen = eL;
}
void run() {
for (Node n : nodes) {
n.run(nodes);
}
growth();
}
void addNode(Node n) {
nodes.add(n);
}
void addNodeAt(Node n, int index) {
nodes.add(index, n);
}
void growth() {
for (int i=0; i<nodes.size()-1; i++) {
Node n1 = nodes.get(i);
Node n2 = nodes.get(i+1);
float d = PVector.dist(n1.position, n2.position);
if (d>maxEdgeLen) { // Can add more rules for inserting nodes
int index = nodes.indexOf(n2);
PVector middleNode = PVector.add(n1.position, n2.position).div(2);
addNodeAt(new Node(middleNode.x, middleNode.y, maxForce, maxSpeed, desiredSeparation, separationCohesionRation), index);
}
}
}
void render() {
for (int i=0; i<nodes.size()-1; i++) {
PVector p1 = nodes.get(i).position;
PVector p2 = nodes.get(i+1).position;
line(p1.x, p1.y, p2.x, p2.y);
colorMode(HSB);
stroke(255);
//stroke(10,frameCount*0.3,100);
//stroke(255);//Farbe
strokeWeight(1); //Strichstärke
if (i==nodes.size()-2) {
line(p2.x, p2.y, nodes.get(0).position.x, nodes.get(0).position.y);
}
}
}
}
class Node {
PVector position;
PVector velocity;
PVector acceleration;
float maxForce;
float maxSpeed;
float desiredSeparation;
float separationCohesionRation;
Node(float x, float y) {
acceleration = new PVector(0, 0);
velocity =PVector.random2D();
position = new PVector(x, y);
}
Node(float x, float y, float mF, float mS, float dS, float sCr) {
acceleration = new PVector(0, 0);
velocity =PVector.random2D();
position = new PVector(x, y);
maxSpeed = mF;
maxForce = mS;
desiredSeparation = dS;
separationCohesionRation = sCr;
}
void run(ArrayList<Node> nodes) {
differentiate(nodes);
update();
}
void applyForce(PVector force) {
acceleration.add(force);
}
void differentiate(ArrayList<Node> nodes) {
PVector separation = separate(nodes);
PVector cohesion = edgeCohesion(nodes);
separation.mult(separationCohesionRation);
//cohesion.mult(1.0);
applyForce(separation);
applyForce(cohesion);
}
void update() {
velocity.add(acceleration);
velocity.limit(maxSpeed);
position.add(velocity);
acceleration.mult(0);
}
PVector seek(PVector target) {
PVector desired = PVector.sub(target, position);
desired.setMag(maxSpeed);
PVector steer = PVector.sub(desired, velocity);
steer.limit(maxForce);
return steer;
}
PVector separate(ArrayList<Node> nodes) {
PVector steer = new PVector(0, 0);
int count = 0;
for (Node other : nodes) {
float d = PVector.dist(position, other.position);
if (d>0 && d < desiredSeparation) {
PVector diff = PVector.sub(position, other.position);
diff.normalize();
diff.div(d); // Weight by distance
steer.add(diff);
count++;
}
}
if (count>0) {
steer.div((float)count);
}
if (steer.mag() > 0) {
steer.setMag(maxSpeed);
steer.sub(velocity);
steer.limit(maxForce);
}
return steer;
}
PVector edgeCohesion (ArrayList<Node> nodes) {
PVector sum = new PVector(0, 0);
int this_index = nodes.indexOf(this);
if (this_index!=0 && this_index!=nodes.size()-1) {
sum.add(nodes.get(this_index-1).position).add(nodes.get(this_index+1).position);
} else if (this_index == 0) {
sum.add(nodes.get(nodes.size()-1).position).add(nodes.get(this_index+1).position);
} else if (this_index == nodes.size()-1) {
sum.add(nodes.get(this_index-1).position).add(nodes.get(0).position);
}
sum.div(2);
return seek(sum);
}
}