From 80bd94953194bfc9432a1e9c111ac0d51a6a1b05 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Wed, 15 Jun 2011 12:58:00 -0600 Subject: [PATCH] add mode to `arc' in `dc-path%' to support right/bottom alignment --- collects/racket/draw/private/dc-path.rkt | 10 +++++---- collects/scribblings/draw/dc-path-class.scrbl | 21 ++++++++++++++----- 2 files changed, 22 insertions(+), 9 deletions(-) diff --git a/collects/racket/draw/private/dc-path.rkt b/collects/racket/draw/private/dc-path.rkt index 12257fc433..711b50161e 100644 --- a/collects/racket/draw/private/dc-path.rkt +++ b/collects/racket/draw/private/dc-path.rkt @@ -191,7 +191,7 @@ rev-open-points))) (def/public (arc [real? x] [real? y] - [nonnegative-real? w] [nonnegative-real? h] + [real? w] [real? h] [real? start] [real? end] [any? [ccw? #t]]) (do-arc x y w h start end ccw?)) @@ -209,6 +209,8 @@ ;; Change top-left to center: (let ([x (+ x (/ w 2.0))] [y (+ y (/ h 2.0))] + [w (abs w)] + [h (abs h)] [pts null]) ;; make up to 4 curves to represent the arc: (let loop ([start start] @@ -382,13 +384,13 @@ (* (min w h) (- radius)) radius))]) (move-to (+ x (- w dx)) y) - (arc (+ x (- w (* 2 dx))) y (* 2 dx) (* 2 dy) pi/2 0.0 #f) + (arc (+ x w) y (* -2 dx) (* 2 dy) pi/2 0.0 #f) (line-to (+ x w) (+ y dy)) (line-to (+ x w) (+ y (- h dy))) - (arc (+ x (- w (* 2 dx))) (+ y (- h (* 2 dy))) (* 2 dx) (* 2 dy) 0 (- pi/2) #f) + (arc (+ x w) (+ y h) (* -2 dx) (* -2 dy) 0 (- pi/2) #f) (line-to (+ x (- w dx)) (+ y h)) (line-to (+ x dx) (+ y h)) - (arc x (+ y (- h (* 2 dy))) (* 2 dx) (* 2 dy) (- pi/2) (- pi) #f) + (arc x (+ y h) (* 2 dx) (* -2 dy) (- pi/2) (- pi) #f) (line-to x (+ y (- h dy))) (line-to x (+ y dy)) (arc x y (* 2 dx) (* 2 dy) pi pi/2 #f) diff --git a/collects/scribblings/draw/dc-path-class.scrbl b/collects/scribblings/draw/dc-path-class.scrbl index 936c1cfc4d..4fbeaed8bb 100644 --- a/collects/scribblings/draw/dc-path-class.scrbl +++ b/collects/scribblings/draw/dc-path-class.scrbl @@ -57,19 +57,30 @@ Adds the sub-paths of @scheme[path] to @this-obj[]. @tech{Closed @defmethod[(arc [x real?] [y real?] - [width (and/c real? (not/c negative?))] - [height (and/c real? (not/c negative?))] + [width real?] + [height real?] [start-radians real?] [end-radians real?] [counter-clockwise? any/c #t]) void?]{ Extends or starts the path's @tech{open sub-path} with a curve that - corresponds to a section of an ellipse. The ellipse is the one + corresponds to a section of an ellipse. If @racket[width] and @racket[height] + are non-negative, the ellipse is the one bounded by a rectangle whose top-left corner is @math{(@scheme[x], @scheme[y])} and whose dimensions are @scheme[width] by - @scheme[height]. The ellipse section starts a the angle - @scheme[start-radians] (@scheme[0] is three o'clock and half-pi is + @scheme[height]; if @racket[width] is negative, then + the rectangle's right edge is @racket[x], and the ellipse + width is @racket[(abs width)], while a negative @racket[height] + similarly makes @racket[y] is the bottom edge of the ellipse and + the height @racket[(abs height)]. + @margin-note*{Support for negative @racket[width] and @racket[height] + helps avoid round-off problems for aligned drawing in an eventual + destination, since @method[dc-path% arc] reduces its input to a sequence of curves. + In contrast, @xmethod[dc<%> draw-arc] can automatically correct for round off, + since the drawing mode is known immediately.} + The ellipse section starts a the angle + @scheme[start-radians] (@scheme[0] is three o'clock and half-π is twelve o'clock) and continues to the angle @scheme[end-radians]; if @scheme[counter-clockwise?] is true, then the arc runs counter-clockwise from @scheme[start-radians] to