Skip to content

Instantly share code, notes, and snippets.

@quephird
Created August 19, 2012 17:50
Show Gist options
  • Save quephird/3396692 to your computer and use it in GitHub Desktop.
Save quephird/3396692 to your computer and use it in GitHub Desktop.
function plot
; This is _really_ hacky; I converted Processing code from within a presentation
; here, www.dsic.upv.es/~jlinares/grafics/processing_eng_7.pdf, to Clojure/quil code.
;
; OK, now... I have a slightly more interesting function in here, the ability to
; move the plot around and be able to zoom in and out. I'm not nuts about the zoom feature since
; there are clipping issues if you zoom too far out. But it's cool.
;
; Ugh... still too many magic numbers. And apparently you can't mix AWT nor Swing with Processing.
; I have to figure out how to embed a PApplet onto a Frame and add UI widgets to that. Only then can I
; allow user input of functions, x and y ranges, and the number of plot points.
;
; This needs to be a project proper at some point.
(ns function-plot
(:import [processing.core PConstants]
[java.awt.event MouseWheelListener])
(:use quil.core quil.applet)
)
(def screen-w 500)
(def screen-h 500)
(def steps 50)
(def scale-z 200)
(def start-x -3.0)
(def end-x 3.0)
(def start-y -3.0)
(def end-y 3.0)
(def zs (atom []))
(def rot-x (atom 0.0))
(def rot-y (atom 0.0))
(def last-x (atom 0.0))
(def last-y (atom 0.0))
(def dist-x (atom 0.0))
(def dist-y (atom 0.0))
;(def zoom-z -300)
(def zoom-z (atom -2000))
(defn f [x y]
; (+ (* x x x) (* y y y)))
(Math/sin (+ (* x x) (* y y))))
(defn- compute-points []
(let [range-x (- end-x start-x)
range-y (- end-y start-y)]
(reset! zs
(into []
(for [i (range (inc steps))
j (range (inc steps))]
(f (+ start-x (* i (/ range-x steps)))
(+ start-y (* j (/ range-y steps)))))
)
)
)
)
(defn- mouse-pressed []
(reset! last-x (mouse-x))
(reset! last-y (mouse-y))
)
(defn- mouse-dragged []
(reset! dist-x (radians (- (mouse-x) @last-x)))
(reset! dist-y (radians (- @last-y (mouse-y))))
)
(defn- mouse-released []
(swap! rot-x + @dist-y)
(swap! rot-y + @dist-x)
(reset! dist-x 0.0)
(reset! dist-y 0.0)
)
(defn- mouse-wheel [mwr]
(if (> mwr 0)
(swap! zoom-z + 50)
(swap! zoom-z - 50))
)
(defn setup []
(no-fill)
(let [applet (current-applet)
mouse-wheel-listener (proxy [java.awt.event.MouseWheelListener] []
(mouseWheelMoved [mwe] (mouse-wheel (.getWheelRotation mwe)))
)]
(.addMouseWheelListener applet mouse-wheel-listener)
)
(compute-points)
)
(defn- draw-function-plot []
(lights)
(stroke 255)
(no-stroke)
(fill 127 127 0)
(let [range-x (- end-x start-x)
range-y (- end-y start-y)]
(doseq [j (range steps)]
(begin-shape :quad-strip)
(doseq [i (range (inc steps))]
(let [x (+ start-x (* i (/ range-x steps)))
y (+ start-y (* j (/ range-y steps)))]
(vertex x y (@zs (+ i (* j (inc steps)))))
(vertex x (+ y (/ range-y steps)) (@zs (+ i (* (inc j) (inc steps)))))
)
)
(end-shape)
)
)
)
(defn- draw-axes []
(stroke 255 0 0)
(line -2000 0 0 2000 0 0)
(stroke 0 255 0)
(line 0 -2000 0 0 2000 0)
(stroke 0 0 255)
(line 0 0 -2000 0 0 2000)
)
(defn draw []
(background 0)
; We center the results on window
(translate (/ screen-w 2) (/ screen-h 2) @zoom-z)
; Rotation
(rotate-y (+ @rot-y @dist-x))
(rotate-x (+ @rot-x @dist-y))
; Centering around (0, 0);
(translate (- (/ screen-w 2)) (- (/ screen-h 2)))
; Function covers
; 400 x 400 x scaleZ
; NOTA BENE: quil only exposes two arities of scale so we
; need to dive into Java here.
(.scale (current-applet) screen-w screen-h scale-z)
;(scale screen-w screen-h scale-z)
(draw-function-plot)
(draw-axes)
)
(defsketch main
:title "function plot"
:setup setup
:draw draw
:size [500 500]
:renderer :opengl
:mouse-pressed mouse-pressed
:mouse-dragged mouse-dragged
:mouse-released mouse-released
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment