/** Draw a Bezier patch This is just a demonstration of how a Bezier patch is defined -- in a real OpenGL application you would use OpenGL's evaluators for Bezier patches */ import javax.media.opengl.*; public class BezierPatch{ static Vector3D[][] pts = {{new Vector3D(0.997318, 0.588299, -1.521656), new Vector3D(1.078617, 0.760218, -2.753872), new Vector3D(-0.737494, 0.167809, -2.995954), new Vector3D(-0.839501, 0.076099, -1.850207)}, {new Vector3D(0.711893, 1.217446, -0.793816), new Vector3D(0.537288, 1.861077, -1.398575), new Vector3D(-1.298280, 1.258282, -1.524114), new Vector3D(-1.149062, 0.650171, -0.923835)}, {new Vector3D(0.647240, 1.038420, 0.644803), new Vector3D(0.387053, 1.489424, 1.242428), new Vector3D(-1.453633, 0.888604, 1.200335), new Vector3D(-1.201629, 0.417627, 0.696299)}, {new Vector3D(1.127011, -0.401840, 0.646791), new Vector3D(1.283487, -1.069904, 1.163934), new Vector3D(-0.531168, -1.675671, 1.024685), new Vector3D(-0.681939, -1.024174, 0.562137)}}; // the basis function for a Bezier spline static float b(int i, float t) { switch (i) { case 0: return (1-t)*(1-t)*(1-t); case 1: return 3*t*(1-t)*(1-t); case 2: return 3*t*t*(1-t); case 3: return t*t*t; } return 0; //we only get here if an invalid i is specified } // derivative of the basis function for a Bezier spline static float bdash(int i, float t) { switch (i) { case 0: return (-3*t + 6)*t - 3; case 1: return (9*t - 12)*t + 3; case 2: return (-9*t +6)*t; case 3: return 3*t*t; } return 0; //we only get here if an invalid i is specified } //evaluate a point on the Bezier patch static Vector3D p(float s, float t) { Vector3D result = new Vector3D(0,0,0); for (int i = 0; i<=3; i++){ for (int j = 0; j<=3; j++){ result = result.add(pts[i][j].scale(b(i,s)*b(j,t))); } } return result; } //evaluate a partial derivative on the Bezier patch in s direction static Vector3D pds(float s, float t) { Vector3D result = new Vector3D(0,0,0); for (int i = 0; i<=3; i++){ for (int j = 0; j<=3; j++){ result = result.add(pts[i][j].scale(bdash(i,s)*b(j,t))); } } return result; } //evaluate a partial derivative on the Bezier patch in t direction static Vector3D pdt(float s, float t) { Vector3D result = new Vector3D(0,0,0); for (int i = 0; i<=3; i++){ for (int j = 0; j<=3; j++){ result = result.add(pts[i][j].scale(b(i,s)*bdash(j,t))); } } return result; } public static void vertex3d(GL gl, Vector3D a) { gl.glVertex3d(a.x,a.y,a.z); } public static void normal3d(GL gl, Vector3D a) { gl.glNormal3d(a.x,a.y,a.z); } public static void patch(GL gl, int level){ Vector3D a,ads,adt,n; //draw control net gl.glDisable(GL.GL_LIGHTING); for (int i = 0; i <= 3; i++){ gl.glBegin(GL.GL_LINE_STRIP); for (int j = 0; j <= 3; j++){ vertex3d(gl,pts[i][j]); } gl.glEnd(); } for (int j = 0; j <= 3; j++){ gl.glBegin(GL.GL_LINE_STRIP); for (int i = 0; i <= 3; i++){ vertex3d(gl,pts[i][j]); } gl.glEnd(); } gl.glEnable(GL.GL_LIGHTING); float h = 1.0f/level; for (int i = 0; i < level; i++){ float x = i*h; gl.glBegin(GL.GL_TRIANGLE_STRIP); for (int j = 0; j <= level; j++){ float y = j*h; a = p(x+h, y); ads = pds(x+h, y); adt = pdt(x+h, y); n = adt.cross(ads); gl.glTexCoord2d(x+h,y); normal3d(gl,n); vertex3d(gl,a); a = p(x, y); ads = pds(x, y); adt = pdt(x, y); n = adt.cross(ads); gl.glTexCoord2d(x,y); normal3d(gl,n); vertex3d(gl,a); } gl.glEnd(); } } }