NetLogo version NetLogo 3.1.1
Running with NetLogoLite.jar version 314.
NetLogo Version: NetLogo 3.1.1
;;;; SUMMARY ;; Import PPM images into turtle-based sprites ;;;; Copyright ;; Copyright (C) 2004/2005 James P. Steiner ;; Portions (C) 2004 Uri Wilensky ;; See code for licensing and usage. ;; globals [ ] breed [ pixels ] breed [ sprites ] sprites-own [ spr-height spr-width spr-max-value spr-first-pixel spr-pixel-list spr-pixel-set spr-name spr-scale spr-trans-color ;; the transparent color ] pixels-own [ pix-x pix-y pix-r ; original r value pix-g ; original b value pix-b ; original g value pix-c ; original color value pix-spr-id ] to import-sprite ask new-sprite [ sprite-import-ppm sprite-file-name ] clear-output output-print "Sprites:" ask sprites [ output-print self ] end to spin-sprites no-display ask sprites [ home set heading heading + 5 + 5 * who mod 3 jump max-pxcor * .66 sprite-paint-nowrap ] every 1 / stamp-rate [ if stamp?[ stamp-sprites ]] display end to stamp-sprites ask sprites [ sprite-to-patches ] end ;; the sprite turtle is used to manage the pixel turtles to-report new-sprite let results nobody create-custom-sprites 1 [ set results self ] report results end ;; these procedures import a "plain" (ascii) PPM (Portable Pixel Map). ;; a sprite turtle is created to manage the pixel turtles. to sprite-import-ppm [ pathname ] ;; error trapping wrapper for sprite-import-ppm-contents ;; reports a turtle of breed sprite ;; USER-CHOOSE-FILE returns false if the user cancels, so this ;; check is here to handle that case, or if the path is blank if not is-string? pathname or pathname = "" [ stop ] carefully [ file-open (word "data/" pathname ) sprite-import-ppm-contents ] ;; error handler for "carefully" [ user-message (word pathname " is not a valid ASCII format PPM file: (" error-message ")." ) ] file-close end to sprite-to-patches ;; run by a sprite turtle ;; causes the pixel turtles to imprint their color into the pcolor of the patch. ;; if patches own ppix-r, ppix-g and ppix-b, will copy pix-r, -g, -b into the patch, too. ;; this preserves the original color values, rather than the "covertered" values ;; one might get using "extract-rgb" on the pcolor. ifelse is-patch-variable? "ppix-r" [ ask pixels with [ pix-spr-id = myself and not (transparent? and color = spr-trans-color-of myself )] [ set pcolor color run "set ppix-r pix-r set ppix-g pix-g set ppix-b pix-b" ] ] [ ask pixels with [ pix-spr-id = myself and not (transparent? and color = spr-trans-color-of myself )] [ set pcolor color ] ] end to-report is-patch-variable? [ varname-string ] let is-a-variable? false carefully [ ask patch 0 0 [ set is-a-variable? run-result "ppix-r = ppix-r" ] set is-a-variable? true ] [ set is-a-variable? false ] report is-a-variable? end to sprite-import-ppm-contents ;; check magic number if read-pnm-entry != "P3" [ user-message "This is not a valid ASCII format PPM file (magic number is not P3)" stop ] ;; assumes this code is run by a turtle. ;; any turtle that runs this code becomes a sprite set breed sprites set shape "blank" set color white set heading 0 set spr-scale 1 set hidden? true ;; get width, height, and white value set spr-width read-from-string read-pnm-entry set spr-height read-from-string read-pnm-entry set spr-max-value read-from-string read-pnm-entry let max-value spr-max-value ;; adjust x and y to new origin. ;; sprite x y is origin let x-offset int ( spr-width / -2 ) let y-offset int ( spr-height / 2 ) ;; read the actual pixel values ;; create pixel turtles, assign to sprite let x 0 let y 0 while [y < spr-height] [ set x 0 while [x < spr-width] [ ;; convert from sprite coordinates to relative patch-at coordinates ;; (in patch-at coordinates, the origin is in the center, ;; not the top left, and y coordinates increase going up, ;; not going down) hatch 1 [ set breed pixels set heading 0 set shape "square-pixel" ;; read R G B values from file set pix-r ( read-from-string read-pnm-entry ) / max-value set pix-g ( read-from-string read-pnm-entry ) / max-value set pix-b ( read-from-string read-pnm-entry ) / max-value ;; set location set pix-x x-offset + x set pix-y y-offset - y ;; assign to sprite turtle set pix-spr-id myself set pix-c rgb pix-r pix-g pix-b set color pix-c setxy pix-x pix-y set hidden? true ] set x x + 1 ] set y y + 1 ] ;; assign pixel agentset to sprite set spr-pixel-set pixels with [ pix-spr-id = myself ] set spr-trans-color 9.9 end to hide-pixel ifelse (transparent? and (color = spr-trans-color-of pix-spr-id) ) [ if not hidden? [ hide-turtle ] ] [ if hidden? [ show-turtle ] ] end to hide-pixel-nowrap [ wrapped? ] ifelse wrapped? or (transparent? and (color = spr-trans-color-of pix-spr-id) ) [ if not hidden? [ hide-turtle ] ] [ if hidden? [ show-turtle ] ] end to sprite-paint let ox xcor let oy ycor ask spr-pixel-set [ setxy ( ox + pix-x ) ( oy + pix-y ) hide-pixel ] end to sprite-paint-nowrap ifelse xcor + .5 * spr-width <= max-pxcor and xcor - .5 * spr-width >= min-pxcor and ycor + .5 * spr-height <= max-pycor and ycor - .5 * spr-height >= min-pycor [ sprite-paint ] [ let ox xcor let oy ycor ask spr-pixel-set [ let new-x ox + pix-x let new-y oy + pix-y setxy new-x new-y hide-pixel-nowrap (new-x != xcor or new-y != ycor) ] ] end to sprite-paint-scale [ amount pix-amount ] ;; amount adjusts pixel spacing ;; pix-amount adjusts relative pixel size set spr-scale amount let ox xcor let oy ycor ask spr-pixel-set [ let new-x ox + pix-x * amount let new-y oy + pix-y * amount set hidden? off-screen? new-x new-y setxy new-x new-y set size amount * pix-amount ] end to sprites-reset ask sprites [ sprite-paint-scale 1 1 ] ask pixels [ set heading 0 ] end to-report on-screen? [ x y ] report (abs x <= max-pxcor or abs y <= max-pycor) end to-report off-screen? [ x y ] report (abs x > max-pxcor or abs y > max-pycor) end to sprite-hide hide-turtle ask spr-pixel-set [ hide-turtle ] end to sprite-show show-turtle ask spr-pixel-set [ show-turtle ] end to sprite-die ask spr-pixel-set [ die ] die end to-report pix-real-x report (xcor-of pix-spr-id) + pix-x end to-report pix-real-y report (ycor-of pix-spr-id) + pix-y end ;; reads the next entry in a "plain" (ascii) pnm file ;; i.e. pgm P2, ppm P3 ;; - an error occurs if there are no more entries ;; - entries are separated by arbitrary whitespace ;; - characters on a line after "#" are comments to-report read-pnm-entry ;; get next character let c file-read-characters 1 ;; ignore leading whitespace while [whitespace-char? c] [ set c file-read-characters 1 ] ;; skip comments if c = "#" [ ;; first skip the comment itself while [c != "\n" and c != "\r"] [ set c file-read-characters 1 ] ;; then skip linefeeds and/or newlines at end of comment while [c = "\n" or c = "\r"] [ set c file-read-characters 1 ] ] ;; read the entry let str "" while [not whitespace-char? c] [ set str str + c set c file-read-characters 1 ] report str end ;; reports true if c is a single whitespace character to-report whitespace-char? [c] report c = " " or c = "\t" or ;; tab c = "\n" or ;; newline c = "\r" ;; linefeed end ; (C) 2004 James Steiner, Uri Wilensky. ; This code may be freely copied, distributed, ; altered, or otherwise used by anyone for any legal purpose. ; ; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ; "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ; LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ; A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ; OWNERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ; SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ; LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ; DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ; THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ; OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
View or download the complete model file (to download: right-click, save-link-as):
-- Download ppm-image-import-with-sprites_2-1 --