Last active
August 29, 2015 14:15
-
-
Save rm-hull/178513f8d2b6ecf501e4 to your computer and use it in GitHub Desktop.
The humble cone contains the answers to fundamental questions about the universe. But not _this_ one, its just pixels on the screen. What is mildly interesting about this cone is the way it is generated - a 2D polyline forms the bottom side and hypotenuse of a right-handed triangle in the X-Y plane. This flat shape is then "extruded" into three …
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(ns enchilada.wireframe-extrusion | |
(: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.primitives :refer [extrude make-line make-point 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) | |
(def intervals->radians | |
(let [atan8 (* (Math/atan 1.0) 8.0)] | |
(fn [num-intervals] (/ atan8 (double num-intervals))))) | |
(defn polyline-2d [& points] | |
(apply make-line (map (fn [[x y]] (make-point x y 0)) points))) | |
(defn make-cone [n] | |
(extrude | |
(polyline-2d | |
[0.0 0.0] | |
[1.0 0.0] | |
[2.0 0.0] | |
[3.0 0.0] | |
[4.0 0.0] | |
[5.0 0.0] | |
[4.5 1.0] | |
[4.0 2.0] | |
[3.5 3.0] | |
[3.0 4.0] | |
[2.5 5.0] | |
[2.0 6.0] | |
[1.5 7.0] | |
[1.0 8.0] | |
[0.5 9.0] | |
[0.0 10]) | |
(rotate :y (intervals->radians n)) | |
n)) | |
(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-cone divisions) | |
(center-at-origin) | |
(inflate (js/parseFloat (value-of :scale 0.25))))) | |
(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) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment