[racket] Plotting in the x and y dimensions

From: Neil Toronto (neil.toronto at gmail.com)
Date: Tue Sep 17 12:55:43 EDT 2013

Interesting and useful!

Aside from a looming graduation deadline (for a PhD - yeah, BYU is 
weird), the only thing keeping me from generalizing the surface 
renderers like this is depth sorting. Because of transparency, and 
because plots have to be rendered in non-OpenGL contexts (e.g. PDFs, in 
which there's no depth buffer), polygons have to be sorted by their 
distance from the viewer and drawn back-to-front. I didn't initially 
take the time to do it properly. The current implementation sorts 
polygons by the centers of their bounding boxes, which sorts correctly 
for discretized f(x,y) surfaces and other x,y-grid-like things.

IIRC, its correctness depends on the x,y grid, and the view vector 
always pointing at the top of the z-min plane. It doesn't guarantee 
proper depth sorting otherwise, and I apologize for that.

If/when you get bad sorting, you could generate an isosurface3d renderer 
to draw the surface where the signed y or z distance from your function 
is zero, like this:

   (define (f x z) (* x z))
   (plot3d (isosurface3d (λ (x y z) (- y (f x z)))
                         0
                         -1 1 -1 1 -1 1))

This is basically how `polar3d' is implemented. Because it chops the 
entire plot into cubes, the produced polygons meet the depth sorter's 
assumptions. It's a lot slower than your solution, though, and ends up 
drawing extraneous contour lines.

I would like to eventually make the depth sorting robust.

Neil ⊥

On 09/16/2013 05:51 AM, Kieron Hardy wrote:
> In the plot collection, it currently seems possible to plot only in the
> z-dimension, i.e. plot functions where the z value is derived from some
> f(x,y)
>
> I needed the ability to plot functions where: x is derived from some
> f(y,z); and y is derived from some f(x,z). In case it is useful to
> others, my solution is on github at
> https://github.com/khardy/racket-surface3d.git
>
> I copied intact the existing surface3d form to create surface3d/z (i.e.
> calculate z from x and y) and then derived two new forms, surface/x and
> surface/y, that calculate values for the x and y dimensions
> respectively. Some refactoring could be useful, since the three forms
> differ only in the various permutations of which dimension's min's and
> max's and values get used where, but maybe not worth the effort for just
> those three.
>
> The new forms are in surface3d-xyz.rkt. The demo
> (surface3d-xyz-demo.rkt) below show drawing three surfaces, one each for
> part of the x, y, and z axes around the origin.
>
> Cheers,
>
> Kieron.
>
> ****
>
> #lang racket/base
>
> (require plot)
> (require "surface3d-xyz.rkt")
>
> (plot3d
>    (list
>      (surface3d/x
>        (lambda (y z) 0) ; plot x = 0
>        -2 2 ; y-min/y-max
>        -2 2 ; z-min/z-max
>        #:label "x = 0"
>        #:color 3
>        )
>      (surface3d/y
>        (lambda (x y) 0) ; plot y = 0
>        -2 2 ; x-min/x-max
>        -2 2 ; z-min/z-max
>        #:label "y = 0"
>        #:color 5
>        )
>      (surface3d/z
>        (lambda (x y) 0) ; plot z = 0
>        -2 2 ; x-min/x-max
>        -2 2 ; y-min/y-max
>        #:label "z = 0"
>        #:color 7
>        )
>      )
>    #:x-min -3 #:x-max 3
>    #:y-min -3 #:y-max 3
>    #:z-min -3 #:z-max 3
>    #:altitude 25
>    )
>
>
>
> ____________________
>    Racket Users list:
>    http://lists.racket-lang.org/users
>


Posted on the users mailing list.