Skip to content

Commit 8328b90

Browse files
benknoblesoegaard
authored andcommitted
add flip-x and flip-y
Close #29. Co-authored-by: Jens Axel Søgaard <[email protected]>
1 parent 6b6526e commit 8328b90

File tree

3 files changed

+94
-0
lines changed

3 files changed

+94
-0
lines changed

pict-doc/pict/scribblings/pict.scrbl

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -938,6 +938,20 @@ scale while drawing the original @racket[pict].
938938

939939
}
940940

941+
@defproc*[([(flip-x [pict pict-convertible?]) pict?]
942+
[(flip-y [pict pict-convertible?]) pict?])]{
943+
Flips a pict drawing horizontally or vertically.
944+
945+
@examples[#:eval ss-eval
946+
(standard-fish 100 50)
947+
(flip-x (standard-fish 100 50))
948+
(flip-x (flip-x (standard-fish 100 50)))
949+
(flip-y (standard-fish 100 50))
950+
(flip-y (flip-y (standard-fish 100 50)))
951+
(flip-y (flip-x (standard-fish 100 50)))
952+
(flip-x (flip-y (standard-fish 100 50)))]
953+
}
954+
941955
@defproc*[([(scale-to-fit [pict pict-convertible?] [size-pict pict-convertible?]
942956
[#:mode mode (or/c 'preserve 'inset
943957
'preserve/max 'inset/max

pict-lib/pict/private/utils.rkt

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,8 @@
6767
(provide/contract
6868
[scale (case-> (-> pict-convertible? number? number? pict?)
6969
(-> pict-convertible? number? pict?))]
70+
[flip-x (-> pict-convertible? pict?)]
71+
[flip-y (-> pict-convertible? pict?)]
7072
[scale-to-fit (->* (pict-convertible? (or/c number? pict-convertible?))
7173
(number? #:mode (or/c 'preserve 'inset 'preserve/max 'inset/max 'distort))
7274
pict?)]
@@ -1305,6 +1307,62 @@
13051307
(pict-last p))]
13061308
[(p factor) (scale p factor factor)]))
13071309

1310+
(define/match (compose-trans _t1 _t2)
1311+
[{(vector a d b e c f) (vector g j h k i l)}
1312+
(vector (+ (* a g) (* b j)) (+ (* d g) (* e j))
1313+
(+ (* a h) (* b k)) (+ (* d h) (* e k))
1314+
(+ (* a i) (* b l) c) (+ (* d i) (* e l) f))])
1315+
1316+
(define (compose-trans* t0 . ts)
1317+
(foldl (λ (t acc) (compose-trans acc t)) t0 ts))
1318+
1319+
(define (make-translate h k)
1320+
(vector 1 0 0 1 h k))
1321+
1322+
(define (make-flip-x) ; around y-axis
1323+
(vector -1 0 0 1 0 0))
1324+
1325+
(define (flip-x p)
1326+
(define w (pict-width p))
1327+
(define h (pict-height p))
1328+
(dc (λ (dc x y)
1329+
;; ( x, y) is the top-left corner
1330+
;; (cx,cy) is the center of the pict
1331+
(define cx (+ x (/ w 2)))
1332+
(define cy (+ y (/ h 2)))
1333+
(define old-t (send dc get-initial-matrix))
1334+
(define new-t (compose-trans*
1335+
(make-translate cx cy)
1336+
(make-flip-x)
1337+
(make-translate (- cx) (- cy))
1338+
old-t))
1339+
(send dc set-initial-matrix new-t)
1340+
(draw-pict p dc x y)
1341+
(send dc set-initial-matrix old-t))
1342+
w h))
1343+
1344+
(define (make-flip-y)
1345+
(vector 1 0 0 -1 0 0))
1346+
1347+
(define (flip-y p)
1348+
(define w (pict-width p))
1349+
(define h (pict-height p))
1350+
(dc (λ (dc x y)
1351+
;; ( x, y) is the top-left corner
1352+
;; (cx,cy) is the center of the pict
1353+
(define cx (+ x (/ w 2)))
1354+
(define cy (+ y (/ h 2)))
1355+
(define old-t (send dc get-initial-matrix))
1356+
(define new-t (compose-trans*
1357+
(make-translate cx cy)
1358+
(make-flip-y)
1359+
(make-translate (- cx) (- cy))
1360+
old-t))
1361+
(send dc set-initial-matrix new-t)
1362+
(draw-pict p dc x y)
1363+
(send dc set-initial-matrix old-t))
1364+
w h))
1365+
13081366
(define (translate p dx dy #:extend-bb? [bb? #f])
13091367
(define nw (if (not bb?) (pict-width p) (+ (pict-width p) (abs dx))))
13101368
(define nh (if (not bb?) (pict-height p) (+ (pict-height p) (abs dy))))

pict-test/tests/pict/main.rkt

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -740,3 +740,25 @@
740740
[alg (in-list layout-algs)])
741741
(define t (rand-bin-tree))
742742
(check-pict=? (alg t) (alg t #:transform values))))
743+
744+
(test-case "Flips"
745+
(define fish (standard-fish 100 50))
746+
(check-pict=? (flip-x (flip-x fish)) fish)
747+
(check-pict=? (flip-y (flip-y fish)) fish)
748+
(check-pict=? (flip-x (flip-y fish))
749+
(flip-y (flip-x fish)))
750+
;; borders cause problems:
751+
;; https://github.com/racket/pict/pull/78#issuecomment-1479939570
752+
;; https://github.com/racket/draw/pull/26
753+
(define oval (filled-ellipse 20 30 #:draw-border? #f))
754+
(check-pict=? (flip-x oval) oval)
755+
(check-pict=? (flip-y oval) oval)
756+
(define (get-bounding-box p)
757+
(map (λ (f) (f p)) (list pict-width pict-height pict-descent pict-ascent)))
758+
;; proof that "scale" with -1 factors is "wrong"
759+
(check-not-equal? (get-bounding-box (flip-x fish))
760+
(get-bounding-box (scale fish -1 1)))
761+
(check-not-equal? (get-bounding-box (flip-y fish))
762+
(get-bounding-box (scale fish 1 -1)))
763+
(check-not-equal? (get-bounding-box (flip-x oval)) (get-bounding-box (scale oval -1 1)))
764+
(check-not-equal? (get-bounding-box (flip-y oval)) (get-bounding-box (scale oval 1 -1))))

0 commit comments

Comments
 (0)