为什么我的循环中的所有向量都在此处理代码中旋转

时间:2016-09-27 15:27:50

标签: processing

我正在构建一个简单代码中的错误。代码从节点增长线。每个节点是两个点和连接两个点的线。每个节点可以增长一次,并且在增长函数中处理增长

节点类的增长函数的一部分具有旋转节点方向的条件(因此线条略微波动)并且由于某种原因所有节点以我编写代码的方式旋转。有人能指出我所犯的毫无疑问的简单错误吗?

代码:

Node[] ns;
int nodeCount;

void setup() {
size(1024, 1024, P3D); 
background(255);
stroke(0);
frameRate(60);
fill(0);
nodeCount = int(10000);
ns = new Node[nodeCount];

for(int i = 0; i < nodeCount; i++){
ns[i] = new Node(i, 0, 0, 0, 0, 0, new PVector(0, 0), false, false, false);
}  

for(int i = 0; i < 1; i++){
ns[i] = new Node(i, random(float(width)), random(float(height)), 5, 0, random(100), new PVector(10, 10).rotate(random(-PI/2, PI/2)), true, false, true);
}
}

void draw() {
background(255);

//print("frame ");
for ( Node n: ns ){

if ( n.Active ) {
//print(n.index, " ");
n.display();
if ( n.Growth ){
n.grow();
}
}
if( n.Init ){
n.init(); 
}

}
}

class Node {
int index;
float xi, yi, size, theta, noiseoff;
PVector dir;
Boolean Active, Growth, Init;
Node(int ind, float x, float y, float s, float t, float n, PVector d, Boolean A, Boolean G, Boolean I) {
index = ind;
xi = x;
yi = y;
size = s;
theta = t;
noiseoff = n;
dir = d;
Active = A;
Growth = G;
Init = I;
}

void display(){

strokeWeight(0);
ellipse(xi, yi, size, size);
ellipse(xi + dir.x, yi + dir.y, size, size);
strokeWeight(size);
line(xi, yi, xi + dir.x, yi + dir.y);

//xi = xi + dir.x;
//yi = yi + dir.y;

}

void grow(){
boolean done = false;
int i = index + 1;
PVector tempDir = new PVector(0, 0);

tempDir = dir;

while ( !done & i < nodeCount & Growth ) {

if ( ns[i].Active == false ) {

if( random(100) > 85 ){
noiseoff += 0.01;
theta = map(noise(noiseoff), 0, 1, -PI/12, PI/12);
tempDir.rotate(theta);
}

ns[i] = new Node(i, xi + tempDir.x, yi + tempDir.y, size, theta, noiseoff, tempDir, true, false, true);
Growth = false;
done = true;
if (i == nodeCount - 1 ) {
 done = true; 
}
}
i++;
if (i == nodeCount ) {
 done = true; 
}
} 
i++;  
}

void init(){
Growth = true;
Init = false;
}
} 

另一个引入createNode()方法的版本,用于删除节点类中节点数组的循环(仍有错误):

Node[] ns;
int nodeCount;


void setup() {
size(1024, 1024, P3D); 
background(255);
stroke(0);
frameRate(60);
fill(0);
nodeCount = int(10000);
ns = new Node[nodeCount];


// Initialize array with blank nodes 
for(int i = 0; i < nodeCount; i++){
ns[i] = new Node(i, 0, 0, 0, 0, 0, new PVector(0, 0), false, false, false);
}  

// Create Root node
createNode(random(float(width)), random(float(height)), 5, 0, random(100), new PVector(2.5, 2.5).rotate(random(-PI/2, PI/2)), true, false, true);

}



void draw() {
background(255);



for ( Node n: ns ){

if ( n.Active ) {
// Draw active nodes
n.display();
// Grow nodes which haven't grown before
if ( n.Growth ){
n.grow();
}
}
// Initialize nodes which were grown last time step (so that they can grown in the subsequent timestep)
if( n.Init ){
n.init(); 
}

}
}


// Wrapper function that looks for a free row in the node array to create a new node
void createNode(float x, float y, float s, float t, float n, PVector d, Boolean A, Boolean G, Boolean I){
float xi, yi, size, theta, noiseoff;
PVector dir;
Boolean Active, Growth, Init, done;
int i;
xi = x;
yi = y;
size = s;
theta = t;
noiseoff = n;
dir = d;
Active = A;
Growth = G;
Init = I;

i = 0;
done = false;

 while ( !done ) {

 if ( ns[i].Active == false ) {
 ns[i] = new Node(i, xi + dir.x, yi + dir.y, size, theta, noiseoff, dir, true, false, true);
 done = true;
 if (i == nodeCount - 1 ) {
  done = true; 
 }
 }
 i++;
 if (i == nodeCount ) {
  done = true; 
 }
 }

}

// Node class
class Node {
int index;
float xi, yi, size, theta, noiseoff;
PVector dir;
Boolean Active, Growth, Init;
Node(int ind, float x, float y, float s, float t, float n, PVector d, Boolean A, Boolean G, Boolean I) {
index = ind;
xi = x;
yi = y;
size = s;
theta = t;
noiseoff = n;
dir = d;
Active = A;
Growth = G;
Init = I;
}


void display(){
// Draw node as two circles and a line
strokeWeight(0);
ellipse(xi, yi, size, size);
ellipse(xi + dir.x, yi + dir.y, size, size);
strokeWeight(size);
line(xi, yi, xi + dir.x, yi + dir.y);

}


// Grow method
void grow(){

int i = index + 1;
PVector tempDir = dir;


// Small chance of angle deviation
if( random(100) > 85 ){
noiseoff += 0.01;
theta = map(noise(noiseoff), 0, 1, -PI/12, PI/12);
tempDir.rotate(theta);
}

// Create new node appended onto the last
createNode(xi + tempDir.x, yi + tempDir.y, size, theta, noiseoff, tempDir, true, false, true);
// Set growth to false to prevent this node growning again
Growth = false;

}

// Initialize previously grown nodes for growth
void init(){
Growth = true;
Init = false;
}

}

2 个答案:

答案 0 :(得分:1)

原来是我生成的一个临时矢量tempDir要旋转(因为.rotate()方法旋转矢量并更改它)稍微不正确。

改变

PVector tempDir = dir;

PVector tempDir = new PVector(dir.x, dir.y);

修正了我的错误,我猜不知道数据分配会不知所措?

答案 1 :(得分:0)

您的Node#grow()函数循环遍历数组中的每个索引,将每个Node替换为自身的旋转版本。

这没有多大意义,因为您已经遍历每个Node并调用grow()函数。因此,对于每个Node,您循环遍历每个Node并将其替换为旋转版本...为什么?

看起来你正在混合应该在每个Node上运行的逻辑与在Node上运行的逻辑。以下是一般的经验法则:您的Node类应该只处理单个Node,因此如果您正在访问ns数组,那么可能会出现一些问题。

(除非您需要每个Node与其他Node进行互动,但这似乎并非如此。)

要解决您的问题,您必须将循环每个Node的逻辑与修改单个Node的逻辑分开。

如果您从一个Node开始,可能会更容易。在您担心多个Node实例之前,让单Node工作。

编辑:您仍然在修改每个Node内部包含Node个实例的数组。这是你困惑的根源。我现在看到你修复了你的问题,但我敢打赌,你会继续遇到类似的问题。

这是我正在研究的例子。这在每个child实例中使用Node变量,而不是尝试将子项存储在存储父Node实例的同一数组中。也许它会派上用场:< / p>

ArrayList<Node> nodes = new ArrayList<Node>();

void setup() {
  size(500, 500);

  for(int i = 0; i < 100; i++){
    nodes.add(new Node());
  }
}

void mousePressed() {
  for ( Node node : nodes ) {
    node.grow();
  }
}

void draw() {
  background(255);

  for ( Node node : nodes ) {
    node.display();
  }
}

class Node {

  float x;
  float y;
  float angle;
  float length;

  Node child;

  Node() {
    x = random(width);
    y = random(height);
    angle = random(360);
    length = random(5, 10);
  }

  void display() {
    float endX = x + cos(radians(angle)) * length;
    float endY = y + sin(radians(angle)) * length;

    line(x, y, endX, endY);

    if (child != null) {
      child.display();
    }
  }

  void grow() {
    if (child == null) {
      float endX = x + cos(radians(angle)) * length;
      float endY = y + sin(radians(angle)) * length;

      child = new Node();
      child.x = endX;
      child.y = endY;
      child.angle = random(angle-10, angle+10);
    } else {
      child.grow();
    }
  }
}

growing nodes