From d5d21c858e194e789fc0298c3f4ea526f5f2bc46 Mon Sep 17 00:00:00 2001 From: Matthew Butterick Date: Thu, 2 Dec 2021 21:45:50 -0800 Subject: [PATCH] size and point --- quad/quad2/main.rkt | 73 +++++++++++++++++++++++---------------------- 1 file changed, 37 insertions(+), 36 deletions(-) diff --git a/quad/quad2/main.rkt b/quad/quad2/main.rkt index 098e141d..9f051ff6 100644 --- a/quad/quad2/main.rkt +++ b/quad/quad2/main.rkt @@ -1,20 +1,23 @@ #lang debug racket/base (require racket/contract racket/function rackunit) -(struct $posn (x y) #:transparent) +(struct $point (x y) #:transparent #:mutable) +(struct $size (width height) #:transparent #:mutable) +(struct $rect (origin size) #:transparent #:mutable) + (struct $quad (posn char) #:transparent #:mutable) (define/contract (posn-add p0 p1) - ($posn? $posn? . -> . $posn?) - ($posn (+ ($posn-x p0) ($posn-x p1)) (+ ($posn-y p0) ($posn-y p1)))) + ($point? $size? . -> . $point?) + ($point (+ ($point-x p0) ($size-width p1)) (+ ($point-y p0) ($size-height p1)))) (define/contract (size char) - ($quad? . -> . $posn?) - ($posn 1 1)) + ($quad? . -> . $size?) + ($size 1 1)) (define/contract (advance char) - ($quad? . -> . $posn?) - ($posn 1 0)) + ($quad? . -> . $size?) + ($size 1 0)) (define pass/c ((listof $quad?) . -> . (listof $quad?))) @@ -41,38 +44,36 @@ (error 'postcondition-failed)) res)) -(struct $rect (x y width height) #:transparent #:mutable) - -(define (min-x rect) ($rect-x rect)) -(define (max-x rect) (+ (min-x rect) ($rect-width rect))) -(define (min-y rect) ($rect-y rect)) -(define (max-y rect) (+ (min-y rect) ($rect-height rect))) +(define (min-x rect) ($point-x ($rect-origin rect))) +(define (width rect) ($size-width ($rect-size rect))) +(define (max-x rect) (+ (min-x rect) (width rect))) +(define (min-y rect) ($point-y ($rect-origin rect))) +(define (height rect) ($size-height ($rect-size rect))) +(define (max-y rect) (+ (min-y rect) (height rect))) -(define/contract (rect-contains-posn? rect posn) - ($rect? $posn? . -> . boolean?) - (and (<= (min-x rect) ($posn-x posn) (max-x rect)) - (<= (min-y rect) ($posn-y posn) (max-y rect)))) +(define/contract (rect-contains-point? rect pt) + ($rect? $point? . -> . boolean?) + (and (<= (min-x rect) ($point-x pt) (max-x rect)) + (<= (min-y rect) ($point-y pt) (max-y rect)))) (define/contract (rect-contains-rect? outer inner) ($rect? $rect? . -> . boolean?) - (and (rect-contains-posn? outer ($posn (min-x inner) (min-y inner))) - (rect-contains-posn? outer ($posn (max-x inner) (max-y inner))))) + (and (rect-contains-point? outer ($rect-origin inner)) + (rect-contains-point? outer ($point (max-x inner) (max-y inner))))) - (define (has-position? q) (not (eq? ($quad-posn q) #false))) (define-pass (layout qs) #:precondition (λ (qs) (andmap (λ (q) (not (has-position? q))) qs)) #:postcondition (λ (qs) (andmap has-position? qs)) - (define frame ($rect 0 0 5 30)) + (define frame ($rect ($point 0 0) ($size 5 30))) (define (quad-fits? q posn) (define q-size (size q)) - (define quad-rect ($rect ($posn-x posn) ($posn-y posn) - ($posn-x q-size) ($posn-y q-size))) + (define quad-rect ($rect posn q-size)) (and (rect-contains-rect? frame quad-rect) posn)) - (for/fold ([posn ($posn 0 0)] + (for/fold ([posn ($point 0 0)] #:result qs) ([q (in-list qs)]) - (define first-posn-on-next-line ($posn 0 (add1 ($posn-y posn)))) + (define first-posn-on-next-line ($point 0 (add1 ($point-y posn)))) (define winning-posn (or (ormap (λ (posn) (quad-fits? q posn)) (list posn first-posn-on-next-line)) (error 'no-posn-that-fits))) (set-$quad-posn! q winning-posn) (posn-add winning-posn (advance q)))) @@ -80,14 +81,14 @@ (define compile (make-compiler layout)) (check-equal? (compile "Hello world") (list - ($quad ($posn 0 0) #\H) - ($quad ($posn 1 0) #\e) - ($quad ($posn 2 0) #\l) - ($quad ($posn 3 0) #\l) - ($quad ($posn 4 0) #\o) - ($quad ($posn 0 1) #\space) - ($quad ($posn 1 1) #\w) - ($quad ($posn 2 1) #\o) - ($quad ($posn 3 1) #\r) - ($quad ($posn 4 1) #\l) - ($quad ($posn 0 2) #\d))) \ No newline at end of file + ($quad ($point 0 0) #\H) + ($quad ($point 1 0) #\e) + ($quad ($point 2 0) #\l) + ($quad ($point 3 0) #\l) + ($quad ($point 4 0) #\o) + ($quad ($point 0 1) #\space) + ($quad ($point 1 1) #\w) + ($quad ($point 2 1) #\o) + ($quad ($point 3 1) #\r) + ($quad ($point 4 1) #\l) + ($quad ($point 0 2) #\d))) \ No newline at end of file