2016-09-27 1 views
0

ビルドしている簡単なコードにバグがあります。コードはノードから線を伸ばします。各ノードは2つの点とその2つを結ぶ線です。各ノードは1回成長でき、成長は成長関数で処理されますループ内のすべてのベクトルがこの処理コード内で回転するのはなぜですか?

ノードクラスの成長関数の一部には、ノードの方向を回転させる条件があります(何らかの理由ですべてのノードはコードを書いたやり方で回転します。誰かが私が作った間違いなく単純なエラーを指摘できますか?

コード:

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; 
} 

} 
+0

これらのノードの動作を正確に把握できますか?彼らはどのように接続する必要がありますか? –

+0

確かに、ノードは大きさ(この段階では定数)と方向(この段階ではランダム)で「生まれ」ます。ノードは2つの円として表示され、その2つをベクトルの方向/ magに結ぶ線が表示されます。 ノードは一度「成長」することができます。元のノードにわずかにランダムなオフセット角度を持つ新しいノードを追加する必要があります。ノードが大きくなると、それは決してそのプロパティを変更するべきではありません – niklz

答えて

0

あなたNode#grow()機能配列内のすべてのインデックスをループし、各Nodeをそれ自身の回転バージョンに置き換えます。

Nodeをすべてループしており、grow()という機能を呼び出しているため、これは意味がありません。したがって、Nodeごとに、Nodeごとにループし、回転バージョンに置き換えます...なぜですか?

Nodeのロジックが1つのNodeで動作するロジックを混在しているようです。一般的な経験則は、NodeクラスはNodeの1つしか扱わないので、ns配列にアクセスしている場合、何か不思議です。

(あなたが他のすべてのNodeと対話するために、各Nodeが必要ですが、それはここではケースのように思われない場合を除きます。)

あなたの問題を解決するために、あなたはすべてのNodeをループロジックを分離する必要があります1つを変更するロジックからNode

最初にNodeで始めると楽になるかもしれません。複数のNodeインスタンスについて心配する前にその単一のNodeを稼働させてください。

編集:NodeのインスタンスをすべてNodeの内部から保持する配列は依然として変更しています。それがあなたの混乱の原因です。私はあなたの問題を修正したことを確認しましたが、今後も同様の問題が生じるでしょう。

ここでは私が取り組んでいる例を示します。これは、代わりに親Nodeインスタンスが中に保存されているのと同じ配列に子供を保存しようとしているの各Nodeインスタンスでchild変数を使用して多分それは便利になるでしょう:。

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

+0

grow関数のwhileループは実際にループしてノード配列の空の要素を見つけます。ノードの 'Active'、 'Init' and 'Growth' varはtrueに設定されています。 私はあなたが正しいと確信していますが、どういうわけかこのロジックは機能していません。どのように他のデータ(ノードの展開リスト)を扱うのか分かりません。 – niklz

+0

@niklz基本的な教訓はこれです:ノードが相互作用するコードがなければ、他のすべての 'Node' 'Node'クラスの内部にあります。最初からやり直して一つの 'Node'を動かしてからコードを投稿すればそこから行くでしょう。 –

+0

n.grow()の呼び出しをコメントアウトすると、動作する単一ノードのバージョンになります(コードは1つのノードでは無意味ですが、最も基本的な操作で1つのノードを拡張する必要があります)。 私は、ノード上のループを行う新しい関数 'createNode()'にデータ処理部分を移動しようとします(しかし、これはまだあなたのテストに失敗します)。 – niklz

1

ターンそれが私の世代の一時的なベクトルtempDir(回転()メソッドはベクトルを回転させ、それを変更するため)が若干不正確になっていました。

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

は私のバグを修正しました

PVector tempDir = dir; 

を変え、私は何とかデータの割り当てが混乱していることを推測しますか?

+0

それを理解する上でうまくやっています。 '' 'PVector tempDir = dir;' ''はそのベクトルへの参照をコピーするので、独立したPVectorではありません...同じオブジェクトを指す別の変数です。 '' 'PVector tempDir = new PVector(dir.x、dir.y);' 'は' 'PVector tempDir = dir.get();' 'と書くこともできます。コピーされたx、y値で) –

関連する問題