2011-01-27 75 views
1

我想畫一個3D Superformula網格,但不知道我應該如何組織這些面(它們是三角形或四邊形)。如何繪製SuperShape3D作爲網格?

我已經安裝了八度並嘗試了示例代碼。我不知道Gnuplot的mesh()函數是如何工作的,但我想我會需要類似的東西。

的維基百科條目有一個鏈接到一個Processing demo。 我看了一下源代碼,發現它只畫出了點。 我試圖在beginShape()/endShape() 調用中包裝該代碼段,但按我希望的方式工作。

我也試圖檢查點的數量是被3個整除 或4,使用三角形或四邊形,但這不是要做到這一點, 正確的方式,你可以看到如下: SuperShape Processing

如何使用三角形/四邊形繪製SuperShape3D? 我想象的頂點是在正確的位置,但他們 需要被分類到該提請使用 頂點索引的面孔電話。

我現在並不是固定在某種特定的語言上,但是我的目標是讓頂點位於數組中,然後使用頂點索引推動面(3或4個點)。

任何提示?

更新:

這裏是用在處理樣品代碼來獲得積分功能:

import toxi.geom.*; 
import controlP5.*; 

ControlP5 controlP5; 
ArrayList points = new ArrayList(); 
ArrayList faces = new ArrayList(); 

float a1=1,a2=1,b=1,xx,step = 0.05,yy,zz,n1=4,n2=12,n3=15,n4=15,r,raux1,r1,raux2,r2; 
int N_X = int(2*PI/step); 
int N_Y = int(PI/step); 


void setup() { 
    size(800,800,P3D); 
    //hint(ENABLE_DEPTH_SORT); 

    controlP5 = new ControlP5(this); 

    controlP5.addSlider("a1value",0,3,1,20,0,200,10); 
    controlP5.addSlider("a2value",0,3,1,20,20,200,10); 
    controlP5.addSlider("bvalue",0,3,1,20,40,200,10); 
    controlP5.addSlider("n1value",0,20,8,20,60,200,10); 
    controlP5.addSlider("n2value",0,5,0.5,20,80,200,10); 
    controlP5.addSlider("n3value",0,5,0.5,20,100,200,10); 
    controlP5.addSlider("n4value",0,20,8,20,120,200,10); 
    controlP5.addSlider("stepvalue",0.02,0.9,0.05,20,140,200,10); 
    controlP5.setAutoDraw(false); 
    draw_super_formula(); 
} 

void draw() { 
    background(0); 
    fill(255); 
    controlP5.draw(); 
    lights(); 
    translate(width/2, height/2, 0); 
    rotateX(mouseY * 0.01f); 
    rotateY(mouseX * 0.01f); 
    // connect 4 points into quads: 
    Vec3D pt; 
    for(int x=0;x<N_X-1;x++) 
    { 
    for(int y=0;y<N_Y-1;y++) 
    { 
     beginShape(QUADS); 
     pt = (Vec3D)points.get(x*N_Y + y); 
     vertex(pt.x,pt.y,pt.z); 
     pt = (Vec3D)points.get(x*N_Y + y+1); 
     vertex(pt.x,pt.y,pt.z); 
     pt = (Vec3D)points.get((x+1)*N_Y + y+1); 
     vertex(pt.x,pt.y,pt.z); 
     pt = (Vec3D)points.get((x+1)*N_Y + y); 
     vertex(pt.x,pt.y,pt.z); 
     endShape(); 
    } 
    } 
} 

void vertex(Vec3D v) { 
    vertex(v.x,v.y,v.z); 
} 

void draw_super_formula() { 
    for(int i = points.size()-1; i>0;i--){ 
    points.remove(i); 
    } 

    for(int x=0;x<N_X;x++) 
    { 
    float i = -PI + x*step; 
    for(int y=0;y<N_Y;y++) 
    { 
     float j = -PI/2.0 + y*step; 
     raux1=pow(abs(1/a1*abs(cos(n1*i/4))),n3)+pow(abs(1/a2*abs(sin(n1*i/4))),n4); 
     r1=pow(abs(raux1),(-1/n2)); 
     raux2=pow(abs(1/a1*abs(cos(n1*j/4))),n3)+pow(abs(1/a2*abs(sin(n1*j/4))),n4); 
     r2=pow(abs(raux2),(-1/n2)); 
     xx=r1*cos(i)*r2*cos(j)*100; 
     yy=r1*sin(i)*r2*cos(j)*100; 
     zz=r2*sin(j)*100; 

     Vec3D test1 = new Vec3D(xx,yy,zz); 
     points.add(test1); 
    } 
    } 
} 

void bvalue(float new_value){ 
    b = new_value; 
    draw_super_formula(); 
} 
void a1value(float new_value){ 
    a1 = new_value; 
    draw_super_formula(); 
} 
void a2value(float new_value){ 
    a2 = new_value; 
    draw_super_formula(); 
} 
void n1value(float new_value){ 
    n1 = new_value; 
    draw_super_formula(); 
} 
void n2value(float new_value){ 
    n2 = new_value; 
    draw_super_formula(); 
} 
void n3value(float new_value){ 
    n3 = new_value; 
    draw_super_formula(); 
} 
void n4value(float new_value){ 
    n4 = new_value; 
    draw_super_formula(); 
} 

void stepvalue(float new_value){ 
    step = new_value; 
    draw_super_formula(); 
    println("% 3: "+(points.size()%3)); 
    println("% 4: "+(points.size()%4)); 
} 
class F4{ 
    int a,b,c,d; 
    F4(int a,int b,int c,int d){ 
    this.a = a; 
    this.b = b; 
    this.c = c; 
    this.d = d; 
    } 
} 

@ tim_hutton的解決方案是偉大的,但它看起來索引斷開,試圖找出在那裏。

superformula issue

回答

1

的超級公式爲您提供採樣每個角半徑。在3D中,你需要兩個角度:theta和phi。通過保持theta固定和變化phi(反之亦然),您將沿着一個大圓圈進行採樣。 (a + b,a + da,b),(a + da,b + db)的四個點取樣製作四邊形的一種方法。 (A,b +分貝)。對a:0,da,2 * da ...和b:0,db,2 * db ...執行此操作,直到覆蓋整個表面。使用小da和db來獲得小四邊形。

(另一種方法是使用一個通用的表面重建算法(12),但是這是矯枉過正了這樣的問題。)

更新:

我認爲下面的代碼是什麼喜歡你想要的:


import toxi.geom.*; 
import controlP5.*; 

ControlP5 controlP5; 
ArrayList points = new ArrayList(); 
ArrayList faces = new ArrayList(); 

float a1=1,a2=1,b=1,xx,step = 0.05,yy,zz,n1=4,n2=12,n3=15,n4=15,r,raux1,r1,raux2,r2; 
int N_X = int(2*PI/step); 
int N_Y = int(PI/step); 


void setup() { 
    size(800,800,P3D); 
    //hint(ENABLE_DEPTH_SORT); 

    controlP5 = new ControlP5(this); 

    controlP5.addSlider("a1value",0,3,1,20,0,200,10); 
    controlP5.addSlider("a2value",0,3,1,20,20,200,10); 
    controlP5.addSlider("bvalue",0,3,1,20,40,200,10); 
    controlP5.addSlider("n1value",0,20,8,20,60,200,10); 
    controlP5.addSlider("n2value",0,5,0.5,20,80,200,10); 
    controlP5.addSlider("n3value",0,5,0.5,20,100,200,10); 
    controlP5.addSlider("n4value",0,20,8,20,120,200,10); 
    controlP5.addSlider("stepvalue",0.02,0.9,0.05,20,140,200,10); 
    controlP5.setAutoDraw(false); 
    draw_super_formula(); 
} 

void draw() { 
    background(0); 
    fill(255); 

    controlP5.draw(); 

    translate(width/2, height/2, 0); 
    rotateX(mouseY * 0.01f); 
    rotateY(mouseX * 0.01f); 
    drawAxes(300); 
    beginShape(POINTS); 
    for(int i = 0; i < points.size();i++){ 
    Vec3D k = (Vec3D)points.get(i); 
    stroke(color(k.x+110,k.y+110,k.z+110)); 
    vertex(k.x,k.y,k.z); 
    } 
    endShape(); 

    // connect 4 points into quads: 
    Vec3D pt; 
    noFill(); 
    for(int x=0;x<N_X-1;x++) 
    { 
    for(int y=0;y<N_Y-1;y++) 
    { 
     beginShape(); 
     pt = (Vec3D)points.get(x*N_Y + y); 
     vertex(pt.x,pt.y,pt.z); 
     pt = (Vec3D)points.get(x*N_Y + y+1); 
     vertex(pt.x,pt.y,pt.z); 
     pt = (Vec3D)points.get((x+1)*N_Y + y+1); 
     vertex(pt.x,pt.y,pt.z); 
     pt = (Vec3D)points.get((x+1)*N_Y + y); 
     vertex(pt.x,pt.y,pt.z); 
     endShape(); 
    } 
    } 
} 

void vertex(Vec3D v) { 
    vertex(v.x,v.y,v.z); 
} 

void draw_super_formula() { 
    for(int i = points.size()-1; i>0;i--){ 
    points.remove(i); 
    } 

    for(int x=0;x<N_X;x++) 
    { 
    float i = -PI + x*step; 
    for(int y=0;y<N_Y;y++) 
    { 
     float j = -PI/2.0 + y*step; 
     raux1=pow(abs(1/a1*abs(cos(n1*i/4))),n3)+pow(abs(1/a2*abs(sin(n1*i/4))),n4); 
     r1=pow(abs(raux1),(-1/n2)); 
     raux2=pow(abs(1/a1*abs(cos(n1*j/4))),n3)+pow(abs(1/a2*abs(sin(n1*j/4))),n4); 
     r2=pow(abs(raux2),(-1/n2)); 
     xx=r1*cos(i)*r2*cos(j)*100; 
     yy=r1*sin(i)*r2*cos(j)*100; 
     zz=r2*sin(j)*100; 

     Vec3D test1 = new Vec3D(xx,yy,zz); 
     points.add(test1); 
    } 
    } 
} 

void drawAxes(float l) { 
    stroke(255, 0, 0); 
    line(0, 0, 0, l, 0, 0); 
    line(l, 0, 0, l-10, 10, 0); 
    line(l, 0, 0, l-10, -10, 0); 

    stroke(0, 255, 0); 
    line(0, 0, 0, 0, l, 0); 
    line(0, l, 0, 10, l-10, 0); 
    line(0, l, 0, -10, l-10, 0); 

    stroke(0, 0, 255); 

    line(0, 0, 0, 0, 0, l); 
    line(0, 0, l, 0, 10, l-10); 
    line(0, 0, l, 0, -10, l-10); 

} 

void bvalue(float new_value){ 
    b = new_value; 
    draw_super_formula(); 
} 
void a1value(float new_value){ 
    a1 = new_value; 
    draw_super_formula(); 
} 
void a2value(float new_value){ 
    a2 = new_value; 
    draw_super_formula(); 
} 
void n1value(float new_value){ 
    n1 = new_value; 
    draw_super_formula(); 
} 
void n2value(float new_value){ 
    n2 = new_value; 
    draw_super_formula(); 
} 
void n3value(float new_value){ 
    n3 = new_value; 
    draw_super_formula(); 
} 
void n4value(float new_value){ 
    n4 = new_value; 
    draw_super_formula(); 
} 

void stepvalue(float new_value){ 
    step = new_value; 
    draw_super_formula(); 
    println("% 3: "+(points.size()%3)); 
    println("% 4: "+(points.size()%4)); 
} 
class F4{ 
    int a,b,c,d; 
    F4(int a,int b,int c,int d){ 
    this.a = a; 
    this.b = b; 
    this.c = c; 
    this.d = d; 
    } 
} 
+0

通過採樣四點製作四邊形的想法聽起來不錯。我很害怕我不完全理解這些觀點。 a,b是兩個角度(wiki樣本中的theta和phi),d是什麼?它是四分之一的第四點嗎?我已經更新了我的問題。 – 2011-01-27 15:37:03