                 }))
             springs)))
 
+(defn real-mod [a b]
+    (mod (+ (mod a b) b) b))
+(defn pi-mod [a]
+    (-
+        (real-mod
+            (+ a Math/PI)
+            (* 2 Math/PI))
+        Math/PI))
+
 (defn calculate-hinge-force [a b c rest-angle strength]
     (let [
         b-to-a (vec- a b)
         b-to-c (vec- c b)
-        pressure (* (- rest-angle (angle b-to-a b-to-c)) strength)
+        pressure (* (pi-mod (- rest-angle (angle b-to-a b-to-c))) strength)
         result [
-            (vec* (rot-ccw b-to-a) (/ pressure (magnitude-squared b-to-a)))
-            (vec* (rot-cw b-to-c) (/ pressure (magnitude-squared b-to-c)))
+            (vec* (rot-cw b-to-a) (/ pressure (magnitude-squared b-to-a)))
+            (vec* (rot-ccw b-to-c) (/ pressure (magnitude-squared b-to-c)))
         ]]
             result))
 

(def magnitude (comp Math/sqrt magnitude-squared))
(def normalize (comp (partial apply vec*) (juxt identity (comp (partial / 1.0) magnitude))))
(defn dot-product [v w] (apply + (map * v w)))
(defn clamp [v lower upper] (Math/min (Math/max v lower) upper))
(defn angle [v w] (Math/acos (clamp
    (dot-product (normalize v) (normalize w))
    -1.0 1.0 )))
(defn rot-cw [[x y]] [y (- x)])
(defn rot-ccw [[x y]] [(- y) x])

(defn calculate-force [node-a node-b rest-length strength]
    (let [a-b (vec- node-a node-b)


(defn rerender [canvas-element game-state]
    (let [
        graphics (graphics/createGraphics width-in-px height-in-px)
        {nodes :nodes springs :springs} game-state]
        (do
            (apply draw-line graphics (apply concat (map world-to-screen [[0 0] [width-in-px 0]])))
            (dorun (map
                (fn [{a :node-a b :node-b}]
                    (let [
