Skip to content

Instantly share code, notes, and snippets.

@nasser
Last active August 29, 2015 14:18
Show Gist options
  • Save nasser/1b3f4380befe38ee5fe8 to your computer and use it in GitHub Desktop.
Save nasser/1b3f4380befe38ee5fe8 to your computer and use it in GitHub Desktop.
Experimenting with graphics as data
(ns curve)
(defn power [x a]
(Math/Pow x a))
(defmacro v* [a b] `(Vector2/op_Multiply ~a ~b))
(defmacro v+
([a] a)
([a b] `(Vector2/op_Addition ~a ~b))
([a b & vs] (reduce
(fn [frm x]
`(v+ ~x ~frm))
`(v+ ~a ~b)
vs)))
(defn bezier [t ^Vector2 a ^Vector2 b ^Vector2 c ^Vector2 d]
(let [-t (- 1 t)]
(v+ (v* a ^double (power -t 3))
(v* b ^double (* 3 (power -t 2) t))
(v* c ^double (* 3 -t (power t 2)))
(v* d ^double (power t 3)))))
(defn clear
"Clears the OpenGL buffer. Call this at the top of the draw function
to clear the window."
([left right top bottom]
(GL/Clear (enum-or ClearBufferMask/ColorBufferBit
ClearBufferMask/DepthBufferBit))
(GL/MatrixMode MatrixMode/Projection)
(GL/LoadIdentity)
(GL/Enable EnableCap/Blend)
(GL/Ortho left right top bottom 0 4))
([] (clear -50 50 -50 50)))
(defn lines
"Draws a line strip connecting all points in ps"
[ps]
(GL/Begin PrimitiveType/LineStrip)
(doseq [^Vector2 p ps] (GL/Vertex2 p))
(GL/End))
(defn points
"Draws a line strip connecting all points in ps"
[ps]
(GL/Begin PrimitiveType/Points)
(doseq [^Vector2 p ps] (GL/Vertex2 p))
(GL/End))
(def control-point-a (atom (Vector2. 0 0)))
(def control-point-b (atom (Vector2. 0 0)))
(defn on-draw [w]
(clear)
(GL/LineWidth 1)
(let [ps [(Vector2. -40 0)
@control-point-a
@control-point-b
(Vector2. 40 0)]
curve (let [res 50]
(for [t (map #(cond (zero? %) 0
:else (/ % res)) (range (+ 1 res)))
:let [p (apply bezier t ps)]]
p))]
(GL/PointSize 5)
(points ps)
(GL/PointSize 10)
(points curve)
(lines curve)
(lines (interleave curve
(repeat (Vector2. 0 -20))))
(lines (interleave curve
(repeat (Vector2. 0 40))))))
(defn on-mouse-move [w e]
(if (= ButtonState/Pressed (.. e Mouse LeftButton))
(reset! control-point-a (Vector2. (* 50 (/ (.X e) (.Width w)))
(* 50 (/ (.Y e) (.Height w))))))
(if (= ButtonState/Pressed (.. e Mouse RightButton))
(reset! control-point-b (Vector2. (* 50 (/ (.X e) (.Width w)))
(* 50 (/ (.Y e) (.Height w)))))))
(Window. "curve")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment