2014-03-01 65 views
1

我遇到了我正在製作的動畫的問題。主要思想是6個等邊三角形圍繞一箇中心點旋轉,同時也圍繞自己旋轉。處理中的嵌套問題

當我運行代碼時,三角形的每個實例都使用先前的實例作爲參考點,而不是中心。這會導致一個很酷的螺旋效應,但這不是我所追求的。

代碼如下:

//Declare 
tri myTri1; 
tri myTri2; 
tri myTri3; 
tri myTri4; 
tri myTri5; 
tri myTri6; 

void setup() { 
    size(600, 600); 
    smooth(); 

    //Initialise 
    myTri1 = new tri(); 
    myTri2 = new tri(); 
    myTri3 = new tri(); 
    myTri4 = new tri(); 
    myTri5 = new tri(); 
    myTri6 = new tri(); 
} 

void draw() { 
    background(0); 

    //Call Functions 
    myTri1.run(); 
    translate(width/2,height/2); 
    rotate(PI/3); 
    translate(-width/2,-height/2); 
    myTri2.run(); 
    translate(width/2,height/2); 
    rotate(PI/3); 
    translate(-width/2,-height/2); 
    myTri3.run(); 
    translate(width/2,height/2); 
    rotate(PI/3); 
    translate(-width/2,-height/2); 
    myTri4.run(); 
    translate(width/2,height/2); 
    rotate(PI/3); 
    translate(-width/2,-height/2); 
    myTri5.run(); 
    translate(width/2,height/2); 
    rotate(PI/3); 
    translate(-width/2,-height/2); 
    myTri6.run(); 
} 

第二個選項卡:

class tri { 
    //Variables 
    float ax, ay, bx, by, cx, cy; //triangle point coordinates 
    float theta; //triangle angle 
    float pi = PI; //pi reference 

    //Construct 
    tri() { 
    theta = PI/6; 
    ax = 0; 
    ay = 0; 
    bx = -50*(sin(theta)); 
    by = +50*(cos(theta)); 
    cx = +50*(sin(theta)); 
    cy = +50*(cos(theta)); 
    } 

    //Functions 
    void run() { 

    translate(width/2, height/2); 
    revolve(); //revolve triangle about centre 
    spin(); //spin triangle about itself 
    pulse(); //move triangle in/out 
    display(); //show triangle 
    translate(-width/2, -height/2); 
    } 

    void spin() { 
    translate(0, by/2); //sets rotation axis to centre of triangle 
    rotate(millis()*-0.0005*pi); 
    translate(0, -by/2); //resets axis to centre of window 
    } 

    void revolve() { 
    translate(-2*by, 0); 
    ax = ax + 2*sin(millis()*0.005); 
    ay = ay + 4*cos(millis()*0.005); 
    bx = bx + 2*sin(millis()*0.005); 
    by = by + 4*cos(millis()*0.005); 
    cx = cx + 2*sin(millis()*0.005); 
    cy = cy + 4*cos(millis()*0.005); 
    translate(2*by, 0); 
    } 

    void pulse() { 
    ay = ay + 5*sin(millis()*0.005); 
    by = by + 5*sin(millis()*0.005); 
    cy = cy + 5*sin(millis()*0.005); 
    } 

    void display() { 
    fill(255); 
    strokeWeight(0.8); 
    triangle(ax, ay, bx, by, cx, cy); 
    } 
} 

如果任何人都可以指出在那裏我這個腳麻這將是真棒,如果你能提出任何的優化RE六角形的形成(而不是翻譯的混亂)我會非常高興。

+0

什麼是翻譯應該做的? – Franchesca

+0

Translate將原點(0,0)重置爲您指定的座標。 這裏http://processing.org/reference/ – BenjiHare

+1

所有命令的描述(不同程度的細節)嘗試在你的起源的起點上渲染一個小點,因爲我不認爲翻譯回到你認爲的地方是。不能檢查自己,因爲我不能運行它:) – Franchesca

回答

1

Franchesca的建議很好。你應該知道原點在哪裏以及你應用的座標空間轉換如何影響,至少在你感覺到它並且完全控制之前。

我還熱情推薦這款Processing tutorial on 2d transformations

現在,回到你的代碼:)

可以提高第一件事就是習慣的循環和數組。 他們一開始可能看起來很可怕,但一旦你掌握了它們,他們很容易。 無論您想到需要重複的情況,您都可以使用for循環讓您的生活更輕鬆。 在你的情況下,生成三角形並存儲它們可以使用循環和數組完成。

For循環的語法如下:

for keyword (3 elements: a start point,an end point(condition) and an increment,(separated by the ; character) 

比方說,你想從(0)到B(10),一步一次移動:

for(int currentPos = 0 ; currentPos < 10; currentPos++){ 
    println("step: " + currentPos); 
} 

如果可以的話走,你也可以跳過:)

for(int currentPos = 0 ; currentPos < 10; currentPos+=2){ 
    println("step: " + currentPos); 
} 

甚至倒退,如果你想:

for(int currentPos = 10 ; currentPos > 0; currentPos--){ 
    println("step: " + currentPos); 
} 

(三角形三角形的場景,頂點等)遍歷當所有類型的數據

你如何組織你的數據,這是非常有用嗎?你把它放在一個列表或數組中。 數組包含相同類型的元素並具有設定的長度。 聲明數組的語法如下:

ObjectType[] nameOfArray; 

,你可以初始化一個空數組:

int[] fiveNumbers = new int[5];//new keyword then the data type and length in sq.brackets 

,或者您可以初始化值的數組:

String[] words = {"ini","mini","miny","moe"}; 

你使用方括號訪問數組中的元素以及要訪問的列表中對象的索引。數組具有長度屬性,因此您可以輕鬆地對對象進行計數。

background(255); 
String[] words = {"ini","mini","miny","moe"}; 
for(int i = 0 ; i < words.length; i++){ 
    fill(map(i,0,words.length, 0,255)); 
    text(words[i],10,10*(i+1)); 
} 

回到原來的問題。 下面是使用循環和數組簡化您的主要代碼:

//Declare 
int numTri = 6;//number of triangles 
tri[] triangles = new tri[numTri];//a list/an array of tri objects (currently empty) 
float angleIncrement = TWO_PI/numTri; 
float radius = 100; 
void setup() { 
    size(600, 600); 
    smooth(); 

    //Initialise 
    for(int i = 0 ; i < numTri; i++){ 
    triangles[i] = new tri();//allocate/initialise each tri object into it's 'slot' in the list/array 
    } 
} 

void draw() { 
    background(0); 
    translate(width * .5, height * .5);//move everything to the centre 
    for(int i = 0 ; i < numTri; i++){ 
    pushMatrix(); 
     rotate(angleIncrement * i);//rotate from the last offset(centre) 
     translate(radius,0);//move on (rotated) X axis away from the centre 
     triangles[i].run(); 
    popMatrix(); 
    } 
} 
void drawAxes(int size){ 
    pushStyle(); 
    stroke(255,0,0); 
    line(0,0,size,0); 
    stroke(0,255,0); 
    line(0,0,0,size); 
    popStyle(); 
} 

通知我縮進內push/pop matrix調用的代碼。 這不是必要的,但我補充說,所以你可以感受到座標空間如何嵌套。 這些調用非常有用,因爲它們處理幕後的基本數學部分。注意我是如何將符號放在一個圓圈中而不使用極座標到笛卡爾座標轉換公式(cos(angle)* radius,sin(angle)* radius)。

您可以測試這個代碼與其他標籤:

class tri { 
    //Variables 
    float ax, ay, bx, by, cx, cy; //triangle point coordinates 
    float theta; //triangle angle 
    float pi = PI; //pi reference 

    //Construct 
    tri() { 
    theta = PI/6; 
    ax = 0; 
    ay = 0; 
    bx = -50*(sin(theta)); 
    by = +50*(cos(theta)); 
    cx = +50*(sin(theta)); 
    cy = +50*(cos(theta)); 
    } 

    //Functions 
    void run() { 
    pushMatrix(); 
    revolve(); //revolve triangle about centre 
// pulse(); //move triangle in/out 
    display(); //show triangle 
    popMatrix(); 
    } 

    void revolve() { 
    translate(-2*by, 0); 
    float angle = millis()*0.005; 
    float cos = cos(angle); 
    float sin = sin(angle); 
    ax = ax + 2*sin; 
    ay = ay + 4*cos; 
    bx = bx + 2*sin; 
    by = by + 4*cos; 
    cx = cx + 2*sin; 
    cy = cy + 4*cos; 
    translate(2*by, 0); 
    } 

    void pulse() { 
    ay = ay + 5*sin(millis()*0.005); 
    by = by + 5*sin(millis()*0.005); 
    cy = cy + 5*sin(millis()*0.005); 
    } 

    void display() { 
    fill(255); 
    strokeWeight(0.8); 
    triangle(ax, ay, bx, by, cx, cy); 
    } 
} 

還要注意我添加了一個drawAxes功能。這只是一個實用工具,可以讓您更容易理解您的繪圖的座標空間。

再次,要回陣列和for循環,這裏是你的代碼的修改版本:

class tri { 
    //Variables 
    float ai = TWO_PI/3;//angle increment 
    float r = 50; 
    float sr = r * 1.5;//spin radius 
    float vt = 5;//vertical translation(for pulse) 
    PVector[] verts = new PVector[3]; 

    boolean rotateAroundCentre = true; 
    boolean translateAroundCentre = false; 
    boolean translateVertically = false; 
    //Construct 
    tri() { 
    for(int i = 0 ; i < 3; i++){ 
     verts[i] = new PVector(cos(ai * i) * r,sin(ai * i) * r); 
    } 
    } 

    //Functions 
    void run() { 
    pushMatrix(); 
     float angle = millis()*0.0005; 
     if(rotateAroundCentre) rotate(angle); 
     if(translateVertically) translate(sin(angle)*vt,0); 
     if(translateAroundCentre){ 
//  translate(cos(angle) * sr,sin(angle) * r); 
//  or   
      rotate(angle); 
      translate(sr,0); 
     } 
    display(); //show triangle 
    popMatrix(); 
    } 
    void display() { 
    fill(255); 
    strokeWeight(0.8); 
    triangle(verts[0].x, verts[0].y, verts[1].x, verts[1].y, verts[2].x, verts[2].y); 
    drawAxes(10); 
    } 
} 

隨意與布爾rotateAroundCentre,translateAroundCentre,translateVertically變量發揮和有樂趣的座標和幾何形狀彈:)

例如,以下是草圖的版本,您可以切換上述使用鍵盤上的按鍵1/2/3的3個選項:

//Declare 
int numTri = 6;//number of triangles 
tri[] triangles = new tri[numTri];//a list/an array of tri objects (currently empty) 
float angleIncrement = TWO_PI/numTri; 
float radius = 100; 
boolean[] options = {false,false,false}; 
void setup() { 
    size(600, 600); 
    smooth(); 

    //Initialise 
    for(int i = 0 ; i < numTri; i++){ 
    triangles[i] = new tri();//allocate/initialise each tri object into it's 'slot' in the list/array 
    } 
} 

void draw() { 
    background(0); 
    translate(width * .5, height * .5);//move everything to the centre 
    for(int i = 0 ; i < numTri; i++){ 
    pushMatrix(); 
     rotate(angleIncrement * i);//rotate from the last offset(centre) 
     translate(radius,0);//move on (rotated) X axis away from the centre 
     drawAxes(20); 
     triangles[i].run(); 
    popMatrix(); 
    } 
} 
void drawAxes(int size){ 
    pushStyle(); 
    stroke(255,0,0); 
    line(0,0,size,0); 
    stroke(0,255,0); 
    line(0,0,0,size); 
    popStyle(); 
} 
void keyReleased(){ 
    for(int i = 0 ; i < 3; i++) if(key == (49+i)) options[i] = !options[i];//quick'n'dirty option toggling 
    for(int i = 0; i < numTri; i++) { 
    triangles[i].rotateAroundCentre = options[0]; 
    triangles[i].translateAroundCentre = options[1]; 
    triangles[i].translateVertically = options[2]; 
    } 
} 
class tri { 
    //Variables 
    float ai = TWO_PI/3;//angle increment 
    float r = 50; 
    float sr = r * 1.5;//spin radius 
    float vt = 5;//vertical translation(for pulse) 
    PVector[] verts = new PVector[3]; 

    boolean rotateAroundCentre = false; 
    boolean translateAroundCentre = false; 
    boolean translateVertically = false; 
    //Construct 
    tri() { 
    for(int i = 0 ; i < 3; i++){ 
     verts[i] = new PVector(cos(ai * i) * r,sin(ai * i) * r); 
    } 
    } 

    //Functions 
    void run() { 
    pushMatrix(); 
     float angle = millis()*0.0005; 
     if(rotateAroundCentre) rotate(angle); 
     drawAxes(30); 

     if(translateVertically) translate(sin(angle)*vt,0); 
     drawAxes(40); 

     if(translateAroundCentre){ 
//  translate(cos(angle) * sr,sin(angle) * r); 
//  or   
      rotate(angle); 
      drawAxes(40); 

      translate(sr,0); 
     } 
    display(); //show triangle 
    popMatrix(); 
    } 
    void display() { 
    fill(255); 
    strokeWeight(0.8); 
    triangle(verts[0].x, verts[0].y, verts[1].x, verts[1].y, verts[2].x, verts[2].y); 
    drawAxes(10); 
    } 
} 
+0

你的解釋真的比我見過的教程更有幫助,非常感謝: ) – BenjiHare