home *** CD-ROM | disk | FTP | other *** search
/ Enter 2004 August / ENTER.ISO / files / gimp-2.0.5-i586-setup.exe / {app} / share / gimp / 2.0 / scripts / spyrogimp.scm < prev    next >
Encoding:
GIMP Script-Fu Script  |  2004-09-26  |  12.6 KB  |  373 lines

  1. ;; spyrogimp.scm -*-scheme-*-
  2. ;; Draws Spirographs, Epitrochoids and Lissajous Curves.
  3. ;; More info at http://netword.com/*spyrogimp
  4. ;; Version 1.2
  5. ;;
  6. ;; Copyright (C) 2003 by Elad Shahar <elad@wisdom.weizmann.ac.il>
  7. ;; 
  8. ;; This program is free software; you can redistribute it and/or
  9. ;; modify it under the terms of the GNU General Public License
  10. ;; as published by the Free Software Foundation; either version 2
  11. ;; of the License, or (at your option) any later version.
  12. ;; 
  13. ;; This program is distributed in the hope that it will be useful,
  14. ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16. ;; GNU General Public License for more details.
  17. ;; 
  18. ;; You should have received a copy of the GNU General Public License
  19. ;; along with this program; if not, write to the Free Software
  20. ;; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  21.  
  22. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  23.  
  24. ; Internal function to draw the spyro.
  25. (define (script-fu-spyrogimp-internal img drw 
  26.              x1 y1 x2 y2   ; Bounding box.
  27.              type          ; = 0 (Spirograph), 1 (Epitrochoid), 2(Lissajous) .
  28.              shape         ; = 0 (Circle), 1 (Frame), >2 (Polygons) .
  29.              oteeth iteeth ; Outer and inner teeth.
  30.              margin hole-ratio 
  31.              start-angle   ; 0 <= start-angle < 360 .
  32.              tool          ; = 0 (Pencil), 1 (Brush), 2 (Airbrush) .
  33.              brush
  34.              color-method  ; = 0 (Single color), 1 (Grad. Loop Sawtooth), 2 (Grad. Loop triangle) .
  35.              color         ; Used when color-method = Single color .
  36.              grad          ; Gradient used in Gradient color methods.
  37.              )
  38.  
  39.     ; Find minimum number n such that it is divisible by both a and b.
  40.     ; (least common multiplier)
  41.     (define (calc-min-mult a b)
  42.       (let* ((c 1) (fac 2) (diva 0) (divb 0))
  43.         (while ( <= fac (max a b) )
  44.           (set! diva ( = 0 (fmod (/ a fac) 1) ) )
  45.           (set! divb ( = 0 (fmod (/ b fac) 1) ) )
  46.  
  47.           (if diva (set! a (/ a fac)))
  48.           (if divb (set! b (/ b fac)))
  49.  
  50.           (if (or diva divb) 
  51.                 (set! c (* c fac))
  52.                 (set! fac (+ 1 fac)) )
  53.         )
  54.         c
  55.       )
  56.     )
  57.  
  58.  
  59.   ; This function returns a list of samples according to the gradient.
  60.   (define (get-gradient steps color-method grad)
  61.     (if (= color-method 1)
  62.         ; option 1
  63.         ; Just return the gradient
  64.         (cdr (gimp-gradients-get-gradient-data grad (min steps 50) FALSE))
  65.  
  66.         ; option 2
  67.         ; The returned list is such that the gradient appears two times, once
  68.         ; in the normal order and once in reverse. This way there are no color
  69.         ; jumps if we go beyond the edge
  70.         (let* (
  71.                 ; Sample the gradient into array "gr".
  72.                 (gr (cdr (gimp-gradients-get-gradient-data grad (/ (min steps 50) 2) FALSE)))
  73.                                                     
  74.                 (grn (car gr))  ; length of sample array.
  75.                 (gra (cadr gr)) ; array of color samples (R1,G1,B1,A1, R2,....)
  76.  
  77.                 ; Allocate array gra-new of size  (2 * grn) - 8,
  78.                 ; but since each 4 items is actually one (RGBA) tuple, 
  79.                 ; it contains 2x - 2 entries.
  80.                 (grn-new (+ grn grn -8))
  81.                 (gra-new (cons-array grn-new 'double))
  82.  
  83.                 (gr-index 0)
  84.                 (gr-index2 0)
  85.               )
  86.  
  87.               ; Copy original array gra to gra_new.
  88.               (while (< gr-index grn)
  89.                  (aset gra-new gr-index (aref gra gr-index))
  90.                  (set! gr-index (+ 1 gr-index))
  91.               )
  92.  
  93.               ; Copy second time, but in reverse
  94.               (set! gr-index2 (- gr-index 8))
  95.               (while (< gr-index grn-new)
  96.                  (aset gra-new gr-index (aref gra gr-index2))
  97.                  (set! gr-index (+ 1 gr-index))
  98.                  (set! gr-index2 (+ 1 gr-index2))
  99.  
  100.                  (if (= (fmod gr-index 4) 0)
  101.                    (set! gr-index2 (- gr-index2 8))
  102.                  )
  103.               )
  104.  
  105.               ; Return list.
  106.               (list grn-new gra-new)
  107.         )
  108.     )
  109.   )  
  110.  
  111.  
  112.   (let* ((steps (+ 1 (calc-min-mult oteeth iteeth)))
  113.          (*points* (cons-array (* steps 2) 'double))
  114.  
  115.          (ot 0)                         ; current outer tooth
  116.          (cx 0)                         ; Current x,y
  117.          (cy 0)
  118.  
  119.          ; Save old foreground color, brush, opacity and paint mode
  120.          (old-fg-color (car (gimp-palette-get-foreground)))
  121.          (old-brush (car (gimp-brushes-get-brush)))
  122.          (old-opacity (car (gimp-brushes-get-opacity)))
  123.          (old-paint-mode (car (gimp-brushes-get-paint-mode)))
  124.  
  125.          ; If its a polygon or frame, how many sides does it have.
  126.          (poly (if (= shape 1) 4   ; A frame has four sides.
  127.                               (if (> shape 1) (+ shape 1) 0)))
  128.  
  129.      (2pi (* 2 *pi*))
  130.         
  131.      (drw-width (- x2 x1))
  132.      (drw-height (- y2 y1))
  133.      (half-width (/ drw-width 2))
  134.      (half-height (/ drw-height 2))
  135.          (midx (+ x1 half-width))
  136.          (midy (+ y1 half-height))
  137.  
  138.          (hole (* hole-ratio 
  139.                   (- (/ (min drw-width drw-height) 2) margin)
  140.                )
  141.          )
  142.          (irad (+ hole margin))
  143.  
  144.          (radx (- half-width irad))  ; 
  145.          (rady (- half-height irad)) ; 
  146.  
  147.          (gradt (get-gradient steps color-method grad))
  148.          (grada (cadr gradt)) ; Gradient array.
  149.          (gradn (car gradt))  ; Number of entries of gradients.
  150.  
  151.          ; Indexes
  152.          (grad-index 0)  ; for array: grada
  153.          (point-index 0) ; for array: *points*
  154.      (index 0)
  155.      )
  156.  
  157.  
  158.     ; Do one step of the loop.
  159.     (define (calc-and-step!)
  160.       (let* (
  161.              (oangle (* 2pi (/ ot oteeth)) )
  162.              (shifted-oangle (+ oangle (* 2pi (/ start-angle 360))) )
  163.              (xfactor (cos shifted-oangle))
  164.              (yfactor (sin shifted-oangle))
  165.              (lenfactor 1)
  166.              (ofactor (/ (+ oteeth iteeth) iteeth))
  167.  
  168.              ; The direction of the factor changes according
  169.              ; to whether the type is a sypro or an epitcorhoid.
  170.              (mfactor (if (= type 0) (- ofactor) ofactor))
  171.             )
  172.  
  173.         ; If we are drawing a polygon then compute a contortion
  174.         ; factor "lenfactor" which deforms the standard circle.
  175.         (if (> poly 2)
  176.           (let* (
  177.                   (pi4 (/ *pi* poly))
  178.                   (pi2 (* pi4 2))
  179.  
  180.                   (oanglemodpi2 (fmod (+ oangle 
  181.                                         (if (= 1 (fmod poly 2))
  182.                                            0 ;(/ pi4 2)
  183.                                            0 
  184.                                         )
  185.                                       )
  186.                                       pi2
  187.                                ))
  188.                 )
  189.                 (set! lenfactor (/ ( if (= shape 1) 1 (cos pi4) )
  190.                                    (cos
  191.                                      (if (< oanglemodpi2 pi4)
  192.                                        oanglemodpi2
  193.                                        (- pi2 oanglemodpi2)
  194.                                      )
  195.                                    )
  196.                                 )
  197.                 )
  198.           )
  199.         )
  200.  
  201.         (if (= type 2)
  202.           (begin  ; Lissajous
  203.             (set! cx (+ midx
  204.                         (* half-width (cos shifted-oangle)) ))
  205.             (set! cy (+ midy
  206.                         (* half-height (cos (* mfactor oangle))) ))
  207.           )
  208.           (begin  ; Spyrograph or Epitrochoid
  209.            (set! cx (+ midx
  210.                        (* radx xfactor lenfactor)
  211.                        (* hole (cos (* mfactor oangle) ) ) ))
  212.            (set! cy (+ midy
  213.                        (* rady yfactor lenfactor)
  214.                        (* hole (sin (* mfactor oangle) ) ) ))
  215.           )
  216.         )
  217.  
  218.       ;; Advance teeth
  219.       (set! ot (+ ot 1))
  220.     ))
  221.  
  222.  
  223.     ;; Draw all the points in *points* with appropriate tool.
  224.     (define (flush-points len)
  225.  
  226.         (if (= tool 0)
  227.           (gimp-pencil drw len *points*)              ; Use pencil
  228.           (if (= tool 1)
  229.             (gimp-paintbrush-default drw len *points*); use paintbrush
  230.             (gimp-airbrush-default drw len *points*)  ; use airbrush
  231.           )
  232.         )
  233.  
  234.         ; Reset points array, but copy last point to first
  235.         ; position so it will connect the next time.
  236.         (aset *points* 0 (aref *points* (- point-index 2)))
  237.         (aset *points* 1 (aref *points* (- point-index 1)))
  238.         (set! point-index 2)
  239.     )
  240.  
  241.  ;;
  242.  ;; Execution starts here.
  243.  ;;
  244.  
  245.     (gimp-image-undo-group-start img)
  246.  
  247.     ; Set new color, brush, opacity, paint mode.
  248.     (gimp-palette-set-foreground color)
  249.     (gimp-brushes-set-brush (car brush))
  250.     (gimp-brushes-set-opacity (* 100 (car (cdr brush))))
  251.     (gimp-brushes-set-paint-mode (car (cdr (cdr (cdr brush)))))
  252.  
  253.     (while (< index steps)
  254.  
  255.         (calc-and-step!)
  256.  
  257.         (aset *points* point-index cx)
  258.         (aset *points* (+ point-index 1) cy)
  259.         (set! point-index (+ point-index 2))
  260.  
  261.         ; Change color and draw points if using gradient.
  262.         (if (< 0 color-method)  ; use gradient.
  263.            (if (< (/ (+ grad-index 4) gradn) (/ index steps))
  264.              (begin
  265.               (gimp-palette-set-foreground 
  266.                 (list 
  267.                   (* 255 (aref grada grad-index))
  268.                   (* 255 (aref grada (+ 1 grad-index)) )
  269.                   (* 255 (aref grada (+ 2 grad-index)) )
  270.                 )
  271.               )
  272.               (gimp-brushes-set-opacity (* 100 (aref grada (+ 3 grad-index) ) )  )
  273.               (set! grad-index (+ 4 grad-index))
  274.  
  275.               ; Draw points
  276.               (flush-points point-index)
  277.              )
  278.            )
  279.         )
  280.  
  281.         (set! index (+ index 1))
  282.     )
  283.  
  284.  
  285.     ; Draw remaining points.
  286.     (flush-points point-index)   
  287.  
  288.     ; Restore foreground color, brush and opacity
  289.     (gimp-palette-set-foreground old-fg-color)
  290.     (gimp-brushes-set-brush old-brush)
  291.     (gimp-brushes-set-opacity old-opacity)
  292.     (gimp-brushes-set-paint-mode old-paint-mode)
  293.  
  294.     (gimp-image-undo-group-end img)
  295.     (gimp-displays-flush)
  296.   )
  297. )
  298.  
  299.  
  300. ; This routine is invoked by a dialog.
  301. ; It is the main routine in this file.
  302. (define (script-fu-spyrogimp img drw 
  303.                              type shape
  304.                              oteeth iteeth 
  305.                              margin hole-ratio start-angle
  306.                              tool brush
  307.                              color-method color grad)
  308.   (let* 
  309.  
  310.        ; Get current selection to determine where to draw. 
  311.        (
  312.          (bounds (cdr (gimp-selection-bounds img)))
  313.          (x1 (car bounds))
  314.          (y1 (cadr bounds))
  315.          (x2 (caddr bounds))
  316.          (y2 (car (cdddr bounds)))
  317.        )
  318.  
  319.     (script-fu-spyrogimp-internal img drw 
  320.              x1 y1 x2 y2
  321.              type shape
  322.              oteeth iteeth 
  323.              margin hole-ratio start-angle
  324.              tool brush
  325.              color-method color grad)
  326.   )
  327. )
  328.  
  329.  
  330.  
  331. (script-fu-register "script-fu-spyrogimp"
  332.  _"<Image>/Script-Fu/Render/_Spyrogimp..."
  333.  _"Draws Spirographs, Epitrochoids and Lissajous Curves. More info at http://netword.com/*spyrogimp"
  334.  "Elad Shahar <elad@wisdom.weizmann.ac.il>"
  335.  "Elad Shahar"
  336.  "June 2003"
  337.  "RGB*, INDEXED*, GRAY*"
  338.  SF-IMAGE       "Image"         0
  339.  SF-DRAWABLE    "Drawable"      0
  340.  
  341.  SF-OPTION     _"Type"         '(_"Spyrograph"
  342.                      _"Epitrochoid"
  343.                      _"Lissajous")
  344.  SF-OPTION     _"Shape"        '(_"Circle"
  345.                  _"Frame"
  346.                      _"Triangle"
  347.                      _"Square"
  348.                      _"Pentagon"
  349.                      _"Hexagon"
  350.                      _"Polygon: 7 sides"
  351.                      _"Polygon: 8 sides"
  352.                      _"Polygon: 9 sides"
  353.                      _"Polygon: 10 sides")
  354.  SF-ADJUSTMENT _"Outer Teeth"   '(90 1 120 1 10 0 0)
  355.  SF-ADJUSTMENT _"Inner Teeth"   '(70 1 120 1 10 0 0)
  356.  SF-ADJUSTMENT _"Margin (pixels)" '(0 -10000 10000 1 10 0 1)
  357.  SF-ADJUSTMENT _"Hole Ratio"    '(0.4 0.0 1.0 0.01 0.1 2 0)
  358.  SF-ADJUSTMENT _"Start Angle"   '(0 0 359 1 10 0 0)
  359.  
  360.  SF-OPTION     _"Tool"          '(_"Pencil"
  361.                                   _"Brush"
  362.                                   _"Airbrush")
  363.  SF-BRUSH      _"Brush"         '("Circle (01)" 1.0 -1 0)
  364.  
  365.  SF-OPTION     _"Color Method"  '(_"Solid Color" 
  366.                   _"Gradient: Loop Sawtooth" 
  367.                                   _"Gradient: Loop Triangle")
  368.  SF-COLOR      _"Color"         '(0 0 0)
  369.  SF-GRADIENT   _"Gradient"       "Deep Sea"
  370. )
  371.  
  372. ;; End of syprogimp.scm
  373.