title: How do Bezier Patches work in the Utah Teapot?
body: <p>I prematurely posted a code golf challenge to draw the <a href="http://en.wikipedia.org/wiki/Utah_teapot" rel="nofollow noreferrer">Utah Teapot</a> using <a href="ftp://ftp.funet.fi/pub/sci/graphics/packages/objects/teaset.tar.Z" rel="nofollow noreferrer">this dataset</a> (<a href="http://code.google.com/p/xpost/downloads/detail?name=teapot" rel="nofollow noreferrer">just the teapot</a>). (<a href="https://codegolf.stackexchange.com/questions/22620/draw-the-utah-teapot">Revised and Posted teapot challenge</a>) But when I looked deeper at the data in order to whip up a little example, I realized I have no idea what's going on with that data. I have a good understanding of Bezier curves in 2D, implemented deCasteljau. But for 3D does it work the same?</p>
  
  <blockquote class="spoiler">
    <p> Yes! It does!</p>
  </blockquote>
  
  <p>The data contains patches containing 16 vertices each. Is there a standard ordering for how these are laid out? And if they correspond to the 2D curves, then the four corner points actually touch the surface and the remaining 12 are controls, right?</p>
  
  <blockquote class="spoiler">
    <p> Yes!</p>
  </blockquote>
  
  <p>My "original plan" was to simplify the shape to rectangles, project them to the canvas, and draw filled shapes in a grey computed by the magnitude of the dot product of the patch normal to a light vector. If I simplify it that far, will it even look like a teapot? Does one have to use raytracing to achieve a recognizable image?</p>
  
  <blockquote class="spoiler">
    <p> That's subjective. :-(</p>
  </blockquote>
  
  <p>While this may look like several questions, but they are all aspects of this one: "Please, kindly Guru, school me on some Bezier Patches? What do I need to know to draw the teapot?"</p>
  
  <hr>
  
  <p>Here's the code I've written so far. (uses this matrix library: <a href="http://web.archive.org/web/20160404161539/https://code.google.com/p/xpost/downloads/detail?name=mat.ps&amp;can=2&amp;q=" rel="nofollow noreferrer">mat.ps</a>)</p>
  
  <pre><code>%!
  %%BoundingBox: 115 243 493 487
  %-115 -243 translate
  
  (mat.ps)run  %include matrix library
  
  /tok{ token pop exch pop }def
  /s{(,){search{ tok 3 1 roll }{ tok exit }ifelse }loop }def
  /f(teapot)(r)file def
  /patch[ f token pop { [ f 100 string readline pop s ] } repeat ]def
  /vert[ f token pop { [ f 100 string readline pop s ] } repeat ]def
  %vert == patch == %test data input
  
  /I3 3 ident def      % 3D identity matrix
  /Cam [ 0 0 10 ] def  % world coords of camera center viewpoint
  /Theta [ 0 0 0 ] def % y-rotation x-rotation z-rotation
  /Eye [ 0 0 15 ] def  % eye relative to camera vp
  /Rot I3 def          % initial rotation seq
  
  /makerot {
      Theta 0 get roty        % pan
      Theta 1 get rotx matmul % tilt
      Theta 2 get rotz matmul % twist
  } def
  
  /proj {
      Cam {sub} vop  % translate to camera coords
      Rot matmul  % perform camera rotation
      0 get aload pop Eye aload pop  % extract dot x,y,z and eye xyz
      4 3 roll div exch neg          % perform perspective projection
      4 3 roll add 1 index mul
      4 1 roll 3 1 roll sub mul exch % (ez/dz)(dx-ex) (ez/dz)(dy-ey)
  } def
  
  
  /R 20 def
  /H -3 def
  /ang 0 def
  {
      300 700 translate
      1 70 dup dup scale div setlinewidth
  
      /Cam [ ang sin R mul  H  ang cos R mul ] def % camera revolves around Y axis at height H, dist R
      /Theta [ ang  H R atan  0 ] def % rotate camera back to origin
      /Rot makerot def % squash rotation sequence into a matrix
  
      patch {
          % Four corners
          %[ exch dup 0 get exch dup 3 get exch dup 12 get exch 15 get ]
  
          % Boundary curves
          [ exch
              dup 8 get exch dup 4 get exch dup 0 get exch %curveto4
  
              dup 14 get exch dup 13 get exch dup 12 get exch %curveto3
  
              dup 7 get exch dup 11 get exch dup 15 get exch %curveto2
  
              dup 1 get exch dup 2 get exch dup 3 get exch %curveto1
  
              dup 0 get exch %moveto
          pop ]
  
          { 1 sub vert exch get proj } forall
  
          moveto
              curveto curveto curveto curveto
  
          stroke
          %flushpage flush (%lineedit)(r)file pop
      } forall
      pstack
      showpage
  
      %exit
      /ang ang 10 add def
  } loop
  </code></pre>
  
  <p>Here's the <a href="ftp://ftp.funet.fi/pub/sci/graphics/packages/objects/teaset.tar.Z" rel="nofollow noreferrer">original Newell Teapot dataset</a>.</p>
  
  <p>And here's my spectacularly bad image:<br>
  <img src="https://i.stack.imgur.com/gyRcy.png" alt="Don&#39;t know how the vertices are organized."></p>
  
  <p>Update: bugfix. Maybe they are laid out 'normally' after all. Selecting the correct corners at least gives a symmetrical shape:<br>
  <img src="https://i.stack.imgur.com/pv4xP.png" alt="Found the corners."></p>
  
  <p>Update: boundary curves looks better.<br>
  <img src="https://i.stack.imgur.com/Xh5pz.png" alt="boundary curves"></p>