Fixed a bug with small (but not epsilon) flonum bounds

This commit is contained in:
Neil Toronto 2011-11-25 23:16:23 -07:00
parent 11994bd4f8
commit 918c4e97a6
5 changed files with 48 additions and 37 deletions

View File

@ -84,11 +84,9 @@
;; (apply-bounds* elems), overridden at every iteration by the plot bounds (if given). Because a ;; (apply-bounds* elems), overridden at every iteration by the plot bounds (if given). Because a
;; fixpoint doesn't always exist, or only exists in the limit, it stops after max-iters. ;; fixpoint doesn't always exist, or only exists in the limit, it stops after max-iters.
(define (bounds-fixpoint elems given-bounds-rect [max-iters 4]) (define (bounds-fixpoint elems given-bounds-rect [max-iters 4])
(define res
(let/ec break (let/ec break
;; Shortcut eval: if the plot bounds are all given, the code below just returns them anyway ;; Shortcut eval: if the plot bounds are all given, the code below just returns them anyway
(when (rect-known? given-bounds-rect) (break given-bounds-rect)) (when (rect-known? given-bounds-rect) (break given-bounds-rect))
(let ([given-bounds-rect (rect-inexact->exact given-bounds-rect)])
;; Objective: find the fixpoint of F starting at given-bounds-rect ;; Objective: find the fixpoint of F starting at given-bounds-rect
(define (F bounds-rect) (rect-meet given-bounds-rect (apply-bounds* elems bounds-rect))) (define (F bounds-rect) (rect-meet given-bounds-rect (apply-bounds* elems bounds-rect)))
;; Iterate joint bounds to (hopefully) a fixpoint ;; Iterate joint bounds to (hopefully) a fixpoint
@ -108,17 +106,14 @@
[(and delta-area new-delta-area (new-delta-area . > . delta-area)) (break bounds-rect)] [(and delta-area new-delta-area (new-delta-area . > . delta-area)) (break bounds-rect)]
;; All good - one more iteration ;; All good - one more iteration
[else (values new-bounds-rect new-area new-delta-area)]))) [else (values new-bounds-rect new-area new-delta-area)])))
bounds-rect))) bounds-rect))
;(printf "fixpoint bounds-rect = ~v~n" res)
res)
;; Applies the bounds functions of multiple plot elements, in parallel, and returns the smallest ;; Applies the bounds functions of multiple plot elements, in parallel, and returns the smallest
;; bounds containing all the new bounds. This function is monotone and increasing regardless of ;; bounds containing all the new bounds. This function is monotone and increasing regardless of
;; whether any element's bounds function is. If iterating it is bounded, a fixpoint exists. ;; whether any element's bounds function is. If iterating it is bounded, a fixpoint exists.
(define (apply-bounds* elems bounds-rect) (define (apply-bounds* elems bounds-rect)
(rect-inexact->exact
(apply rect-join bounds-rect (for/list ([elem (in-list elems)]) (apply rect-join bounds-rect (for/list ([elem (in-list elems)])
(apply-bounds elem bounds-rect))))) (apply-bounds elem bounds-rect))))
;; Applies the plot element's bounds function. Asks this question: If these are your allowed bounds, ;; Applies the plot element's bounds function. Asks this question: If these are your allowed bounds,
;; what bounds will you try to use? ;; what bounds will you try to use?

View File

@ -291,6 +291,7 @@
;; Fixpoint margin computation ;; Fixpoint margin computation
(define (get-param-vs/set-view->dc! left right top bottom) (define (get-param-vs/set-view->dc! left right top bottom)
;(printf "margins = ~v ~v ~v ~v~n" left right top bottom)
(set! view->dc (make-view->dc left right top bottom)) (set! view->dc (make-view->dc left right top bottom))
(append (append* (map (λ (params) (send/apply pd get-text-corners params)) (append (append* (map (λ (params) (send/apply pd get-text-corners params))
(get-all-label-params))) (get-all-label-params)))
@ -372,9 +373,10 @@
(draw-axes) (draw-axes)
(draw-ticks) (draw-ticks)
(draw-labels) (draw-labels)
(define lw (plot-line-width))
(send pd set-clipping-rect (send pd set-clipping-rect
(vector (ivl (+ 1/2 (- area-x-min (plot-line-width))) (+ area-x-max (plot-line-width))) (vector (ivl (+ 1/2 (- area-x-min lw)) (+ area-x-max lw))
(ivl (+ 1/2 (- area-y-min (plot-line-width))) (+ area-y-max (plot-line-width)))))) (ivl (+ 1/2 (- area-y-min lw)) (+ area-y-max lw)))))
(define/public (start-renderer rend-bounds-rect) (define/public (start-renderer rend-bounds-rect)
(reset-drawing-params) (reset-drawing-params)

View File

@ -42,7 +42,7 @@
(match-define (vector x-ivl y-ivl) plot-bounds-rect) (match-define (vector x-ivl y-ivl) plot-bounds-rect)
(error 'plot "could not determine sensible plot bounds; got x ∈ ~a, y ∈ ~a" (error 'plot "could not determine sensible plot bounds; got x ∈ ~a, y ∈ ~a"
(ivl->plot-label x-ivl) (ivl->plot-label y-ivl))) (ivl->plot-label x-ivl) (ivl->plot-label y-ivl)))
plot-bounds-rect) (rect-inexact->exact plot-bounds-rect))
(define (get-ticks renderer-list bounds-rect) (define (get-ticks renderer-list bounds-rect)
(define-values (all-x-ticks all-x-far-ticks all-y-ticks all-y-far-ticks) (define-values (all-x-ticks all-x-far-ticks all-y-ticks all-y-far-ticks)
@ -65,7 +65,9 @@
(define legend-entries (define legend-entries
(flatten (for/list ([rend (in-list renderer-list)]) (flatten (for/list ([rend (in-list renderer-list)])
(match-define (renderer2d rend-bounds-rect _bf _tf render-proc) rend) (match-define (renderer2d rend-bounds-rect _bf _tf render-proc) rend)
(send area start-renderer (if rend-bounds-rect rend-bounds-rect (empty-rect 2))) (send area start-renderer (if rend-bounds-rect
(rect-inexact->exact rend-bounds-rect)
(unknown-rect 2)))
(if render-proc (render-proc area) empty)))) (if render-proc (render-proc area) empty))))
(send area end-renderers) (send area end-renderers)
@ -176,8 +178,9 @@
(define legend-entries (define legend-entries
(flatten (for/list ([rend (in-list renderer-list)]) (flatten (for/list ([rend (in-list renderer-list)])
(match-define (renderer2d rend-bounds-rect _bf _tf render-proc) rend) (match-define (renderer2d rend-bounds-rect _bf _tf render-proc) rend)
(send area start-renderer (send area start-renderer (if rend-bounds-rect
(if rend-bounds-rect rend-bounds-rect (empty-rect 2))) (rect-inexact->exact rend-bounds-rect)
(unknown-rect 2)))
(if render-proc (render-proc area) empty)))) (if render-proc (render-proc area) empty))))
(send area end-renderers) (send area end-renderers)

View File

@ -42,7 +42,7 @@
(match-define (vector x-ivl y-ivl z-ivl) plot-bounds-rect) (match-define (vector x-ivl y-ivl z-ivl) plot-bounds-rect)
(error 'plot "could not determine sensible plot bounds; got x ∈ ~a, y ∈ ~a, z ∈ ~a" (error 'plot "could not determine sensible plot bounds; got x ∈ ~a, y ∈ ~a, z ∈ ~a"
(ivl->plot-label x-ivl) (ivl->plot-label y-ivl) (ivl->plot-label z-ivl))) (ivl->plot-label x-ivl) (ivl->plot-label y-ivl) (ivl->plot-label z-ivl)))
plot-bounds-rect) (rect-inexact->exact plot-bounds-rect))
(define (get-ticks renderer-list bounds-rect) (define (get-ticks renderer-list bounds-rect)
(define-values (all-x-ticks all-x-far-ticks all-y-ticks all-y-far-ticks all-z-ticks all-z-far-ticks) (define-values (all-x-ticks all-x-far-ticks all-y-ticks all-y-far-ticks all-z-ticks all-z-far-ticks)
@ -73,7 +73,9 @@
(define legend-entries (define legend-entries
(flatten (for/list ([rend (in-list renderer-list)]) (flatten (for/list ([rend (in-list renderer-list)])
(match-define (renderer3d rend-bounds-rect _bf _tf render-proc) rend) (match-define (renderer3d rend-bounds-rect _bf _tf render-proc) rend)
(send area start-renderer (if rend-bounds-rect rend-bounds-rect (empty-rect 3))) (send area start-renderer (if rend-bounds-rect
(rect-inexact->exact rend-bounds-rect)
(unknown-rect 3)))
(if render-proc (render-proc area) empty)))) (if render-proc (render-proc area) empty))))
(send area end-renderers) (send area end-renderers)
@ -207,8 +209,9 @@
legend-entries-hash (plot-animating?) legend-entries-hash (plot-animating?)
(flatten (for/list ([rend (in-list renderer-list)]) (flatten (for/list ([rend (in-list renderer-list)])
(match-define (renderer3d rend-bounds-rect _bf _tf render-proc) rend) (match-define (renderer3d rend-bounds-rect _bf _tf render-proc) rend)
(send area start-renderer (cond [rend-bounds-rect rend-bounds-rect] (send area start-renderer (if rend-bounds-rect
[else (empty-rect 3)])) (rect-inexact->exact rend-bounds-rect)
(unknown-rect 3)))
(if render-proc (render-proc area) empty)))) (if render-proc (render-proc area) empty))))
(hash-set! render-list-hash (plot-animating?) (send area get-render-list))] (hash-set! render-list-hash (plot-animating?) (send area get-render-list))]

View File

@ -2,6 +2,14 @@
(require plot plot/utils unstable/flonum) (require plot plot/utils unstable/flonum)
(plot (points '(#(0 0)))
#:x-min +min.0 #:x-max (flstep +min.0 1000)
#:y-min 0 #:y-max 1)
(plot3d (points3d '(#(0 0 0)))
#:x-min +min.0 #:x-max (flstep +min.0 1000)
#:y-min 0 #:y-max 1 #:z-min 0 #:z-max 1)
(plot-x-label #f) (plot-x-label #f)
(plot-y-label #f) (plot-y-label #f)