Normal of a coons patch at a given point

Disclamer: Rendering the Coons patch is part of 3D Graphics homework, but finding the normals at a given point isn't. Just curious.

Here's what I got so far: It's a Coons patch defined by four Hermite curves. I render the Coons patch by making a mesh of triangles from points calculated on the Coons patch.

The surface could look much smoother than it actually is if I could figure out how to get the normal of the patch at any given point, instead of using the normals of the flat triangles.

Now I know that if I have two tangents of the surface at a given point, their cross product will give me what I look for. I also know that, for an Hermite curve in 2D space, finding the tangent means getting the derivative, which is easy if you see Hermite curve as a product of matrixes and the vector (1, t, t^2, t^3); just use this vector instead (0, 1, 2t 3t^2). The normal is just the perpendicular of the tangent then: But how do I translate that knowledge into finding the two tangents necessary for finding the normal of the Coons patch at a given point? My shaky programmer maths fail me.

EDIT: Here's how I build my Coons patch. Taken at Wikipedia. The 4 curves are Hermites.

Given four space curves c0(s), c1(s), d0(t), d1(t) which meet at four corners c0(0) = d0(0), c0(1) = d1(0), c1(0) = d0(1), c1(1) = d1(1); linear interpolation can be used to interpolate between c0 and c1, that is

$L_c(s,t)=(1-t) c_0(s)+ t c_1(s)$

and between d0, d1

$L_d(s,t)=(1-s) d_0(t)+ s d_1(t)$

producing two ruled surfaces defined on the unit square.

The bilinear interpolation on the four corner points is another surface

$B(s,t) = c_0(0) (1-s)(1-t) + c_0(1) s(1-t) + c_1(0) (1-s)t + c_1(1) s t.$

A bilinearly blended Coons patch is the surface

$L_c(s,t)+L_d(s,t)-B(s,t).$

• I assume you have 8 triangles that meet at each vertex of your mesh. You could use the average of the 8 normals of these triangles. That will give you nicer shading. – bubba Mar 21 '15 at 14:16
• @bubba That's a good idea. Why make it if I can fake it? If it turns out to be too complicated to find tangents on a bilinearly blended Coons patch, I'm taking this approach. – lampyridae Mar 21 '15 at 15:30
• Averaging normals gives very smooth results. I've went for that… and I've added Mortenson to my reading todo list :) – lampyridae Mar 22 '15 at 12:48

The term "Coons patch" is used to refer to several different surface types in CAGD, unfortunately. It sounds like you're talking about a standard tensor-product bicubic patch, which can be written in Hermite form: $$\mathbf{S}(u,v) = [1 \; u \; u^2 \; u^3] \cdot \mathbf{M} \cdot [1 \; v \; v^2 \; v^3]^T$$ where $\mathbf{M}$ is a $4 \times 4$ matrix containing corner points, derivative vectors, and "twist" vectors. There's a good description of these creatures in this book by Mortenson.
You can just differentiate the patch equation from above to get partial derivatives: $$\frac{\partial\mathbf{S}}{\partial u}(u,v) = [0 \; 1 \; 2u \; 3u^2] \cdot \mathbf{M} \cdot [1 \; v \; v^2 \; v^3]^T$$ $$\frac{\partial\mathbf{S}}{\partial v}(u,v) = [1 \; u \; u^2 \; u^3] \cdot \mathbf{M} \cdot [0 \; 1 \; 2v \; 3v^2]^T$$ Then, as you mentioned, the normal is just the cross product of the partial derivative vectors $$\mathbf{N}(u,v) = \frac{\partial\mathbf{S}}{\partial u} \times \frac{\partial\mathbf{S}}{\partial v}$$ You should unitize this normal vector before using it in lighting calculations, of course.
Edit: From the modified question, we now know that the Coons patch is actually a bilinearly blended "boolean sum" one: $$\mathbf{S}(u,v) = \mathbf{L}_c(u,v) + \mathbf{L}_d(u,v) - \mathbf{B}(u,v)$$ The process described above will work on these kinds of patches, too (or on any parametric surface, actually). We just have to compute partial derivatives, again. These are straightforward: $$\frac{\partial\mathbf{L}_c}{\partial u} = (1-v)\mathbf{c}'_0(u) + v\mathbf{c}'_1(u)$$ $$\frac{\partial\mathbf{L}_d}{\partial u} = \mathbf{d}_1(v) - \mathbf{d}_0(v)$$ $$\frac{\partial\mathbf{B}}{\partial u} = (1-v)\big[\mathbf{c}_0(1) - \mathbf{c}_0(0)\big] + v\big[\mathbf{c}_1(1) - \mathbf{c}_1(0)\big]$$ $$\frac{\partial\mathbf{S}}{\partial u} = \frac{\partial\mathbf{L}_c}{\partial u} + \frac{\partial\mathbf{L}_d}{\partial u} - \frac{\partial\mathbf{B}}{\partial u}$$ And similarly for the partial derivatives with respect to $v$.