point?
point-x
point-y
- points-distance))
+ points-distance
+ sum-points
+ scale-point))
(define-record-type <point>
(make-point x y)
(abs
(sqrt (+ (expt (- (point-x p1) (point-x p2)) 2)
(expt (- (point-y p1) (point-y p2)) 2)))))
+
+(define (sum-points . points-to-sum)
+ (let loop ((points points-to-sum)
+ (x 0)
+ (y 0))
+ (cond ((null? points)
+ (make-point x y))
+ (else
+ (loop (cdr points)
+ (+ x (point-x (car points)))
+ (+ y (point-y (car points))))))))
+
+(define (scale-point point scale)
+ (make-point
+ (* (point-x point) scale)
+ (* (point-y point) scale)))
(> (angle-sign seed c1 c2) 0)))
(make-raw-voronoi-region seed (list-sort compare-angles vertices)))
+(define (voronoi-region-center region)
+ (let* ((vertices (voronoi-region-vertices region))
+ (centers (map (lambda (v) (triangle-center v)) vertices)))
+ (scale-point
+ (apply sum-points centers)
+ (/ 1 (length vertices)))))
+
+
;;; Voronoi mesh
(define-record-type <voronoi-mesh>
(frame voronoi-mesh-frame)
(regions voronoi-mesh-regions))
-(define* (make-voronoi-mesh vertices #:optional (relax-steps 3))
+(define (make-voronoi-mesh vertices)
;; Delaunay triangulation
(receive (triangles points frame)
(bowyer-watson vertices)
ordered-regions)))
filtered-regions))
-(define* (voronoi-mesh-relax voronoi #:optional (to-relax '()))
- (let ((regions (partitioning voronoi)))
- voronoi))
+(define* (voronoi-mesh-relax voronoi #:optional (points-to-relax '()))
+ (let ((regions
+ (map
+ (lambda (r) (cons (voronoi-region-seed r) (voronoi-region-center r)))
+ (partitioning voronoi)))
+ (points
+ (filter
+ (lambda (p) (not (member p (voronoi-mesh-frame voronoi))))
+ (voronoi-mesh-points voronoi)))
+ (to-relax
+ (if (null? points-to-relax)
+ (voronoi-mesh-points voronoi)
+ points-to-relax)))
+ (make-voronoi-mesh
+ (map
+ (lambda (point)
+ (let ((center (assoc-ref regions point)))
+ (if (and center (member point to-relax))
+ center
+ point)))
+ points))))
(define (make-regions points triangles)
(map-in-order