[racket] Plotting in the x and y dimensions
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
>