Carven
Carven

Reputation: 15660

How to construct polygons from explicit equations?

Suppose I have an explicit equation that could represent an object shape in OpenGL, how should I sort of "plot" out the shape from the explicit equation?

For example, I have this explicit equation: enter image description here

Both u and v are members of the real numbers.

I then tried to do this in OpenGL C++:

float maxParts = 20;

vector<float> point(3);

glBegin(GL_QUAD_STRIP);
for(int i=0; i<=maxParts; i++) {
    float u = ((float)i/maxParts)*2*M_PI;
    for(int j=-maxParts; j<=maxParts; j++) {
        float v = (j/maxParts) * M_PI;
        point[0] = cos(u) * (4.0+3.8*cos(v));
        point[1] = sin(u) * (4.0+3.8*cos(v));
        point[2] = (cos(v) + sin(v) - 1.0) * (1.0 + sin(v)) * log(1.0-M_PI*v/10.0) + 7.5 * sin(v);
        glVertex3f(point[0], point[1], point[2]);
    }
}
glEnd();

But it turns out to be just really crappy. The above code somewhat gives a slight impression of the shape but the polygons are not rendered properly. How should I iterate through the explicit equation for the x, y and z coordinates to construct the shape from the equation?

Upvotes: 2

Views: 216

Answers (1)

datenwolf
datenwolf

Reputation: 162299

You're generally going into the right direction. However you missed the crucial step, that you'll have to split down the patch into smaller quads (tesselate it). So you don't just iterate over the sampling points, you iterate over the patches and must generate 4 sampling points for each patch.

Also you need to supply the vertex normals. The vertex normals are given by taking the cross product of the vectors δ{x,y,z}/δu and δ{x,y,z}/δv

EDIT due to comment

Code example for emitting independent quads:

const int patches_x, patches_y;
const float patch_size_x, patch_size_y;
int px, py;
for(px = 0; px < patches_x; px++) for(py = 0; py < patches_y; py++) {
    const float U = px * patch_size_x;
    const float V = py * patch_size_y;
    {
        float u, v;
        u = U - patch_size_x/2.0;
        v = V - patch_size_y/2.0;
        emit_quad_vertex(u, v);
    }
    {
        float u, v;
        u = U + patch_size_x/2.0;
        v = V - patch_size_y/2.0;
        emit_quad_vertex(u, v);
    }
    {
        float u, v;
        u = U + patch_size_x/2.0;
        v = V + patch_size_y/2.0;
        emit_quad_vertex(u, v);
    }
    {
        float u, v;
        u = U - patch_size_x/2.0;
        v = V + patch_size_y/2.0;
        emit_quad_vertex(u, v);
    }
}

Upvotes: 4

Related Questions