                 (add-point* data [])
                 (commit-path path))))
         (commit-path (assoc this :data p) path)))))
+
+(defn delete-point*
+  [this p path]
+  (if (:children this)
+    (let [[c i] (child-for-point this p)]
+      (if c
+        (delete-point* c p (conj path [this i]))
+        (or (ffirst path) this)))
+    (if (m/delta= p (:data this))
+      (if (seq path)
+        (let [[p i] (peek path)
+              p (assoc-in p [:children i] nil)]
+          (commit-prune p (pop path)))
+        (assoc this :data nil))
+      (or (ffirst path) this))))
 
 (def ^{:const true :private true} qt-children [nil nil nil nil])
 (def ^{:const true :private true} ot-children [nil nil nil nil nil nil nil nil])

(defn select-with-shape
  [s q] (select-with #(g/intersect-shape s %) #(g/contains-point? s %) q))

(def q (time (reduce add-point (quadtree 0 0 100 100) [[55 10] [25 10] [55 11]])))
(def o (time (reduce add-point (octree 0 0 0 100 100 100) [[55 10 25] [25 10 55] [55 11 25]])))


(defn commit-path
  [node path]
  (if (seq path)
    (let [[parent i] (peek path)]
      (recur
       (->> node (assoc (:children parent) i) (assoc parent :children))
       (pop path)))
    node))

(defn commit-prune
  [node path]
  (if (seq path)
    (let [[parent i] (peek path)]
      (recur
       (->> (if (some identity (:children node)) node)
            (assoc (:children parent) i)
            (assoc parent :children))
       (pop path)))
    (if (every? nil? (:children node))
      (assoc node :children nil)
      node)))

(defn add-point*
