(define-module (graphgif)) (use-modules (cairo) (srfi srfi-1)) (re-export (cairo-pattern-create-rgb . create-color)) ;;;;;;;;;;;;;;;;;;; ;; Basic Drawing ;; ;;;;;;;;;;;;;;;;;;; (define-public pi 3.14159) (define-public tau (* 2 pi)) (define-public black (cairo-pattern-create-rgb 0 0 0)) (define-public white (cairo-pattern-create-rgb 1 1 1)) (define (edge-painter cr graph) (lambda (node) (cairo-set-source cr black) (let ([x (caar node)] [y (cdar node)] [edges (cadr node)]) (for-each (lambda (edge) (let* ([other (list-ref graph edge)] [ox (caar other)] [oy (cdar other)]) (cairo-move-to cr x y) (cairo-line-to cr ox oy) (cairo-stroke cr))) edges)))) (define (node-painter cr) (lambda (node) (let ([x (caar node)] [y (cdar node)] [color (if (null? (cddr node)) white (caddr node))]) (cairo-arc cr x y 4. 0. tau) (cairo-set-source cr color) (cairo-fill-preserve cr) (cairo-set-source cr black) (cairo-stroke cr)))) (define-public (draw-abstract-graph graph) (let* ([surface (cairo-image-surface-create 'rgb24 400 400)] [cr (cairo-create surface)]) (define paint-edges (edge-painter cr graph)) (define paint-nodes (node-painter cr)) ;; White background (cairo-rectangle cr 0 0 400 400) (cairo-set-source cr white) (cairo-fill cr) (for-each paint-edges graph) (for-each paint-nodes graph) (cairo-destroy cr) surface)) ;;;;;;;;;;;;;;;;;;;;;; ;; Graph Generation ;; ;;;;;;;;;;;;;;;;;;;;;; (define (idx->x i w) (modulo i w)) (define (idx->y i w) (quotient i w)) (define (xy->idx x y w) (+ (* y w) x)) (define (idx->edges i w) (filter-map (lambda (offset) (let* ([x (idx->x i w)] [y (idx->y i w)] [ox (+ x (car offset))] [oy (+ y (cdr offset))]) (and (not (negative? ox)) (not (negative? oy)) (< ox w) (xy->idx ox oy w)))) ;; Auto-connect these directions if legal indices '(( 0 . -1) (-1 . 0) (-1 . -1) (+1 . -1)))) (define-public (generate-web w h) (define (make-node i) (list (cons (+ (* 30 (idx->x i w)) 10) (+ (* 30 (idx->y i w)) 10)) (idx->edges i w))) (let loop ([i 0] [lst '()]) (if (>= i (* w h)) (reverse lst) (loop (1+ i) (cons (make-node i) lst))))) ;;;;;;;;;;;; ;; Output ;; ;;;;;;;;;;;; (define (output-to-file surfaces filename) (define pngdir (mkdtemp "graphgif_XXXXXX")) (do ([i 1 (1+ i)] [surfaces surfaces (cdr surfaces)]) ((null? surfaces)) (cairo-surface-write-to-png (car surfaces) (string-append pngdir "/img-" (number->string i) ".png"))) (system* "ffmpeg" "-i" (string-append pngdir "/img-%d.png") "-r" "1" filename)) (define-public (write-graphs-to-file graphs filename) (output-to-file (map draw-abstract-graph graphs) filename)) ;; Local Variables: ;; geiser-scheme-implementation: guile ;; End: