Tumbling 3D Torus

webgl3d

A tumbling three-dimensional wireframe torus (and other assorted shapes) in ClojureScript rendered on a canvas, using the wireframes library.

22 Oct 2013 by rm-hull
rm-hull/7098992
TORUS.md

Wireframes

Solids & Translucents

One-sided Shapes

Also see


Built using the https://github.com/rm-hull/wireframes library.

torus.cljs
(ns wireframes.demo
  (: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 [combine rotate scale translate degrees->radians]]
    [wireframes.shapes.primitives :refer [transform-shape]]
    [wireframes.shapes.curved-solids :refer [make-torus make-wineglass make-sphere make-isosphere 
                                             make-mobius-strip make-klein-bottle make-klein-bagel]]
    [wireframes.shapes.platonic-solids :refer [cube tetrahedron icosahedron dodecahedron]]
    [wireframes.shapes.elite :refer [cobra-mk3]]
    [inkspot.color :refer [coerce]]
    [big-bang.core :refer [big-bang]]
    [monet.canvas :refer [get-context fill-rect fill-style]]
    [jayq.core :refer [show]]))

(def width (first (canvas-size)))
(def height (second (canvas-size)))

(defn inflate [shape multiplier]
  ((transform-shape (scale multiplier)) shape))

(def shape 
  (->
    (condp = (keyword (value-of :shape "torus"))
      :torus (make-torus 1 3 30 30)
      :wineglass (make-wineglass 20) 
      :sphere (make-sphere 3 30)
      :isosphere (make-isosphere 3 2)
      :mobius-strip (make-mobius-strip 50 10)
      :klein-bottle (make-klein-bottle 6 2 2 40)
      :klein-bagel (make-klein-bagel 2 40)
      :cobra cobra-mk3
      :cube cube
      :tetrahedron tetrahedron
      :icosahedron icosahedron
      :dodecahedron dodecahedron)
   (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 { :x 0 :y 0 :w width :h height}))
  ((->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 16))})
    [width height]))

(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 {:x 0 :y 0 :w width :h height}))

(show canvas)

(big-bang
  :initial-state [0 0 0]
  :on-tick update-state
  :to-draw render-shape)
x-elite.cljs
(ns wireframes.shapes.elite
  (:use [wireframes.transform :only [point]]))

(def cobra-mk3
  {:points (mapv (partial apply point) [
			[40 0.0 95] 
			[-40 0.0 95] 
			[00 32.5 30] 
			[-150 -3.8 -10] 
			[150 -3.8 -10] 
			[-110 20 -50] 
			[110 20 -50] 
			[160 -10 -50] 
			[-160 -10 -50] 
			[0 32.5 -50] 
			[-40 -30 -50] 
			[40 -30 -50] 
			[-45 10 -55] 
			[-10 15 -55] 
			[10 15 -55] 
			[45 10 -55] 
			[45 -15 -55] 
			[10 -20 -55] 
			[-10 -20 -55] 
			[-45 -15 -55] 
			[-2 -2 95] 
			[-2 -2 112.5] 
			[-100 -7.5 -55] 
			[-100 7.5 -55] 
			[-110 0 -55] 
			[100 7.5 -55] 
			[110 0 -55] 
			[100 -7.5 -55] 
			[2 -2 95] 
			[2 -2 112.5] 
			[2 2 95] 
			[2 2 112.5] 
			[-2 2 95] 
			[-2 2 112.5]])
	:polygons (mapv #(hash-map :vertices %) [
			[2 1 0] 
			[0 1 10 11] 
			[6 2 0] 
			[0 4 6] 
			[0 11 7 4] 
			[1 2 5] 
			[5 3 1] 
			[1 3 8 10] 
			[5 2 9] 
			[2 6 9] 
			[5 8 3] 
			[7 6 4] 
			[9 6 7 11 10 8 5] 
			[14 15 16 17] 
			[12 13 18 19] 
			[25 26 27] 
			[24 23 22] 
			[21 29 28 20] 
			[31 29 28 30] 
			[32 30 31 33] 
			[21 33 32 20] 
			[20 29 31 33]])})

; Data points - attribution: http://karlstanley.net/examples/canvas/shape_simple.js