f8737faa |
(in-package #:3dr.octcone)
(defun make-adj-arr (&optional (size 25))
(make-array size :adjustable t :fill-pointer 0))
(defstruct (bounds (:type vector))
tl tr bl br)
(defclass octcone ()
((nw-bucket :initarg :nw-bucket :accessor nw-bucket :initform (make-adj-arr))
(ne-bucket :initarg :ne-bucket :accessor ne-bucket :initform (make-adj-arr))
(sw-bucket :initarg :sw-bucket :accessor sw-bucket :initform (make-adj-arr))
(se-bucket :initarg :se-bucket :accessor se-bucket :initform (make-adj-arr))
(overflow-bucket :initarg :overflow-bucket :accessor overflow-bucket :initform (make-adj-arr))
(center :initarg :center :accessor center)))
(defun bucket-point (point octcone)
(with-slots (nw-bucket ne-bucket sw-bucket se-bucket center) octcone
|
3bf1c97c |
(with-accessors ((center-y 3dr::point-y) (center-z 3dr::point-z)) center
|
f8737faa |
(with-accessors ((point-y 3dr::point-y) (point-z 3dr::point-z)) point
|
3bf1c97c |
(vector-push-extend
point
(if (< point-y center-y)
(if (< point-z center-z)
sw-bucket
nw-bucket)
(if (< point-z center-z)
se-bucket
ne-bucket)))))))
|
f8737faa |
|
98876dd5 |
(defun normalize-bucket (octcone bucket)
(let ((the-bucket (slot-value octcone bucket)))
(setf (slot-value octcone bucket)
(sort the-bucket #'< :key (lambda (point) (3dr::c-distance point #(0 0 0)))))))
(defun normalize-buckets (octcone)
(loop for bucket in '(nw-bucket ne-bucket se-bucket sw-bucket)
collect (normalize-bucket octcone bucket)))
(defun half-power-two (low high)
|
3bf1c97c |
(* (signum low)
(expt 2
(floor (log (abs (+ low
(floor (- high low)
2)))
2)))))
|
98876dd5 |
(defun subdivide-bucket (octcone bucket)
|
3bf1c97c |
(declare (optimize (debug 3)))
|
98876dd5 |
(let ((the-bucket (slot-value octcone bucket)))
|
3bf1c97c |
(check-type the-bucket vector)
(if (< 1 (length the-bucket))
|
98876dd5 |
(let* ((max-y (reduce #'max the-bucket :key #'3dr::point-y))
(min-y (reduce #'min the-bucket :key #'3dr::point-y))
|
3bf1c97c |
|
98876dd5 |
(max-z (reduce #'max the-bucket :key #'3dr::point-z))
(min-z (reduce #'min the-bucket :key #'3dr::point-z))
|
3bf1c97c |
|
98876dd5 |
(new-octc (make-instance 'octcone
:center (vector 0
(half-power-two min-y max-y)
(half-power-two min-z max-z)))))
|
3bf1c97c |
|
98876dd5 |
(values (prog1 new-octc
|
3bf1c97c |
(when (or (= min-y max-y) (= min-z max-z))
(setf (slot-value octcone bucket)
new-octc)
(map nil
(lambda (point)
(bucket-point point new-octc))
the-bucket)))
|
98876dd5 |
(vector min-y max-y)
|
3bf1c97c |
(vector min-z max-z)))
nil)))
(defmethod bucket-length (bucket)
(declare (optimize (debug 3)))
(typecase bucket
(vector (length bucket))
(octcone
(with-slots (nw-bucket ne-bucket sw-bucket se-bucket overflow-bucket) bucket
(+ (bucket-length nw-bucket)
(bucket-length ne-bucket)
(bucket-length se-bucket)
(bucket-length sw-bucket)
(bucket-length overflow-bucket))))))
(defmethod print-object ((object octcone) s)
(print-unreadable-object (object s :type t :identity t)
(with-slots (nw-bucket ne-bucket sw-bucket se-bucket overflow-bucket center) object
(format s "center: (~{~a~^,~}) sizes: nw ~d, ne ~d, se ~d, sw ~d, overflow ~d"
(coerce center 'list)
(bucket-length nw-bucket)
(bucket-length ne-bucket)
(bucket-length se-bucket)
(bucket-length sw-bucket)
(bucket-length overflow-bucket)))))
|
98876dd5 |
(defun subdivide-buckets (octcone)
|
3bf1c97c |
(let ((result (loop for bucket in '(nw-bucket ne-bucket se-bucket sw-bucket)
collect (subdivide-bucket octcone bucket))))))
|
98876dd5 |
(defun show-bucket-sizes (octcone)
(loop for bucket in '(nw-bucket ne-bucket se-bucket sw-bucket)
collect (length (slot-value octcone bucket))))
(defvar *octc*)
(defvar *points*)
(defun main ()
(setf *octc* (make-instance 'octcone :center (vector 0 0 0)))
(flet ((100- (x) (- 100 x)))
(setf *points*
(loop repeat 1000
collect (vector (random 200) (100- (random 200)) (100- (random 200))))))
(mapcar (lambda (x)
(bucket-point x *octc*))
*points*))
|
f8737faa |
|
3bf1c97c |
(defun make-graph-conns (conns)
(format nil "~:{~4t~(\"~a\" -> \"~a\"~%~)~}" conns))
(defun make-graph (conns)
(format nil "digraph {~%~a~%}~%" (make-graph-conns conns)))
(defun bucket-to-pair (bucket parent)
(declare (optimize (debug 3)))
(flet ((bucket-to-string (center bucket title)
(format nil "\"(~a: <~{~d~^, ~}> ~d)\""
(sxhash bucket)
(coerce center 'list)
(bucket-length bucket))))
(with-slots (center) bucket
(with-slots ((parent-center center)) parent
(list (bucket-to-string parent-center parent)
(bucket-to-string center bucket))))))
(defun octcone-to-graph-pairs (octcone)
(declare (optimize (debug 3)))
(with-slots (nw-bucket ne-bucket se-bucket sw-bucket center) octcone
(list
(typecase nw-bucket
(octcone (bucket-to-pair nw-bucket octcone)))
(typecase ne-bucket
(octcone (bucket-to-pair ne-bucket octcone)))
(typecase se-bucket
(octcone (bucket-to-pair se-bucket octcone)))
(typecase sw-bucket
(octcone (bucket-to-pair sw-bucket octcone))))))
(defun bucket-to-graph-list (bucket)
(declare (optimize (debug 3)))
(typecase bucket
(octcone
(with-slots (nw-bucket ne-bucket se-bucket sw-bucket center) bucket
(append (octcone-to-graph-pairs bucket)
(bucket-to-graph-list nw-bucket)
(bucket-to-graph-list ne-bucket)
(bucket-to-graph-list sw-bucket)
(bucket-to-graph-list se-bucket))))))
|