0
votes

So I currently have a cubic bezier patch on the XZ plane (y = 0, so it is a flat patch). The patch is made up of 16 control points and 400 total grid points. What I am trying to currently implement is to select 1 of the middle 4 control points (any of them), and increment in any coordinate direction.

I think I that the part I am having trouble with is actually displaying the changes with OpenGL drawing functions. Below is the code for creating the patch and my current drawing function as well as a sample of the increment function I'm currently using.

Grid is a 2d array of all of the grid points. Control is a 2d array of the 16 control points. control_point is changed by a menu function that the user picks (options 1-4) and is initialized to 1.

Edit: Fixed last 2 control points in switch statement.

void bezier_plane()
{
    CalcBezier();
    for (int i = 0; i < 19; i++) {
        for (int j = 0; j < 19; j++) {
            glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
            glBegin(GL_TRIANGLE_STRIP);
                glVertex3f(grid[i][j].x, grid[i][j].y, grid[i][j].z);
                glVertex3f(grid[i][j+1].x, grid[i][j+1].y, grid[i][j+1].z);
                glVertex3f(grid[i+1][j].x, grid[i+1][j].y, grid[i+1][j].z);
                glVertex3f(grid[i+1][j+1].x, grid[i+1][j+1].y, grid[i+1][j+1].z);
            glEnd();
        }
    }
}

void CalcBezier()
{
    float u;
    float v;
    u = 0;
    for (int i = 0; i < 20; i++) {
        v = 0;
        for (int j = 0; j < 20; j++) {
            for (int x = 0; x < 4; x++) {
                for (int y = 0; y < 4; y++) {
                    grid[i][j].x += control[x][y].x * Bezier3(x, u) * Bezier3(y, v);
                    grid[i][j].y += control[x][y].y * Bezier3(x, u) * Bezier3(y, v);
                    grid[i][j].z += control[x][y].z * Bezier3(x, u) * Bezier3(y, v);
                }
            }
            v+=.05;
        }
        u+=.05;
    }
}

/*Is called when a menu button is hit, indicating that the control point is incremented in the y direction*/
void OnYInc()
{
    switch(control_point) {
    case 1:
        control[1][1].y += 2;
        break;
    case 2:
        control[1][2].y += 2;
        break;
    case 3:
        control[2][3].y += 2;
        break;
    case 4:
        control[2][4].y += 2;
        break;
    }
    InvalidateRect(NULL, FALSE);
}

My onDraw function simply calls bezier_plane() as well. Right now, with the above code, when I try to increment in terms of y. The triangles in the mesh simply get bigger, but it does not seem to draw it correctly at all. It is a little hard to describe.

Result looks like this. First screenshot is before I have hit increment. Second screenshot and third screenshot is what it looks like after 1 click and then after 10 clicks. I'm also not quite sure why the range of the patch is actually changing when I increment in the y direction (it seems to get bigger as I keep incrementing y).

before increment

after 1 click

after 10 clicks

1
Take a couple screenshots if it's hard to describe.RandyGaul
Do you set the elements of grid to zero before calling CalcBezier() each time?radical7
No. Grid is initially set to 0 and then does not change unless altered in calcbezierKinru
Would adding my onDraw function provide any useful information? I don't want to put unnecessary code in my post. Would make it hard to read.Kinru
that switch is bad. it should be something like control[(control_point - 1) / 2 + 1][control_point].y += 2;Abyx

1 Answers

2
votes

radical7 has solved it for you. Because you don't set grid to zero before calling CalcBezier, every time CalcBezier is called all the grid values are incremented. Changed OnYInc to leave the control points alone and just InvalidateRect and you will see the same behaviour