             b (range n)]
       (let [pa (nth @particles a)
             pb (nth @particles b)
-            v (map + (:vel pa) (:vel pb))
-            pa {:pos (:pos pa) :vel v}
-            pb {:pos (:pos pb) :vel v}]
+            abdir (map - (:pos pa) (:pos pb))
+            dist (magnitude abdir)
+            abdir (map #(/ % dist) abdir)
+            bounce (map #(* % (- 20 dist)) abdir)]
         (when (and (not= a b) (collided? (:pos pa) (:pos pb)))
           (do
-            (reset! particles (assoc @particles a pa))
-            (reset! particles (assoc @particles b pb))))))))
+            (reset! particles (assoc @particles a (assoc pa :pos (map + (:pos pa) bounce) :vel (map + (:vel pa) (map #(* % (magnitude (:vel pa))) abdir)))))
+            (reset! particles (assoc @particles b (assoc pb :pos (map - (:pos pb) bounce) :vel (map - (:vel pb) (map #(* % (magnitude (:vel pb))) abdir)))))))))))
 
 (defn motion-tick!
   []

  (let [a (calc-accel p all)
        v (map + v a)
        magv (magnitude v)
        v (if (> magv velocity-limit)
            (map #(* (/ % magv) vel-limit) v)
            v)
        p (map + p v)]
    [p v a]))

(defn render
  []
  (motion-tick!)
  (handle-collisions!)

  (doseq [i (range (count @particles))]
    (let [p (nth @particles i)
          m (nth @particle-meshes i)]
      ;; static rotation for blinginess
      (rotate-angles! m [0 2 0])
      (set-position! m (:pos p))))

  (render-scene))
