File cleanup bc I'm anal

This commit is contained in:
Dane Johnson 2024-11-19 11:39:13 -06:00
parent e38cda0261
commit f4b52415dc

View File

@ -1,19 +1,17 @@
(define-module (graphgif)) (define-module (graphgif))
(use-modules (cairo) (use-modules (cairo)
(d-) (d-)
(srfi srfi-1) (srfi srfi-1)
(srfi srfi-9 gnu) (srfi srfi-9 gnu)
(srfi srfi-11) (srfi srfi-11)
(srfi srfi-43)) (srfi srfi-43))
(re-export (cairo-pattern-create-rgb . create-color)) (re-export (cairo-pattern-create-rgb . create-color))
;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;
;; Basic Drawing ;; ;; Basic Drawing ;;
;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;
(define-public pi 3.14159) (define-public pi 3.14159) ;; Good enough
(define-public tau (* 2 pi)) (define-public tau (* 2 pi))
(define-public black (cairo-pattern-create-rgb 0 0 0)) (define-public black (cairo-pattern-create-rgb 0 0 0))
@ -31,11 +29,11 @@
node-color set-node-color) node-color set-node-color)
(define (edge-painter cr graph) (define (edge-painter cr graph)
"Creates a closure that draws the edges of graph using cr"
(lambda (node) (lambda (node)
(cairo-set-source cr black) (cairo-set-source cr black)
(let ([x (car (node-coords node))] (let-values ([(x y) (car+cdr (node-coords node))]
[y (cdr (node-coords node))] [edges (node-edges node)])
[edges (node-edges node)])
(for-each (for-each
(lambda (edge) (lambda (edge)
(let* ([other (assq-ref graph edge)] (let* ([other (assq-ref graph edge)]
@ -47,10 +45,10 @@
edges)))) edges))))
(define (node-painter cr) (define (node-painter cr)
"Creates a closure that draws the nodes of graph using cr"
(lambda (node) (lambda (node)
(let ([x (car (node-coords node))] (let-values ([(x y) (car+cdr (node-coords node))]
[y (cdr (node-coords node))] [color (or (node-color node) white)])
[color (or (node-color node) white)])
(cairo-arc cr x y 4. 0. tau) (cairo-arc cr x y 4. 0. tau)
(cairo-set-source cr color) (cairo-set-source cr color)
(cairo-fill-preserve cr) (cairo-fill-preserve cr)
@ -58,6 +56,7 @@
(cairo-stroke cr)))) (cairo-stroke cr))))
(define-public (draw-abstract-graph graph) (define-public (draw-abstract-graph graph)
"Creates a cairo surface with graph drawn on it"
(let* ([surface (cairo-image-surface-create 'rgb24 400 400)] (let* ([surface (cairo-image-surface-create 'rgb24 400 400)]
[cr (cairo-create surface)]) [cr (cairo-create surface)])
(define paint-edges (edge-painter cr graph)) (define paint-edges (edge-painter cr graph))
@ -76,15 +75,19 @@
;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;
(define (idx->x i w) (define (idx->x i w)
"Given i and width w, returns the x value"
(modulo i w)) (modulo i w))
(define (idx->y i w) (define (idx->y i w)
"Given i and width w, returns the y value"
(quotient i w)) (quotient i w))
(define (xy->idx x y w) (define (xy->idx x y w)
"Returns the index of x y on width x in a linear buffer"
(+ (* y w) x)) (+ (* y w) x))
(define (idx->edges i w) (define (idx->edges i w)
"Returns the edges needed to fully connect i on graph width w"
(filter-map (filter-map
(lambda (offset) (lambda (offset)
(let* ([x (idx->x i w)] (let* ([x (idx->x i w)]
@ -97,10 +100,13 @@
(< ox w) (< ox w)
(xy->idx ox oy w)))) (xy->idx ox oy w))))
;; Auto-connect these directions if legal indices ;; Auto-connect these directions if legal indices
'(( 0 . -1) ;; This combined with forwards and back connections create a
(-1 . 0) ;; fully connected graph
(-1 . -1) '(( 0 . -1) ;; Above
(+1 . -1)))) (-1 . 0) ;; Right
(-1 . -1) ;; Right-above
(+1 . -1) ;; Left above
)))
(define lset-unionq (partial lset-union eq?)) (define lset-unionq (partial lset-union eq?))
@ -129,6 +135,7 @@
graph)) graph))
(define-public (connect-bidirectionally graph) (define-public (connect-bidirectionally graph)
"Takes a directed graph and connects all edges to make it fully bidirectional"
(if (null? graph) '() (if (null? graph) '()
(let* ([idx (caar graph)] (let* ([idx (caar graph)]
[node (cdar graph)]) [node (cdar graph)])
@ -139,6 +146,7 @@
idx))))) idx)))))
(define-public (generate-web w h) (define-public (generate-web w h)
"Creates a fully connected graph of width w and height h"
(define (make-node i) (define (make-node i)
(cons i (cons i
(node (node
@ -153,6 +161,7 @@
(loop (1+ i) (cons (make-node i) lst))))) (loop (1+ i) (cons (make-node i) lst)))))
(define-public (remove-rect graph w x1 y1 x2 y2) (define-public (remove-rect graph w x1 y1 x2 y2)
"Removes a rectangular section of a fully connected rectangular graph"
;; Assumption is that is a graph generated by generate-web ;; Assumption is that is a graph generated by generate-web
;; and that it has not been re-indexed ;; and that it has not been re-indexed
;; x1 < x2, y1 < y2 ;; x1 < x2, y1 < y2
@ -180,7 +189,6 @@
;; ALGORITHMS!!! ;; ;; ALGORITHMS!!! ;;
;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;
;; Heap algorithms
(define-public (heap-insert priority item heap) (define-public (heap-insert priority item heap)
(define (fix-up! i heap) (define (fix-up! i heap)
(if (zero? i) (if (zero? i)
@ -217,10 +225,15 @@
(vector-set! new-heap 0 (vector-ref heap (1- (vector-length heap)))) (vector-set! new-heap 0 (vector-ref heap (1- (vector-length heap))))
(fix-down! new-heap 0)))) (fix-down! new-heap 0))))
(define (make-inf-queue graph)
"Creates a heap of the graph where all priorities are +inf"
(list->vector
(map (lambda (entry)
(cons (inf) (car entry)))
graph)))
(define* (djikstra graph source sink #:optional update) (define* (djikstra graph source sink #:optional update)
(define unvisited (list->vector (map (lambda (entry) (define unvisited (make-inf-queue graph))
(cons (inf) (car entry)))
graph)))
(let iter ([heap (heap-insert 0 source unvisited)] (let iter ([heap (heap-insert 0 source unvisited)]
[visited '()]) [visited '()])
(define-values (dist idx) (car+cdr (heap-peek heap))) (define-values (dist idx) (car+cdr (heap-peek heap)))
@ -239,14 +252,11 @@
(export djikstra) (export djikstra)
(define* (a* graph source sink #:optional update) (define* (a* graph source sink #:optional update)
"Uses the Chebychev distance as a heuristic" (define (chebychev idx) ;; Uses the Chebychev distance as a heuristic
(define (chebychev idx)
(let-values ([(x1 y1) (car+cdr (node-coords (assv-ref graph idx)))] (let-values ([(x1 y1) (car+cdr (node-coords (assv-ref graph idx)))]
[(x2 y2) (car+cdr (node-coords (assv-ref graph sink)))]) [(x2 y2) (car+cdr (node-coords (assv-ref graph sink)))])
(max (abs (- x1 x2)) (abs (- y1 y2))))) (max (abs (- x1 x2)) (abs (- y1 y2)))))
(define unvisited (list->vector (map (lambda (entry) (define unvisited (make-inf-queue graph))
(cons (inf) (car entry)))
graph)))
(let iter ([heap (heap-insert (chebychev source) source unvisited)] (let iter ([heap (heap-insert (chebychev source) source unvisited)]
[visited '()]) [visited '()])
(define-values (dist idx) (car+cdr (heap-peek heap))) (define-values (dist idx) (car+cdr (heap-peek heap)))
@ -269,6 +279,7 @@
;;;;;;;;;;;; ;;;;;;;;;;;;
(define (output-to-file filename surface-gen) (define (output-to-file filename surface-gen)
"Takes a filename and a coroutine to generate surfaces, and creates an animation"
(define pngdir (mkdtemp "/tmp/graphgif_XXXXXX")) (define pngdir (mkdtemp "/tmp/graphgif_XXXXXX"))
(let loop ([surface (surface-gen)] (let loop ([surface (surface-gen)]
[i 1]) [i 1])
@ -282,11 +293,8 @@
"-loop" "0" filename)) "-loop" "0" filename))
(define-public (write-graphs-to-file filename graph-gen) (define-public (write-graphs-to-file filename graph-gen)
"Takes a filename and a couroutine to generate graphs, and creates an animation"
(define (surface-gen) (define (surface-gen)
(let ([graph (graph-gen)]) (let ([graph (graph-gen)])
(and graph (draw-abstract-graph graph)))) (and graph (draw-abstract-graph graph))))
(output-to-file filename surface-gen)) (output-to-file filename surface-gen))
;; Local Variables:
;; geiser-scheme-implementation: guile
;; End: