Bezier Surface
I'm trying to plot a Bezier surface in matplotlib. I have my functions for x,y, and z (I didnt type them out, I had sympy automatically generate them) but whenever I run my code, I just get a blan. Bezier Surfaces. The following Applet can be used to draw a single Bezier Surface using 16 control points. Each control point is initially positioned in the xy-plane.The z-coordinate of each control point can be adjusted by simply dragging the point in a direction perpendicular to the xy-plane.To change the x and y coordinate of a control point, simply hold down the SHIFT key while dragging.
(newcommand{Choose}[2]{{{#1}choose{#2}}}newcommand{vecII}[2]{left[begin{array}{c} #1#2 end{array}right]}newcommand{vecIII}[3]{left[begin{array}{c} #1#2#3 end{array}right]}newcommand{vecIV}[4]{left[begin{array}{c} #1#2#3#4 end{array}right]}newcommand{matIIxII}[4]{left[ begin{array}{cc} #1 & #2 #3 & #4 end{array}right]}newcommand{matIIIxIII}[9]{left[ begin{array}{ccc} #1 & #2 & #3 #4 & #5 & #6 #7 & #8 & #9 end{array}right]})Please also read this, on using Quadratic and Cubic Béziercurves in the HTML5 Canvas:
Additional Reading
Most of what I know about Curves and Surfaces I learned from Angel'sbook, so check that chapter first. It's pretty mathematical in places,though. There's also a chapter of the Red Book (the Red OpenGLProgramming Guide).
For practical programming in Three.js, you might try this page on rendering lines and Bézier Curves in Three.js and WebGL.
Simply concentrate. Ask a question, then touch the hand and watch the hand and crysta.Please be aware that APK20 only share the original and free apk version for Crystal Ball Fortune Teller v2.0.2 without any modifications.All the apps & games here are downloaded directly from play store and for home or personal use only. Pocket fortune teller apk game. You are downloading the Crystal Ball Fortune Teller 2.0.2 apk file for Android: Crystal Ball Fortune Teller will answer your most important questions. If Crystal Ball Fortune Teller apk download infringes your copyright, please, We'll delete it in a short time.
Organization
This reading is organized as follows. First, we look at why we try torepresent curves and surfaces in graphics models, but I think most of usare already pretty motivated by that. Then, we look at major classes ofmathematical functions, discussing the pros and cons, and finally choosingcubic parametric equations. Next, we describe different ways to specify acubic equation, and we ultimately settle on Bézier curves. Finally, welook at how the mathematical tools that we've discussed are reflected inOpenGL code.
The preceding develops curves (that is, 1D objects --- wigglylines). In graphics, we're mostly interested in surfaces (thatis, 2D objects --- wiggly planes). The last sections define surfaces as ageneralization of what we've already done with curves.
Introduction
Bézier curves were invented by a mathematician working at Renault, theFrench car company. He wanted a way to make formal and explicit the kindsof curves that had previously been designed by taking flexible strips ofwood (called splines, which is why these mathematical curves areoften called splines) and bending them around pegs in a pegboard.To give credit where it's due, another mathematician named de Castelauindependently invented the same family of curves, although themathematical formalization is a little different.Representing Curves
Most of us know about different kinds of curves, such as parabolas,circles, the square root function, cosines and so forth. Most of thosecurves can be represented mathematically in several ways:- explicit equations
- implicit equations
- parametric equations
Explicit Equations
The explicit equations are the ones we're most familiar with. Forexample, consider the following functions:$$ begin{eqnarray*} y &=& mx+b y &=& ax^2+bx+c y &=& sqrt{r^2-x^2} end{eqnarray*}$$
An explicit equation has one variable that is dependent on the others;here it is always $y$ that is the dependent variable: the one that iscalculated as a function of the others.
An advantage of the explicit form is that it's pretty easy to compute abunch of values on the curve: just iterate $x$ from some minimum to somemaximum.
One trouble with the explicit form is that there are often special cases(for example, vertical lines). Another is that the limits on $x$ willchange from function to function (the domain is infinite for the first twoexamples, but limited to $pm r$ for the third). The deadly blow is thatit's hard to handle non-functions, such as a complete circle, or aparabola of the form $x=ay^2+by+c$. You could certainly get a computerprogram to handle this form, but you'd need to encode lots of extra stuff,like which variable is the dependent one and so forth. Bézier curvescan be completely specified by just an array of coefficients.
Implicit Equations
Another class of representations are implicit equations. These equationsalways put everything on one side of the equation, so no variable isdistinguished as the dependent one. For example: begin{eqnarray*} ax+by+cz-d=0 & & textrm{plane} ax^2+by^2+cz^2-d^2=0 & & textrm{egg} end{eqnarray*}
These equations have a nice advantage that, given a point, it's easy totell whether it's on the curve or not: just evaluate the function and seeif the function is zero. Moreover, each of these functions divides spacein two: the points where the function is negative and the points whereit's positive. Interestingly, the surfaces do as well, so thesign of the function value tells you which side of the surfaceyou're on. (It can even tell you how close you are.)
The fact that no variable is distinguished helps to handle specialcases. In fact, it would be pretty easy to define a large general polynomial in $x$, $y$ and $z$ as our representation.
The deadly blow for this representation, though, is that it's hard to generate points on the surface. Imagine that I give you a value for $a$, $b$, $c$ and $d$ and you have to find a value for $x$, $y$, and $z$ that work for the two examples above. Not easy in general. Also, it's hard to do curves (wiggly lines). In general, curves are the intersection of two surfaces, like conic sections (parabola, ellipse, etc.) being the intersection of a cone and a plane
Parametric Equations
Finally, we turn to the parametric equations. We've seen these before, ofcourse, in defining lines, which are just straight curves.
With parametric equations, we invent some newvariables,parameters, typically $s$ and $t$. These variables arethen used to define a function for each coordinate: [ vecIII{x(s,t)}{y(s,t)}{z(s,t)} ]
Parametric functions have the advantage that they're easy to generalize to3D, as we already saw with lines.
The parameters tell us where we are on the surface (or curve)rather than where we are in space. Therefore, we have a conventionaldomain, namely the unit interval. That means that, like our linesegments, our curves will all go from $t=0$ to $t=1$. (They don't have to,but they almost always do.) Similarly, surfaces are all points where$0leq s,t leq 1$. Thus, another advantage of parametric equations isthat it's easy to define finite segments and sheets, by limiting thedomains of the parameters.
The problem that remains is what family of functions we will use for theparametric functions. One standard approach is to use polynomials,thereby avoiding trigonometric and exponential functions, which areexpensive to compute. In fact, we usually choose a cubic:
Another problem comes with finding these coefficients. We'll develop thatin later sections, but the solution is essentially to appeal to some nicetechniques from linear algebra that let us solve for the desiredcoefficients given some desired constraints on the curve, such as where itstarts and where it stops.
Why We Want Low Degree
Why do we typically use a cubic? Why not something of higher degree,which would let us have more wiggles in our curves and surfaces? This isa reasonable question.
In general, we want a low degree: quadratic, cubic or something inthat neighborhood. There are several reasons:
- The resulting curve is smooth and predictable over long spans. In other words, because it wiggles less, we can control it more easily. Consider trying to make a nice smooth curve with a piece of cardboard or thin wood (a literal spline) versus with a piece of string.
- It takes less information to specify the curve. Since there are four unknown coefficients, we need four points (or similar constraints) to solve for the coefficients. If we were using a quartic, we'd need 5 points, and so forth.
- If we want more wiggles, we can join up several splines. Because of the low degree, we have good control of the derivative at the end points, so we can make sure that the curve is smooth through the joint.
- Finally, it's just less computation and therefore easier for the graphics card to render.
OpenGL will permit you to use higher (and lower) degree functions, butfor this presentation we'll stick to cubics. If you'd like to play withhigher degree functions, I'm happy to help you with that. The followingfigure shows four points defining a curve.
Joining Curves
To make longer curves with more wiggles, we can join up several Bézier curves. The following figure shows two examples. In the first, the curves are connected (the last control point of the first curve is the same as the first point of the second), but not smooth through the joint. The second manages to make the joint smooth, by making sure the tangents line up. The tangents are defined by the line segments from P2 to P3 and from Q0 to Q1. So, if P2, P3=Q0, and Q1 are co-linear, the joint will be smooth. (We'll revisit this later.)
Ways of Specifying a Curve
Once we've settle on a family of functions, such as cubics, whatremains is determining the values of the coefficients that give us aparticular curve. To define a cubic, we need four pieces ofinformation, though there are different choices about what four pieces ofinformation. If I want, for example, a curve that looks like the letter``J,' what four pieces of information do I have to specify? It turns outthat there are three major ways of doing that. (It's strange how everyingseems to break down into threes in this subject.)
- Interpolation: That is, you specify four points on the curve and the curve goes through (interpolates) the points. This is pretty intuitive, and a lot of drawing programs allow you to do this, but it's not often used in CG. This is primarily because such curves have an annoying way of suddenly lurching as they struggle to get through the next specified point.
One exception is that this technique is often used when you have a lot of data, as with a digitally scanned face or figure. Then you have thousands of points, and the curve pretty much has no choice but to be what you want (although the graphics artist may still want to do some smoothing, say for measurement error or something).
- Hermite: In the Hermite case, the four pieces of information you specify are 2 points and 2 vectors: the points are where the curve starts and ends, and the vectors indicate the direction of the curve at that point. They are, in fact, derivatives. (If you've done single-dimensional calculus, you know that the derivative gives the slope at any point and the slope is just the direction of the line; the same idea holds in more dimensions.) This is a very important technique, because we often have this information. For example, if I want a nice rounded corner on a square box, I know the slope at the beginning (vertical, say) and at the end (horizontal).
- Bézier: With a Bézier curve, we specify 4 points, as follows: the curve starts at one, heading for second, ends at fourth, coming from third. (See the picture below.) This is a very important technique, because you can easily specify a point using a GUI, while a vector is a little harder. It turns out there are other reasons that Bézier is preferred, and in practice the first two techniques are implemented by finding the Bézier points that draw the desired curve.
The figure above compares these three approaches. An X11 drawingprogram that will let you experiment with the examples drawn in the figureis xfig. (Xfig uses quadratic Bézier curves.) Tryit! You can also draw Bézier curves in the HTML5 2D canvas.
OpenGL curves are drawn by calculating points on the line and drawingstraight line segments between those points. The more segments, thesmoother the resulting curve looks. In some implementations, thecalculations can be done by the graphics card. In THREE.js, they computethe vertices in the main processor, rather than having the graphics carddo that. I believe it's because they want to simplify the shader program,but that's a guess.
Solving for the Coefficients
We'll now discuss how we can solve for the coefficients given the controlinformation (the four points or the two points and two vectors).Essentially, we're solving four simultaneous equations. We won't do allthe gory details, but we'll appeal to some results from linear algebra.
Let's look at how we solve for the coefficients in the case of theinterpolation curves; the others work similarly.
Note that in every case, the parameter is $t$ and it goes from 0 to 1. Forthe interpolation curve, the interior points are at $t=1/3$ and $t=2/3$.Let's focus just on the function for $x(t)$. The other dimensions workthe same way. If we substitute $t={0, frac13, frac23, 1 }$ into thecubic equations we saw earlier, we get thefollowing:begin{eqnarray*}&& P_0 = x(0) = C_0&& P_1 = x(1/3) = C_0+frac13C_1 + left(frac13right)^2C_2 + left(frac13right)^3C_3&& P_2 = x(2/3) = C_0+frac23C_1 + left(frac23right)^2C_2 + left(frac23right)^3C_3&& P_3 = x(1) = C_0+C_1 + C_2 + C_3end{eqnarray*}
What does this mean? It means that the $x$ coordinate of the first point,$P_0$, is $x(0)$ This makes sense: since the function $x$ starts at $P_0$,it should evaluate to $P_0$ at $t=0$. (This is also exactly what happenswith a parametric equation for a straight line: at $t=0$, the functionevaluates to the first point.) Similarly, the $x$ coordinate of thesecond point, $P_1$ is $x(1/3)$ and that evaluates to the expression thatyou see there. Most of those coefficients are still unknown, but we'llget to how to find them soon enough.
Putting these four equations into a matrix notation, we get the following:[ mathbf{P} = left[ begin{array}{cccc}1 & 0 & 0 & 0 1 & frac13 & (frac13)^2 & (frac13)^3 1 & frac23 & (frac23)^2 & (frac23)^3 1 & 1 & 1 & 1 end{array}right]mathbf{C}]
The $mathbf{P}$ matrix is a matrix of points. It could just bethe $x$ coordinates of our points $P$, or more generally it could be amatrix each of whose four entries is an $(x,y,z)$ point. We'll view it asa matrix of points. The matrix $mathbf{C}$ is a matrix ofcoefficients, where each element --- each coefficient --- is atriple $(C_x,C_y,C_z)$, meaning the coefficients of the $x(t)$ function, the$y(t)$ function and the $z(t)$ function.
If we let $mathbf{A}$ stand for the array of numbers, we get thefollowing deceptively simple equation:[ mathbf{P} = mathbf{A} mathbf{C} ]
By inverting the matrix $mathbf{A}$, we can solve for thecoefficients! (The inverse of a matrix is the analog to a reciprocal inscalar mathematics. It's also equivalent to solving the simultaneousequations in a very general way.) The inverse of $mathbf{A}$ is calledthe interpolating geometry matrix and is denoted $mathbf{M}_I$:[ mathbf{M}_I = mathbf{A}^{-1} ]
Notice that the matrix $mathbf{M}_I$ does not depend on the particularpoints we choose, so that matrix can simply be stored in the graphicscard. When we send an array of control points, $mathbf{P}$, down thepipeline, the graphics card can easily compute the coefficients it needsfor calculating points on the curve:[ mathbf{C} = mathbf{M}_I mathbf{P} ]
The same approach works with Hermite and Bézier curves, yielding theHermite geometry matrix and the Bézier geometry matrix. In the Hermitecase, we take the derivative of the cubic and evaluate it at the endpointsand set it equal to our desired vector (instead of points $P_1$ and$P_2$). In the Bézier case, we use a point to define the vector andreduce it to the previously solved Hermite case.
Blending Functions
Sometimes, looking at the function in a different way can give usadditional insight. Instead of looking at the functions in terms ofcontrol points and geometry matrices, let's look at them in terms of howthe control points influence the curve points.
Looking just at the functions of $t$ that are combined with the controlpoints, we can get a sense of the influence each control point has overeach curve point. The influences of the control points are blendedto yield the final curve point, and these functions are calledblending functions. (Blending functions are also important forunderstanding NURBS, a generalization of Bézier curves.)Equivalently, the curve points are a weighted average of thecontrol points, where the blending functions give the weight. (We lookedat weighted averages in our discussion of bi-linear interpolation.) Thatis, if you evaluate the four blending functions at a particular parametervalue, $t$, you get four numbers, and those numbers are weights in aweighted sum of the four control points.
The following function gives the curve, $P(t)$, as a weighted sum of thefour control points, where the four blending functions evaluate to theappropriate weight as a function of $t$.begin{eqnarray*} P(t) &=& B_0(t)*P_0 + B_1(t)*P_1 + B_2(t)*P_2 + B_3(t)*P_3end{eqnarray*}
The following are the blending functions for interpolating curves. begin{eqnarray*} B_0(t) &=& frac{-9}2(t-frac13)(t-frac23)(t-1) B_1(t) &=& frac{27}2t(t-frac23)(t-1) B_2(t) &=& frac{-27}2t(t-frac13)(t-1) B_3(t) &=& frac{-9}2t(t-frac13)(t-frac23) end{eqnarray*}
These functions are plotted in the following figure on blending functions for Interpolation Curves.
Alternatively, you can go over to Wolfram Alpha and see the live plotting (and adjust to your taste) by clicking on these links
First, notice that the curves always sum to 1. (It may not be entirelyobvious, but it's true.) When a curve is near zero, the control point haslittle influence. When a curve is high, the weight is high and theassociated control point has a lot of influence: a lot of pull.
Infact, when a control point has a lot of pull, the curve passes near it.When a weight is 1, the curve goes through the control point.
Notice that the blending functions are negative sometimes (they allstart and end at zero), which means that this isn't a normal weightedaverage. (A normal weighted average has all non-negative weights.) Whatwould a negative weight mean? If a positive weight means that a controlpoint has a certain pull,
a negative value gives it push
---the curve is repelled from that control point. This repulsion effect ispart of the reason that interpolation curves are hard to control.
Hermite Representation
The coefficients for the Hermite curves and therefore the blendingfunctions can be computed from the control points in a similar way (wehave to deal with derivatives, but that's not the point right now).
Note that the derivative (tangent) of a curve in 3D is a 3D vector,indicating the direction of the curve at this moment. (This followsdirectly from the fact that if you subtract two points, you get the vectorbetween them. The derivative of a curve is simply the limit as the pointsyou're subtracting become infinitely close to each other.)
The Hermite blending functions are the following. [ mathbf{b}(t) = vecIV {2t^3-3t^2+1} {-2t^3+3t^2} {t^3-2t^2+t} {t^3-t^2} ]
The Hermite blending functions are plotted in the following figure:
The Hermite curves have several advantages:
- Smoothness:
- easier to join up at endpoints. Because we control the derivative (direction) of the curve at the endpoints, we can ensure that when we join up two Hermite curves that the curve is smooth through the joint: just ensure that the second curve starts with the same derivative that the first one ends with.
- The blending functions don't have zeros in the interval: so the influence of a control point never switches from positive to negative. For example, the influence of the first control point peaks at the beginning and steadily, monotonically, drops to zero over the interval.
- The Hermite can be easier to control. As we mentioned earlier, there's no need to know interior points, and we often only know how we want a curve to start and end.
Bézier Curves
The Bézier curve is based on the Hermite, but instead of using vectors,we use two control points. Those control points are not interpolatedthough: they exist only in order to define the vectors for the Hermite, asfollows:begin{eqnarray*} p'(0) &=& frac{p_1-p_0}{1/3} = 3(p_1-p_0) p'(1) &=& frac{p_3-p_2}{1/3} = 3(p_3-p_2)end{eqnarray*}
That is, the derivative vector at the beginning is just three times thevector from the first control point to the second, and similarly for theother vector. The figure below shows the derivative vectors and theBézier control points. Notice (as we can see from the equationsabove), that the vectors are three times longer than the distance of theinner control points from the end control points. However, that's notimportant. The factor is chosen so that the resulting equations aresimplified.
Like the Hermite, Bézier curves are easily joined up. We caneasily get continuity through a joint by making sure that the last twocontrol points of the first curve line up with the first two controlpoints of the next. Even better, the interior control points should beequally distant from the joint. This ensures that the derivatives areequal and not just proportional. You can see this in theearlier figure where we smoothly joinedtwo Bézier curves. Repeating that figure here:
- The last control point of the green curve (P3) is the same as the first point of the red curve (Q0).
- The three points (P2, P3=Q0, Q1) form a straight line. (In this case it's a vertical line, but that was just for my convenience.) That co-linearity means that the derivatives are in the same direction, so the joint is smooth.
- The distance from P2-P3 is the same as the distance from Q0-Q1, so that the derivatives are not just lined up but are actually equal. This gives extra smoothness.
The Bézier blending functions are especially nice, as seen infollowing equation.
Here is a figure that plots the Bézier blending functions:
These blending functions are from a family of functions calledthe Bernstein polynomials: [ b_{kd}(t) = Choose{d}{k} t^k(1-t)^{d-k} ]
These can be shown to:
- Have all roots at 0 and 1
- Be non-negative in the interval [0,1]
- Be bounded by 1
- Sum to 1
Perfect for mixing! Thus, our Bézier curve is a weighted sum, so geometrically, all points must lie within the convex hull of the control points, as shown in the following figure:
To be concrete, let's take an example of the Bézier blending functions.For example, what is the midpoint of a Bézier curve? Themidpoint is at a parameter value of $u=0.5$. Evaluating the fourfunctions in the Bézier blending functions, we get:
Thus, to find the coordinates of the midpoint of a Bézier curve, we onlyneed to compute this weighted combination of the control points.Essentially:begin{eqnarray*} P(0.5) &=& frac18 P_0 + frac38 P_1 + frac38 P_2 + frac18 P_3 &=& (P_0 + 3 P_1 + 3 P_2 + P_3 )/8end{eqnarray*}
It turns out that there's a very nice recursive algorithm for computingevery point on the curve by successively dividing it in half like this, stopping the recursion when the piece is sufficiently short or flat, so that it can be drawn with just a straight line.
Representing Surface Patches
Using parametric representation, each coordinate becomes a function of twonew parameters, which we will call $s$ and $t$, just like we did with textures (which is why $u$ and $v$ are sometimes used instead). [begin{array}{rcllll} x(s,t) &=& C_{00} + &C_{01}t + &C_{02}t^2 + &C_{03}t^3 + & & C_{10}s + &C_{11}st + &C_{12}st^2 + &C_{13}st^3 + & & C_{20}s^2 + &C_{21}s^2t + &C_{12}s^2t^2 + &C_{23}s^2t^3 + & & C_{30}s^3 + &C_{31}s^3t + &C_{22}s^2t^2 + &C_{33}s^3t^3end{array}]
or [ x(s,t) = sum_{i=0}^{3}sum_{j=0}^{3} C_{ij}s^it^j]
And similarly for $y$ and $z$. Since there are 16 coefficients, we need 16control points to specify the surface patch.
Note that the four edges of a Bézier surface are Bézier curves,which helps a great deal in understanding how to control them. That helpsus to understand 12 of the 16 control points.
The four interior points are hard to interpret. Concentrating on onecorner: if it lies in the plane determined by the three boundary points,the patch is locally flat. Otherwise, it tends to twist. This is hard topicture. It is, of course, related to the double partial derivative ofthe curve:begin{equation} label{eq:dudv} frac{partial^2 p}{partial upartial v}(0,0) = 9(p_{00} - p_{01} +p_{10} - p_{11}) end{equation}
Bézier Patch Demo in THREE.js
The following uses some things that I added to THREE.js, just to automate the computing of the interpolated points and faces.
You can stop here; the rest is based on the old OpenGL API, rather than Three.js. In the old OpenGL API, you could coax the graphics card into computing the points on curves and surfaces for you, but the more recent approach is to do all that computation in the main CPU and send the computed vertices down to the graphics card. Three.js does this for us when we construct curved geometrical objects.
Bézier Curves in OpenGL
Note for 2014: The following section will have to be theoretical
for now, because it seems that the current version of Three.js does not expose the OpenGL Bézier curve API or even use it. Instead, it provides functions for computing values using the Bernstein polynomials, which we can then use for computing vertices for a line or a surface. Please read this for the concepts, but you need not pay close attention to the programming aspects.
To draw a curve in OpenGL, the main thing we have to do is to specify thecontrol points. However, there are other things we might want OpenGL tocalculate for us. Here are some:
- vertices (points on the curve or surface)
- normals
- colors
- texture coordinates
They all work the same way. For example, if we specify four controlpoints, we can have OpenGL compute any point on the curve, and if wespecify four colors (one for each of those points), we can have OpenGLcompute the color of the associated point, using the same blendingfunctions.
Each of these is called an evaluator. You can have multipleevaluators active at once, say for vertices and colors.
The basic OpenGL functions for curves are (in C):
The first two are setup functions. The first, glMap1f()
,is how we specify all the control information (points, colors, orwhatever). The target
is the kind of control information you arespecifying and the kind of information you want generated, such as:
GL_MAP1_VERTEX_3
, a vertex in 3DGL_MAP1_VERTEX_4
, a vertex in 4D (homogeneous coordinatesGL_MAP1_COLOR_4
, a RGBA colorGL_MAP1_NORMAL
, a normal vectorGL_MAP1_TEXTURE_COORD_1
, a texture coordinate. (We'll talk about textures in a few weeks.)
The u_min
and u_max
arguments are just the min and maxparamater, so they are typically 0 and 1, though if you just want a pieceout of the curve, you can use different values. For example, to get themiddle fifth of the curve, you could give u_min
=0.4 andu_max
=0.6.
The stride is a complicated thing that we'll talk about below.The order is one more than the degree of the polynomial (4 for acubic) and is therefore equal to the number of control points we aresupplying. Since JavaScript knows how long its arrays are, it can count thatfor you. Finally, an array of the control information: vertices, RGBAvalues or whatever. They should be of the same type as the target.
The second function, glEnable()
, simply enables the evaluator; youcan enable and disable them like lights or textures.
Finally, the last function, glEvalCoord1f()
, replaces functions liketexttt{glVertexf()}, texttt{glColorf()} and texttt{glNormalf()},depending on the target. In other words, that's the one that actuallycalculates a point on the curve or its color or whatever, and sends itdown the pipeline. Here's an example of how you might do 100 evenlyspaced steps on a curve:
If you know that you just want evenly spaced steps (which is often thecase), you can use the following two functions instead of calls toglEvalCoord
.
This is a grid of `steps' (say 100), from the minimum $u$ to the maximum$u$ (typically 0.0 to 1.0, but not necessarily). The second actuallyevals the mesh from `start' (typically 0) to `stop' (typically the same as`steps').
Strides
What the heck is a stride? Since the control point data is given toOpenGL in one flat array, the stride is the number of elements to skip toget from one row/column to the next row/column.
We saw strides in the context of two-dimensional arrays used to represent color images. The stride from one texel to the next along a row was 3 bytes. The stride from one texel to the next down a column was 3*width, where width is the width of the texture (which is the same as the length of a row, which is the same as the number of columns).
For curves, the stride is almost always 3, because the elements are3-place coordinates consecutive in memory. If you're specifying colors,the stride will be 4, because the elements are 4-place RGBA valuesconsecutive in memory. The stride becomes more complicated when we dealwith 2D surfaces instead of 1D curves.
Representing Surface Patches
Using parametric representation, each coordinate becomes a function of twonew parameters, which we will call $s$ and $t$, just like we did with textures (which is why $u$ and $v$ are sometimes used instead). [begin{array}{rcllll} x(s,t) &=& C_{00} + &C_{01}t + &C_{02}t^2 + &C_{03}t^3 + & & C_{10}s + &C_{11}st + &C_{12}st^2 + &C_{13}st^3 + & & C_{20}s^2 + &C_{21}s^2t + &C_{12}s^2t^2 + &C_{23}s^2t^3 + & & C_{30}s^3 + &C_{31}s^3t + &C_{22}s^2t^2 + &C_{33}s^3t^3end{array}]
or [ x(s,t) = sum_{i=0}^{3}sum_{j=0}^{3} C_{ij}s^it^j]
And similarly for $y$ and $z$. Since there are 16 coefficients, we need 16control points to specify the surface patch.
Note that the four edges of a Bézier surface are Bézier curves,which helps a great deal in understanding how to control them. That helpsus to understand 12 of the 16 control points.
The four interior points are hard to interpret. Concentrating on onecorner: if it lies in the plane determined by the three boundary points,the patch is locally flat. Otherwise, it tends to twist. This is hard topicture. It is, of course, related to the double partial derivative ofthe curve:begin{equation} label{eq:dudv} frac{partial^2 p}{partial upartial v}(0,0) = 9(p_{00} - p_{01} +p_{10} - p_{11}) end{equation}
Bézier Surfaces in OpenGL
Note for 2014: As above, the following section will have to be theoretical
for now.
To handle surfaces, we just convert the OpenGL functions from theearlier section above to 2D. The basic functions are:
Here, it's even more common to let OpenGL do the work of generating allthe points:
Texture Mapping
If you're doing texture mapping, you can have OpenGL calculate texturecoordinates for you at each of the surface points, just by setting up andenabling that target:
Because texture-mapping is 2D, the texture coordinates are often generatedby a linear Bézier function, such as:
Here the texture coordinates (0,0) will correspond to the first spatialcorner, and the $(s,t)$ texture coordinates will equal the $(u,v)$Bézier parameters.
Normal Vectors
If you want to use lighting on a surface, you have to generate normals aswell. You can do it yourself using
Run 2 - Play it now at Cool Math Games: Warning: This game requires a huge amount of concentration and memorization as you run (or skate) through the 3 dimensional courses. Run 2 - Play it now at CoolmathGames.com. Play the Free Running 2 Miniclip game. The 2nd cool 3D parkour game made by Miniclip where you play as a free runner. Run through urban environment and overcome all the parkour's obstacles in your way. Try to reach the finish before the time ends while you collect extras and perform aerial tricks to gain extra points. Use ARROW keys or WASD to move. Free Running 2 is the sequel to our smash-hit parkour game, Free Running, featuring stunning 3D graphics, new moves, game modes and challenges. Are you looking for unblocked games? PrimaryGames is the fun place to learn and play! Play run 4. You are currently playing Free Running 2 for free at Aukh. It is one of the unique game that you can play online here. If you liked this game then you will must find other games interesting too. Free Running 2. Description: Have you ever seen those Free-Running and Parkour superstars; like Sebastien Foucan, and David Belle. Free Running 2 is a Running Games. Instructions: Arrow keys to move and X to jump.
However, you can make OpenGL compute the normals for you:
However, when OpenGL generates a normal vector for you, how does it do it?The answer is surprisingly simple, and yet the implications aren'tobvious.
To be concrete, suppose we want to have a linear Béziersurface. This means there are only four control points: the fourcorners, since the interior is all just bi-linear interpolation. The normal for the surface in that figure willface towards us because it is computed as $u$ (the red arrow) cross $v$(the green arrow). The $u$ and $v$ vectors are determined by the directionof the two parameters in the description of the Bézier surface. Forexample, the control points for a quadratic Bézier surface would be defined as follows:
This works because the $u$ dimension is what we would call ``left toright' and so we give the points as A then B and D then C (with a$u$-stride of 3). The $v$ dimension is what we would call ``bottom totop' and so we give the points as A then D and B then C (with a$v$-stride of 6). The $u$ dimension nests ``inside' the $v$ dimension,and so the control points are given in the order ABDC. Theright-hand-rule tells us that ``left-to-right' crossed with``bottom-to-top' yields a vector that points towards us.
Of course, in that example, we decided to give the lower left corner(vertex A) first. If we decided to have the upper left corner first(vertex D), and we still wanted to have the surface normal face towardsus, we would give the control points in the order DACB, because the $u$dimension is determined by DA and CB, which is ``top to bottom' and the$v$ dimension is ``left to right' so AB and DC (as before).
Demos
In class, we'll look at several demos of how to do Bézier curves.
Circular Arcs with Bézier
It's a useful exercise to consider how to do a circle usingBézier curves, as opposed to computing lots of sines and cosines.Note that it is mathematically impossible to do this perfectly, sinceBézier curves are polynomials and a circle is not any kind ofpolynomial, but the approximation might be good enough.
First, note that we can't do a full circle with one curve, because thefirst and last control points would be the same and the bounding region(convex hull) would have no area.
So, let's try a half-circle. Observe that the requirement that the curveis tangent to the line between the first two control points and betweenthe last two control points, together with symmetry, gives us:
Okay, so we could clearly do some trial and error and come up with something reasonable. Can we do better than trial and error?
First, we have to acknowledge that our approximation can never be perfect; there will always be some error. We might, however, make it fairly small. But how to even measure it?
One idea I had, which has the virtue of being easy to calculate, is to make sure that the midpoint of the approximation lies on the circle. In the attempts above, we know:
- If 'C' is the center of the circle, and the center is the origin, then the coordinates of P0 and P3 are (1,0) and (-1,0).
- The interior control points, P1 and P3, lie directly below P0 and P3, so their coordinates are (1,$a$) and (-1,$a$) for some unknown value $a$.
- The midpoint of the Bézier curve is (0,-1).
Using the formula for the midpoint of a Bézier curve and focussing only on the $y$ coordinate, we have:begin{eqnarray*} P(0.5) &=& frac18 P_0 + frac38 P_1 + frac38 P_2 + frac18 P_3 &=& (P_0 + 3 P_1 + 3 P_2 + P_3 )/8 -1 &=& (0 + 3 a + 3 a + 0 )/8 -1 &=& ( 6 a )/8 -8/6 &=& a end{eqnarray*}
So, if we make the value of $a$ be 4/3rds the radius of the circle, we should get a Bézier curve that passes through the correct mid-point. Let's give it a try:
Good enough? If not, we could approximate quarter-circles. Let's try:
Using the formula for the midpoint of the curve again, we get:begin{eqnarray*} vecII{sqrt2/2}{sqrt2/2} &=& (vecII{0}{1} + 3vecII{a}{1} + 3vecII{1}{a}+ vecII{1}{0})/8 vecII{4sqrt2}{4sqrt2} &=& vecII{4+3a}{4+3a} 4(sqrt2-1) &=& 3a a &=& frac{4(sqrt2-1)}{3} approx 0.55end{eqnarray*}
Trying this value yields an even better approximation, which I'll draw some other time.