next up previous contents index
Next: Drawing a box around Up: Tutorials and Examples Previous: Triangles   Contents   Index

Draw a surface plot

The following will plot the surface of a given function from $-5 <= x,y <= 5$. (This is a bit more complicated, so I don't want to include as much error checking for the inputs.)

The graphics here will be the function

proc g {x y} {expr sqrt(abs($x*$y))}

proc draw_surface { f } {
  set minx -5
  set maxx 5
  set miny -5
  set maxy 5
  set step 0.5
  # first, get the data (this isn't the most data efficient way of
  # doing things)
  for {set i $minx} {$i <= $maxx} {set i [expr $i + $step]} {
    for {set j $miny} {$j <= $maxy} {set j [expr $j + $step]} {
      set data($i,$j) [$f $i $j]
  # make another pass through to plot it
  for {set i $minx} {$i <= [expr $maxx - $step]} {set i [expr $i + $step]} {
    for {set j $miny} {$j <= [expr $maxy - $step]} {set j [expr $j + $step]} {
      # get the next two corners
      set i2 [expr $i + $step]
      set j2 [expr $j + $step]
      # find the middle
      set imiddle [expr $i + $step/2]
      set jmiddle [expr $j + $step/2]
      set kmiddle [expr ($data($i,$j) + $data($i2,$j) + $data($i2,$j2) \
		+ $data($i,$j2)) / 4.0]
      # use a cool coloring scheme (this depends on the graph having a min
      # value of 0 and max of 5, or at least less than about 30)
      draw color [expr 17 + [int [expr  200 * $kmiddle]] % 1024]
      # make 4 triangles
      draw triangle "$i $j $data($i,$j)" "$imiddle $jmiddle $kmiddle" \
                "$i2 $j $data($i2,$j)"
      draw triangle "$i $j $data($i,$j)" "$i $j2 $data($i,$j2)" \
                "$imiddle $jmiddle $kmiddle"
      draw triangle "$i2 $j2 $data($i2,$j2)" "$i2 $j $data($i2,$j)" \
                 "$imiddle $jmiddle $kmiddle"
      draw triangle "$i2 $j2 $data($i2,$j2)" "$imiddle $jmiddle $kmiddle" \
                "$i $j2 $data($i,$j2)"
And graph it with the command:
draw_surface g
Looks like it should be on a quilt, doesn't it?