diff --git a/pkgs/htdp/teachpack/2htdp/scribblings/image-guide.scrbl b/pkgs/htdp/teachpack/2htdp/scribblings/image-guide.scrbl index 496d486770..f106842d6e 100644 --- a/pkgs/htdp/teachpack/2htdp/scribblings/image-guide.scrbl +++ b/pkgs/htdp/teachpack/2htdp/scribblings/image-guide.scrbl @@ -324,6 +324,52 @@ And then put three of them together to form the Koch snowflake. (rotate -60 (koch-curve 5))) (flip-vertical (koch-curve 5)))] +@section[#:tag "rotate-center"]{Rotating and Image Centers} + +When rotating an image, some times the image looks best when it +rotates around a point that is not the center of the image. The +@racket[rotate] function, however, just rotates the image as +a whole, effectively rotating it around its center. + +For example, imagine a game where the hero is represented +as a triangle: +@image-interaction[(define (hero α) + (triangle 30 "solid" (color 255 0 0 α))) + (hero 255)] +rotating the hero at the prompt looks reasonable: +@image-interaction[(rotate 10 (hero 255)) + (rotate 20 (hero 255)) + (rotate 30 (hero 255))] +but if the hero has to appear to spin in place, then it will not look +right, as you can kind of see if we use α-blending to represent +old positions of the hero: +@image-interaction[(overlay (rotate 0 (hero 255)) + (rotate 10 (hero 125)) + (rotate 20 (hero 100)) + (rotate 30 (hero 75)) + (rotate 40 (hero 50)) + (rotate 50 (hero 25)))] +What we'd really want is for the hero to appear to rotate around +the centroid of the triangle. To achieve this effect, we can put +the hero onto a transparent rectangle such that the center of the whole +image is the centroid of the triangle: +@image-interaction[(define (hero-on-blank α) + (define the-hero (hero α)) + (define w (image-width the-hero)) + (define h (image-height the-hero)) + (define d (max w h)) + (define dx (/ w 2)) ; centroid + (define dy (* 2/3 h)) ; centroid + (define blank (rectangle (* 2 d) (* 2 d) "solid" (color 255 255 255 0))) + (place-image/align the-hero (- d dx) (- d dy) "left" "top" blank))] +and now the rotating hero looks reasonable: +@image-interaction[(overlay (rotate 0 (hero-on-blank 255)) + (rotate 10 (hero-on-blank 125)) + (rotate 20 (hero-on-blank 100)) + (rotate 30 (hero-on-blank 75)) + (rotate 40 (hero-on-blank 50)) + (rotate 50 (hero-on-blank 25)))] + @section[#:tag "nitty-gritty"]{The Nitty Gritty of Pixels, Pens, and Lines} The image library treats coordinates as if they are in the upper-left corner diff --git a/pkgs/htdp/teachpack/2htdp/scribblings/image.scrbl b/pkgs/htdp/teachpack/2htdp/scribblings/image.scrbl index 4e5646dcd3..80cd521c8b 100644 --- a/pkgs/htdp/teachpack/2htdp/scribblings/image.scrbl +++ b/pkgs/htdp/teachpack/2htdp/scribblings/image.scrbl @@ -1144,7 +1144,7 @@ the parts that fit onto @racket[scene]. @defproc[(rotate [angle angle?] [image image?]) image?]{ Rotates @racket[image] by @racket[angle] degrees in a counter-clockwise direction. - + @image-examples[(rotate 45 (ellipse 60 20 "solid" "olivedrab")) (rotate 5 (rectangle 50 50 "outline" "black")) (rotate 45 @@ -1153,11 +1153,13 @@ the parts that fit onto @racket[scene]. (rectangle 40 20 "solid" "darkseagreen") (rectangle 20 100 "solid" "darkseagreen")))] + See also @seclink["rotate-center"]. + } @defproc[(scale [factor (and/c real? positive?)] [image image?]) image?]{ - Scales @racket[image] by @racket[factor]. + Scales @racket[image] by @racket[factor]. The pen sizes are also scaled and thus draw thicker (or thinner) lines than the original image, unless the pen was size