X-Git-Url: https://git.jsancho.org/?p=dungeon-master.git;a=blobdiff_plain;f=dungeon-master%2Fgeom%2Fbowyer-watson.scm;fp=dungeon-master%2Fgeom%2Fbowyer-watson.scm;h=e8b9ea5a19998d9f53f0263a8751a143670b55a9;hp=0000000000000000000000000000000000000000;hb=695ecf94f5bb10ced4e66b0b4d036de9965c02ca;hpb=4e1254800a1c453aba76b8ccd5b632f38a71aed7 diff --git a/dungeon-master/geom/bowyer-watson.scm b/dungeon-master/geom/bowyer-watson.scm new file mode 100644 index 0000000..e8b9ea5 --- /dev/null +++ b/dungeon-master/geom/bowyer-watson.scm @@ -0,0 +1,124 @@ +(define-module (dungeon-master geom bowyer-watson) + #:use-module (ice-9 receive) + #:use-module (srfi srfi-1) + #:use-module (srfi srfi-9) + #:use-module (dungeon-master geom point) + #:use-module (dungeon-master geom triangle) + #:export (bowyer-watson)) + +"Compute the Delaunay triangulation using Bowyer–Watson algorithm" + +(define (bowyer-watson vertices) + (receive (minx miny maxx maxy) + (calculate-limits vertices) + (let ((c1 (make-point minx miny)) + (c2 (make-point minx maxy)) + (c3 (make-point maxx miny)) + (c4 (make-point maxx maxy))) + (let ((frame (list c1 c2 c3 c4))) + (receive (points triangles) + (calculate-triangulation + (list c1 c2 c3 c4) + (list (make-triangle c1 c2 c3) + (make-triangle c2 c3 c4)) + vertices) + (values triangles points frame)))))) + +(define (calculate-limits vertices) + (let ((xs (map (lambda (p) (point-x p)) vertices)) + (ys (map (lambda (p) (point-y p)) vertices))) + (let ((minx (apply min (cons (expt 10 10) xs))) + (miny (apply min (cons (expt 10 10) ys))) + (maxx (apply max (cons (- (expt 10 9)) xs))) + (maxy (apply max (cons (- (expt 10 9)) ys)))) + (let ((dx (* (- maxx minx) 0.5)) + (dy (* (- maxy miny) 0.5))) + (values (- minx (/ dx 2)) + (- miny (/ dy 2)) + (+ maxx (/ dx 2)) + (+ maxy (/ dy 2))))))) + +(define (calculate-triangulation points triangles vertices) + (cond ((null? vertices) + (values points triangles)) + (else + (let ((vertice (car vertices))) + (receive (to-split to-keep) + (triangles-contains-point triangles vertice) + (cond ((null? to-split) + (calculate-triangulation points triangles (cdr vertices))) + (else + (calculate-triangulation + (cons vertice points) + (concatenate + (list (calculate-new-triangles to-split vertice) + to-keep)) + (cdr vertices))))))))) + +(define (calculate-new-triangles to-split p1) + (receive (a b) + (calculate-new-edges to-split) + (let loop ((p2-list a) + (p3-list b) + (triangles '())) + (cond ((null? p2-list) + triangles) + (else + (let ((p2 (car p2-list)) + (p3 (car p3-list))) + (loop (cdr p2-list) + (cdr p3-list) + (cons (make-triangle p1 p2 p3) triangles)))))))) + +(define* (calculate-new-edges triangles #:optional (original-t triangles) (a '()) (b '())) + (cond ((null? triangles) + (values a b)) + (else + (let* ((triangle (car triangles)) + (common-edge (triangles-has-common-edge triangle original-t))) + (let ((points (triangle-points triangle))) + (let ((p1 (car points)) + (p2 (cadr points)) + (p3 (caddr points)) + (e1 (car common-edge)) + (e2 (cadr common-edge)) + (e3 (caddr common-edge))) + (cond (e1 + (set! a (cons p1 a)) + (set! b (cons p2 b)))) + (cond (e2 + (set! a (cons p2 a)) + (set! b (cons p3 b)))) + (cond (e3 + (set! a (cons p3 a)) + (set! b (cons p1 b)))) + (calculate-new-edges (cdr triangles) original-t a b))))))) + +(define* (triangles-has-common-edge triangle triangles #:optional (e1 #t) (e2 #t) (e3 #t)) + (cond ((not (or e1 e2 e3)) + (list e1 e2 e3)) + ((null? triangles) + (list e1 e2 e3)) + (else + (let ((t (car triangles))) + (cond ((equal? t triangle) + (triangles-has-common-edge triangle (cdr triangles) e1 e2 e3)) + (else + (let ((points (triangle-points triangle))) + (let ((p1 (car points)) + (p2 (cadr points)) + (p3 (caddr points))) + (when (and e1 (triangle-has-edge t p2 p1)) + (set! e1 #f)) + (when (and e2 (triangle-has-edge t p3 p2)) + (set! e2 #f)) + (when (and e3 (triangle-has-edge t p1 p3)) + (set! e3 #f)))) + (triangles-has-common-edge triangle (cdr triangles) e1 e2 e3))))))) + +(define (triangles-contains-point triangles point) + (partition + (lambda (triangle) + (< (points-distance point (triangle-center triangle)) + (triangle-radius triangle))) + triangles))