root/trunk/projects/bos/tools/quadtree-test/quadtree.lisp

Revision 2321, 3.1 kB (checked in by ksprotte, 1 year ago)

marked lisp files that are currently not used in the production core

  • Property svn:eol-style set to native
  • Property svn:keywords set to author date id revision
Line 
1 ;; 2008-01-15: currently not used in the production core
2
3 (in-package :cl-user)
4
5 (defconstant +max-node-objects+ 10)
6
7 (defclass qt-object ()
8   ((x :initarg :x :reader qt-object-x)
9    (y :initarg :y :reader qt-object-y)
10    (object :initarg :object :reader qt-object-object)))
11
12 (defclass qt-node ()
13   ((x :initarg :x :reader qt-node-x)
14    (y :initarg :y :reader qt-node-y)
15    (half-width :initarg :half-width :reader qt-node-half-width)
16    (objects :initarg :objects :accessor qt-node-objects :initform nil)
17    (children :initarg :children :accessor qt-node-children :initform nil)))
18
19 (defclass quadtree ()
20   ((root :reader quadtree-root)))
21
22 (defun dump-node (node &optional (depth 0))
23   (let ((indent (make-string depth :initial-element #\Space)))
24     (format t "~anode x: ~a y: ~a width: ~a~%" indent (qt-node-x node) (qt-node-y node) (* 2 (qt-node-half-width node)))
25     (dolist (child (qt-node-children node))
26       (dump-node child (1+ depth)))
27     (dolist (object (qt-node-objects node))
28       (format t "~a x: ~a y: ~a object: ~a~%" indent (qt-object-x object) (qt-object-y object) (qt-object-object object)))))
29
30 (defmethod in-bbox-p ((object qt-object) x1 y1 x2 y2)
31   (let ((x (qt-object-x object))
32         (y (qt-object-y object)))
33     (and (>= x x1)
34          (<= x x2)
35          (>= y y1)
36          (<= y y2))))
37
38 (defmethod overflow ((node qt-node) (object qt-object))
39   (let ((children-half-width (/ (qt-node-half-width node) 2)))
40     (setf (qt-node-children node)
41           (list (make-instance 'qt-node
42                                :x (qt-node-x node)
43                                :y (qt-node-y node)
44                                :half-width children-half-width)
45                 (make-instance 'qt-node
46                                :x (+ (qt-node-half-width node) (qt-node-x node))
47                                :y (qt-node-y node)
48                                :half-width children-half-width)
49                 (make-instance 'qt-node
50                                :x (qt-node-x node) :y (+ (qt-node-half-width node) (qt-node-y node))
51                                :half-width children-half-width)
52                 (make-instance 'qt-node
53                                :x (+ (qt-node-half-width node) (qt-node-x node))
54                                :y (+ (qt-node-half-width node) (qt-node-y node))
55                                :half-width children-half-width)))
56     (push object (qt-node-objects node)) ; append new object temporarily
57     (dolist (object (qt-node-objects node)) ; push all objects into child nodes
58       (insert (find-node node (qt-object-x object) (qt-object-y object)) object))
59     (setf (qt-node-objects node) nil)))
60
61 (defmethod insert ((node qt-node) (object qt-object))
62   (if (< (length (qt-node-objects node)) +max-node-objects+)
63       (push object (qt-node-objects node))
64       (overflow node object)))
65
66 (defmethod find-node ((node qt-node) x y)
67   (if (qt-node-children node)
68       (let ((x-quadrant (if (minusp (- x (qt-node-x node) (qt-node-half-width node))) 0 1))
69             (y-quadrant (if (minusp (- y (qt-node-y node) (qt-node-half-width node))) 0 2)))
70         (find-node (nth (+ x-quadrant y-quadrant) (qt-node-children node))
71                    x y))
72       node))
73
74 (defmethod insert-object ((quadtree quadtree) x y object)
75   (insert (find-node (quadtree-root quadtree) x y)
76           (make-instance 'qt-object :x x :y y :object object)))
77
78 (defun add-nodes (qt count)
79   (loop for i from 0 below count
80         do (insert-object qt (random 100) (random 100) i)))
Note: See TracBrowser for help on using the browser.