As in the squirrel post, this image is the result of some of our summer research. It demonstrates three new Scheme procedures, image-transform-hshear!, image-transform-vshear!, and image-rotate-selection!. The code that generates this particular image can be found at the bottom of this post. The first 66 lines of the code are the definitions and documentation for the new Scheme procedures; the portion of the code that actually generates the image follows the procedure definitions.
image-transform-hshear! and image-transform-vshear! both take 2 parameters: an image and magnitude, a real number. When either function is called, they transform the selection on the given image by shearing it to the given magnitude. The direction of the shear depends on whether the called function is hshear or vshear: hshears shear the image horizontally, while vshears shear the image vertically.
In the image above, each of the rectangles are sheared horizontally and the degree to which they are sheared increases from left to right. For example, the magnitude of the hshear on the leftmost rectangle is -10, while the rectangle to its immediate right has been sheared by -20. The magnitude of the shear for each subsequent rectangle is double the magnitude of the rectangle before it. After the second rectangle is sheared with a magnitude of -20, the remaining rectangles from left to right are sheared by magnitudes of -40, -80 and -160.
After each rectangular selection is sheared, the student rotates the selection to create the “domino” effect seen above. The image-rotate-selection! procedure, like the shear procedures above, takes 2 parameters: an image, and angle, a real number. When image-rotate-selection! is called, it rotates the current selection on the image by the angle given. In the student’s example, the first rectangle is not rotated at all. The remaining four rectangles, however, are rotated by 10, 20, 45, and 60 degrees (from left to right).
After each rectangle is sheared and rotated the desired amount, it is filled in with the current foreground color using the image-fill-selection! procedure. After each rectangle is finished, the student must “flatten” the image to merge each of its layers.
Here is the code for the image:
<pre>;;; Procedure:
;;; image-transform-hshear!
;;; image-transform-vshear!
;;; Parameters:
;;; image, an image
;;; magnitude, a real
;;; Pre-conditions:
;;; image must be a valid image
;;; Purpose:
;;; transforms selection by shearing based on magnitude
;;; Produces:
;;; [Nothing, called for side effect]
(define _image-transform-hshear!
(lambda (image magnitude)
(gimp-drawable-transform-shear-default (image-get-layer image)
0 magnitude TRUE 0)
(cond ((context-immediate-updates?) (context-update-displays!)))
image))
(define image-transform-hshear!
(guard-proc 'image-transform-hshear!
_image-transform-hshear!
(list 'image 'number)
(list image? number?)))
(define _image-transform-vshear!
(lambda (image magnitude)
(gimp-drawable-transform-shear-default (image-get-layer image)
1 magnitude TRUE 0)
(cond ((context-immediate-updates?) (context-update-displays!)))
image))
(define image-transform-vshear!
(guard-proc 'image-transform-vshear!
_image-transform-vshear!
(list 'image 'number)
(list image? number?)))
;;; Procedure:
;;; image-rotate-selection!
;;; Parameters:
;;; image, an image
;;; angle, a real number
;;; Purpose:
;;; Rotate the current selection around the center of the bounding box
;;; of the selection by an angle (degrees)
;;; Produces:
;;; [Nothing; Called for the side effects.]
(define _image-rotate-selection!
(lambda (image angle)
(gimp-drawable-transform-rotate-default (image-get-layer image)
(* angle (/ pi 180))
TRUE
0 0
TRUE
0
)))
(define image-rotate-selection!
(guard-proc 'image-rotate-selection!
_image-rotate-selection!
(list 'image 'real)
(list image? real?)))
(define image1 (image-new 600 500))
(image-show image1)
(context-set-fgcolor! "mediumaquamarine")
(image-select-rectangle! image1 REPLACE 20 90 50 100)
(image-fill-selection! image1)
(context-set-fgcolor! "white")
(image-select-rectangle! image1 REPLACE 90 90 50 100)
(image-transform-hshear! image1 -10)
(image-fill-selection! image1)
(image-flatten! image1)
(image-select-rectangle! image1 REPLACE 180 100 50 100)
(image-transform-hshear! image1 -20)
(image-rotate-selection! image1 10)
(image-fill-selection! image1)
(image-flatten! image1)
(image-select-rectangle! image1 REPLACE 280 135 50 100)
(image-transform-hshear! image1 -40)
(image-rotate-selection! image1 20)
(image-fill-selection! image1)
(image-flatten! image1)
(image-select-rectangle! image1 REPLACE 380 220 50 100)
(image-transform-hshear! image1 -80)
(image-rotate-selection! image1 45)
(image-fill-selection! image1)
(image-flatten! image1)
(image-select-rectangle! image1 REPLACE 450 350 50 100)
(image-transform-hshear! image1 -160)
(image-rotate-selection! image1 60)
(image-fill-selection! image1)
(image-flatten! image1)
(context-update-displays!)
