2011-01-27 78 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