for
when
By varying
Try translucent, opaque or shaded styles (these are all a bit slower due to the extra hidden face removal calculations required)
Built using the wireframes library.
| (ns enchilada.boys-surface | |
| (:require | |
| [enchilada :refer [canvas ctx value-of canvas-size]] | |
| [wireframes.renderer.canvas :refer [draw-solid ->canvas]] | |
| [wireframes.renderer.color :refer [wireframe solid]] | |
| [wireframes.transform :refer [point combine rotate scale translate degrees->radians]] | |
| [wireframes.shapes.platonic-solids :refer [cube tetrahedron icosahedron dodecahedron]] | |
| [wireframes.shapes.primitives :refer [mesh transform-shape center-at-origin]] | |
| [jayq.core :refer [show]] | |
| [inkspot.color :refer [coerce]] | |
| [monet.canvas :refer [get-context fill-rect fill-style]] | |
| [big-bang.core :refer [big-bang]])) | |
| (def root2 (Math/sqrt 2)) | |
| (def Π Math/PI) | |
| (def sin Math/sin) | |
| (def cos Math/cos) | |
| (defn make-boys-surface [divisions alpha] | |
| (let [i (/ Π divisions) | |
| d (fn [u v] (- 2 (* alpha root2 (sin (* 3 u)) (sin (* 2 v))))) | |
| x (fn [u v] (+ (* root2 (cos v) (cos v) (cos (* 2 u))) (* (cos u) (sin (* 2 v))))) | |
| y (fn [u v] (- (* root2 (cos v) (cos v) (sin (* 2 u))) (* (sin u) (sin (* 2 v))))) | |
| z (fn [u v] (* 3 (cos v) (cos v))) | |
| u (range (/ Π -2) (+ (/ Π 2) i) i) | |
| v (range 0 (+ Π i) i)] | |
| {:polygons (vec | |
| (mesh | |
| (dec (count u)) | |
| (dec (count v)))) | |
| :points (vec | |
| (for [v' v | |
| u' u | |
| :let [d (d u' v')]] | |
| (point | |
| (/ (x u' v') d) | |
| (/ (y u' v') d) | |
| (/ (z u' v') d))))})) | |
| (def rect | |
| (let [[width height] (canvas-size)] | |
| {:x 0 :y 0 :w width :h height})) | |
| (def dimensions | |
| (mapv rect [:w :h])) | |
| (defn inflate [shape multiplier] | |
| ((transform-shape (scale multiplier)) shape)) | |
| (def divisions | |
| (js/parseInt (value-of :divisions 40))) | |
| (def alpha | |
| (js/parseFloat (value-of :alpha 1))) | |
| (def shape | |
| (-> | |
| (make-boys-surface divisions alpha) | |
| (center-at-origin) | |
| (inflate (js/parseFloat (value-of :scale 1))))) | |
| (def style | |
| (keyword (value-of :style :transparent))) | |
| (def color | |
| (coerce (value-of :color :white))) | |
| (def color-fn | |
| (condp = style | |
| :transparent (wireframe color style) | |
| :translucent (wireframe color style) | |
| :opaque (wireframe color style) | |
| :shaded (solid color))) | |
| (defn render-shape | |
| "Draws the shape at the given state of the world (the x,y,z rotation angles)" | |
| [[x y z]] | |
| (-> ctx | |
| (fill-style "rgba(255,255,255,0.75") | |
| (fill-rect rect)) | |
| ((->canvas ctx) | |
| (partial draw-solid | |
| {:style style | |
| :focal-length 3 | |
| :color-fn color-fn | |
| :shape shape | |
| :transform (combine | |
| (rotate :x (degrees->radians x)) | |
| (rotate :y (degrees->radians y)) | |
| (rotate :z (degrees->radians z)) | |
| (translate 0 0 10))}) | |
| dimensions)) | |
| (defn update-state | |
| "Increment/decrement the rotation angles around the x,y and z axes" | |
| [event [x y z]] | |
| [(+ x 0.3) (- y 0.7) (+ z 0.5)]) | |
| (-> | |
| ctx | |
| (fill-style :white) | |
| (fill-rect rect)) | |
| (show canvas) | |
| (big-bang | |
| :initial-state [0 0 0] | |
| :on-tick update-state | |
| :to-draw render-shape) |
for
when
By varying
Try translucent, opaque or shaded styles (these are all a bit slower due to the extra hidden face removal calculations required)
Built using the wireframes library.