Суперформула дает вам радиус для каждого выбранного угла. В 3D вам нужны два угла: тэта и фи. Сохраняя тэту фиксированной и изменяющейся фи (или наоборот), вы будете пробовать большой круг.
Одним из способов создания поверхности является создание четырехугольников путем выборки четырех точек на основе углов a и b: (a, b), (a + da, b), (a + da, b + db), ( а, Ь + дБ). Делайте это для a: 0, da, 2 * da ... и для b: 0, db, 2 * db ..., пока вся поверхность не будет покрыта. Используйте маленький da и db, чтобы получить маленькие квадраты.
(Альтернативой является использование общего алгоритма восстановления поверхности ( 1 , 2 ), но для такой проблемы это излишне.)
Обновление:
Я думаю, что код ниже что-то вроде того, что вы хотите:
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;
}
}