|
Explicit Representation
z = g ( x )
Examples:
2-D line: y = m.x + b
2-D circle: y = ( r2 - x2 ) 1/2 0 ≤ |x| < r
e.g. a spherical surface: z = ( r2 - x2 - y2 ) 1/2
Implicit Representation
Examples:
2-D line: a.x + b.y + c = 0
2-D circle: x2 + y2 - r2 = 0
e.g. a plane: a.x + b.y + c.z + d = 0
e.g. a spherical surface: x2 + y2 + z2 - r2 = 0
f( x, y, z ) = 0
g( x, y, z ) = 0
Algebraic surfaces are those for which f( x, y, z ) is the sum of polynomials in the three variables. Of particular importance are the quadratic surface where each term in f can have degree up to 2 ( e.g. x, xy, or z2 but not xy2 ).
Parametric form
expresses the value of each spatial variable for points in terms of an independent variable, u, the parameter.
x = x(u),
y = y(u),
z = z(u).
A useful interpretation of the parametric form is to visualize the locus of points
requires two parameters
x = x ( u, v )
y = y ( u, v )
z = z ( u, v )
Parametric Polynomial Curves
| p(u) | = |
|
x(u) y(u) z(u) |
|
A polynomial parmetric curve of degree n ( order in OpenGL ) is of the form
| p(u) | = |
![]() k = 0 |
ukck |
| ck | = |
|
ckx cky ckz |
|
Parametric Polynomial Surfaces
| p(u, v) | = |
|
x(u,v) y(u,v) z(u,v) |
|
= |
![]() i=0 |
![]() j=0 |
cij ui vj |
Why
Parametric Cubic Polynomial Curves
| p(u) | = |
![]() k = 0 |
ck uk | = | c0 + c1 u + c2 u2 + c3 u3 | = | uTc |
where
|
|
|
The design of a particular type of cubic will be based on data given at some values of parameter.
Need
Cubic Interpolating Polynomial
| Pk | = | ![]() |
xk yk zk |
![]() |
| P0 | = | p( 0 ) | = | c0 |
| P1 | = | p(1/3 ) | = | c0 + (1/3)c1 + (1/3)2c2 + (1/3)3c3 |
| P2 | = | p(2/3 ) | = | c0 + (2/3)c1 + (2/3)2c2 + (2/3)3c3 |
| P3 | = | p(1 ) | = | c0 + c1 + c2 + c3 |
Or in matrix form
|
|
and
| A = | ![]() |
|
![]() |
The desired coefficients are found by
C = A-1P
( Note in our derivation, Pi can be substituted by xi or yi or zi )
| Bi | = | ( | 3 i |
) | ui | ( 1 - u )3-i | are the Bernstein coefficients. |
| ( | n m |
) | = |
m!(n - m)! |
| B0(u) = (1 -u)3 | B2(u) = 3u2(1 -u) | |
| B1(u) = 3u(1 -u)2 | B3(u) = u3 |
i = 0 |
Bi(u) | = |
i = 0 |
( | 3 i |
) | ui(1 - u)3-i | = | [u + (1 - u)]3 | = | 1 |
Also,
p(0) = P0, p(1) = P3
We can also express p(u) as
Or in matrix form
| p(u) = | ( 1, u, u2, u3 ) | ![]() |
1 -3 3 -1 |
0 3 -6 3 |
0 0 3 -3 |
0 0 0 1 |
![]() |
![]() |
P0 P1 P2 P3 |
![]() |
Thus
p'(0) = 3(P1 - P0 ) p'(1) = 3(P3 - P2 )
Evaluators
One-dimensional Evaluators
Example: A simple Bezier curve
|
|
| p(u, v ) | = |
i = 0 |
j = 0 |
Bi(u) | Bj(v) | Pi,j |
![]() |
![]() Lit, shaded Bezier Surface Draw with mesh |
/* bezsurf.c
* This program renders a wireframe Bezier surface,
* using two-dimensional evaluators.
*/
#include <GL/glut.h>
#include <stdlib.h>
GLfloat ctrlpoints[4][4][3] = {
{{-1.5, -1.5, 4.0}, {-0.5, -1.5, 2.0},
{0.5, -1.5, -1.0}, {1.5, -1.5, 2.0}},
{{-1.5, -0.5, 1.0}, {-0.5, -0.5, 3.0},
{0.5, -0.5, 0.0}, {1.5, -0.5, -1.0}},
{{-1.5, 0.5, 4.0}, {-0.5, 0.5, 0.0},
{0.5, 0.5, 3.0}, {1.5, 0.5, 4.0}},
{{-1.5, 1.5, -2.0}, {-0.5, 1.5, -2.0},
{0.5, 1.5, 0.0}, {1.5, 1.5, -1.0}}
};
void display(void)
{
int i, j;
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glColor3f(1.0, 1.0, 1.0);
glPushMatrix ();
glRotatef(85.0, 1.0, 1.0, 1.0);
for (j = 0; j <= 8; j++) {
glBegin(GL_LINE_STRIP);
for (i = 0; i <= 30; i++)
glEvalCoord2f((GLfloat)i/30.0, (GLfloat)j/8.0);
glEnd();
glBegin(GL_LINE_STRIP);
for (i = 0; i <= 30; i++)
glEvalCoord2f((GLfloat)j/8.0, (GLfloat)i/30.0);
glEnd();
}
glPopMatrix ();
glFlush();
}
void init(void)
{
glClearColor (0.0, 0.0, 0.0, 0.0);
/*
GL_MAP1_VERTEX_3 -- specifies that 3-dimensional control points are
provided and 3-D vertices should be produced
0 -- min u
1 -- max u
3 -- ustride, number of values to advance in the data between two
consecutive control points ( see diagram below )
4 -- order of u ( = degree + 1 )
0 -- min v
1 -- max v
12 -- vstride ( see diagram below )
4 -- order of v ( = degree + 1 )
*/
glMap2f(GL_MAP2_VERTEX_3, 0, 1, 3, 4,
0, 1, 12, 4, &ctrlpoints[0][0][0]);
glEnable(GL_MAP2_VERTEX_3);
/*
glMapGrid2f() -- defines a grid going from u1 to u2; v1 to v2 in
evenly-spaced steps
20 -- number of u steps
0.0 -- u1 ( starting u )
1.0 -- u2 ( ending u )
20 -- number of v steps
0.0 -- v1 ( starting v )
1.0 -- v2 ( ending v )
*/
glMapGrid2f(20, 0.0, 1.0, 20, 0.0, 1.0);
glEnable(GL_DEPTH_TEST);
glShadeModel(GL_FLAT);
}
void reshape(int w, int h)
{
glViewport(0, 0, (GLsizei) w, (GLsizei) h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
if (w <= h)
glOrtho(-4.0, 4.0, -4.0*(GLfloat)h/(GLfloat)w,
4.0*(GLfloat)h/(GLfloat)w, -4.0, 4.0);
else
glOrtho(-4.0*(GLfloat)w/(GLfloat)h,
4.0*(GLfloat)w/(GLfloat)h, -4.0, 4.0, -4.0, 4.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
void keyboard(unsigned char key, int x, int y)
{
switch (key) {
case 27:
exit(0);
break;
}
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize (500, 500);
glutInitWindowPosition (100, 100);
glutCreateWindow (argv[0]);
init ();
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutKeyboardFunc(keyboard);
glutMainLoop();
return 0;
}
|
Each control point is 3-D ( has 3 values ). So ustride = 3, vstride = 3 x 4 = 12
| u → | |||||||||||||||||
| v ↓ |
|
/* bezmesh.c
* This program renders a lighted, filled Bezier surface,
* using two-dimensional evaluators.
*/
#include <stdlib.h>
#include <GL/glut.h>
GLfloat ctrlpoints[4][4][3] = {
{ {-1.5, -1.5, 4.0},
{-0.5, -1.5, 2.0},
{0.5, -1.5, -1.0},
{1.5, -1.5, 2.0}},
{ {-1.5, -0.5, 1.0},
{-0.5, -0.5, 3.0},
{0.5, -0.5, 0.0},
{1.5, -0.5, -1.0}},
{ {-1.5, 0.5, 4.0},
{-0.5, 0.5, 0.0},
{0.5, 0.5, 3.0},
{1.5, 0.5, 4.0}},
{ {-1.5, 1.5, -2.0},
{-0.5, 1.5, -2.0},
{0.5, 1.5, 0.0},
{1.5, 1.5, -1.0}}
};
void initlights(void)
{
GLfloat ambient[] = {0.2, 0.2, 0.2, 1.0};
GLfloat position[] = {0.0, 0.0, 2.0, 1.0};
GLfloat mat_diffuse[] = {0.6, 0.6, 0.6, 1.0};
GLfloat mat_specular[] = {1.0, 1.0, 1.0, 1.0};
GLfloat mat_shininess[] = {50.0};
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glLightfv(GL_LIGHT0, GL_AMBIENT, ambient);
glLightfv(GL_LIGHT0, GL_POSITION, position);
glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);
}
void display(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushMatrix();
glRotatef(85.0, 1.0, 1.0, 1.0);
glEvalMesh2(GL_FILL, 0, 20, 0, 20);
glPopMatrix();
glFlush();
}
void init(void)
{
glClearColor(0.0, 0.0, 0.0, 0.0);
glEnable(GL_DEPTH_TEST);
glMap2f(GL_MAP2_VERTEX_3, 0, 1, 3, 4,
0, 1, 12, 4, &ctrlpoints[0][0][0]);
glEnable(GL_MAP2_VERTEX_3);
glEnable(GL_AUTO_NORMAL);
glMapGrid2f(20, 0.0, 1.0, 20, 0.0, 1.0);
initlights(); /* for lighted version only */
}
void reshape(int w, int h)
{
glViewport(0, 0, (GLsizei) w, (GLsizei) h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
if (w <= h)
glOrtho(-4.0, 4.0, -4.0*(GLfloat)h/(GLfloat)w,
4.0*(GLfloat)h/(GLfloat)w, -4.0, 4.0);
else
glOrtho(-4.0*(GLfloat)w/(GLfloat)h,
4.0*(GLfloat)w/(GLfloat)h, -4.0, 4.0, -4.0, 4.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
void keyboard(unsigned char key, int x, int y)
{
switch (key) {
case 27:
exit(0);
break;
}
}
int main(int argc, char **argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize (500, 500);
glutInitWindowPosition (100, 100);
glutCreateWindow(argv[0]);
init();
glutReshapeFunc(reshape);
glutDisplayFunc(display);
glutKeyboardFunc(keyboard);
glutMainLoop();
return 0;
}
|
Powerful tool for generating curves with many control points. B stands for "Basis"
Advantages
Uniform B-Splines of Degree Three
| q(u) = | n![]() i=0 |
Ni(u).Pi | 3 ≤ u ≤ n + 1 |
where P0, ..., Pn are the control points, N0(u), ..., Nn(u) are the blending ( or basis ) functions
| q(u) = | j![]() i=j-3 |
Ni(u).Pi | u ∈ [j, j+1], 3 ≤ j ≤ n |
When a single control point pi is moved, only the portion of the curve q(u) with i < u < i + 4 is changed --> local control
The blending functions have the following properties:
Ni(u) = 1
Non Uniform Rational B-Splines ( NURB )
Degree m B-Splines
| q(u) = | n![]() i=0 |
Ni,m(u).Pi |
where P0, ..., Pn are the control points. ( for uniform B-splines, u0 = 0, u1 = 1, ... )
The B-spline blending function is given by
| Ni,m(u) = | |
u - ui
------------ ui+m-1 - ui |
|
Ni,m-1(u) | + | |
ui+m - u
------------ ui+m - ui+1 |
|
Ni+1,m-1(u) | i = 0, ... , n |
| Ni,1(u) = | { | 1 if ui < u &le ui+1 0 otherwise |
|
|
|
![]() |
|
![]() |