add molecule and gongshi

This commit is contained in:
2017-05-23 21:00:31 -07:00
parent 9182a78285
commit 716cb9a7aa

View File

@ -13,8 +13,11 @@
[thi.ng.geom.voxel.isosurface :as iso]
[thi.ng.geom.voxel.svo :as svo]
[thi.ng.math.core :as m]
[clojure.math.numeric-tower :as math]))
[clojure.math.numeric-tower :as math]
;;[clisk.patterns :as patterns]
)
(:import clisk.noise.Simplex))
;;;
;;; geometry
;;;
@ -28,6 +31,9 @@
(defn v-- [v1 v2]
(mapv - v1 v2))
(defn v-* [v1 v2]
(mapv * v1 v2))
(defn round-point [v]
(map math/round v))
@ -35,41 +41,11 @@
"Return a set of points contained in the sphere."
[origin radius]
(let [rg (range (- radius) radius)]
(set (for [x rg, y rg, z rg
:let [v (vector x y z)]
:when (<= (v-mag v) radius)] (v-+ origin v)))))
;;;
;;; trace
;;;
(def start-radius 1.0)
(def start-lifespan 120)
(def radius-step 0 #_(/ start-radius start-lifespan))
(defrecord Trace [position velocity radius lifespan start-time])
(defn new-trace [origin]
(Trace. origin (random-vel) start-radius start-lifespan (+ 70 (rand-int 10))))
(defn drawing? [t bounds]
(and (in-draw-bounds? (:position t) bounds)
(> (:radius t) 0)
(> (:lifespan t) 0)
(< (:start-time t) 0)))
(defn update-trace [trace bounds]
(let [t (Trace. (next-pos (:position trace) (:velocity trace))
(next-vel (:velocity trace))
(- (:radius trace) radius-step)
(dec (:lifespan trace))
(dec (:start-time trace)))]
(if (and (in-bounds? (:position t) bounds)
(> (:lifespan t) 0))
t
(do #_(println "died at " (:lifespan t))
nil))))
(for [x rg, y rg, z rg
:let [v (vector x y z)]
:when (<= (v-mag v) radius)] (v-+ origin v))))
;;;
;;; physics
;;;
@ -113,15 +89,55 @@
(or (<= v (- mid gap))
(>= v (+ mid gap))))))
(defn shell-in-bounds?
[v [lo hi]]
(let [thickness 20]
(and (>= v lo) (<= v hi)
(or (<= v (+ lo thickness))
(>= v (- hi thickness))))))
(defn in-draw-bounds?
"Inside complex box?"
[p bounds]
(every? true? (map #(complex-single-in-bounds? %1 %2) p bounds)))
true
#_(some true? (map #(shell-in-bounds? %1 %2) p bounds)))
#_(defn in-bounds?
(defn sphere-in-bounds?
"Inside sphere?"
[p bounds]
(<= (v-mag (v-- p [500 500 500])) 400))
(<= (v-mag (v-- p [500 500 500])) 200))
;;;
;;; trace
;;;
(def start-radius 1.0)
(def start-lifespan 120)
(def radius-step 0 #_(/ start-radius start-lifespan))
(defrecord Trace [position velocity radius lifespan start-time])
(defn new-trace [origin]
(Trace. origin (random-vel) start-radius start-lifespan (+ 70 (rand-int 10))))
(defn drawing? [t bounds]
(and (in-draw-bounds? (:position t) bounds)
(> (:radius t) 0)
(> (:lifespan t) 0)
(< (:start-time t) 0)))
(defn update-trace [trace bounds]
(let [t (Trace. (next-pos (:position trace) (:velocity trace))
(next-vel (:velocity trace))
(- (:radius trace) radius-step)
(dec (:lifespan trace))
(dec (:start-time trace)))]
(if (and (in-bounds? (:position t) bounds)
(> (:lifespan t) 0))
t
(do #_(println "died at " (:lifespan t))
nil))))
(defn trace-trajectory
[trace bounds]
@ -148,18 +164,168 @@
(repeatedly count
#(trace-trajectory (new-trace origin) bounds)))
;;;
;;; tie it together
;;;
(defn trace-tree [count]
(let [tree (svo/voxeltree 1000 1.0)
trace (sample-traces count)]
(svo/apply-voxels svo/set-at tree trace)))
(defn sample-write-ply
(defn trace-write-ply
[count]
(time
(with-open [o (io/output-stream "sample.ply")]
(let [tree (time (trace-tree count))]
(mio/write-ply o (g/tessellate (g/scale (iso/surface-mesh tree 5 0.9) 0.01)))))))
;;;
;;; points
;;;
(defn point-voxels [point]
(sphere point 2))
(defn rand-int-between [low high]
(+ low (rand-int (- high low))))
(defn new-point [bounds]
(mapv #(rand-int-between (first %) (second %)) bounds))
(defn hollow-sphere-in-bounds?
"Inside sphere?"
[p bounds]
(let [thickness 30
radius 300
p-mag (v-mag (v-- p [500 500 500]))]
(and (<= p-mag radius)
(>= p-mag (- radius thickness)))))
(defn sample-point []
(let [bounds (vec (repeat 3 [200 800]))
point (new-point bounds)]
(if (hollow-sphere-in-bounds? point bounds)
(point-voxels point)
(recur))))
(defn sample-points [count]
(reduce set/union (repeatedly count sample-point)))
(defn point-tree [count]
(let [tree (svo/voxeltree 1000 1.0)
points (sample-points count)]
(svo/apply-voxels svo/set-at tree points)))
(defn points-write-ply
[count]
(time
(with-open [o (io/output-stream "points.ply")]
(let [tree (time (point-tree count))]
(mio/write-ply o (g/tessellate (g/scale (iso/surface-mesh tree 5 0.9) 0.01)))))))
;;;
;;; molecule
;;;
(defn rand-int-between [low high]
(+ low (rand-int (- high low))))
(defn new-point [bounds]
(mapv #(rand-int-between (first %) (second %)) bounds))
(defn molecule-point []
(let [bounds (vec (repeat 3 [350 650]))
point [363 456 540] #_(new-point bounds)]
(if (in-draw-bounds? point bounds)
point
(recur))))
(defn take-percent [pct coll]
(set (filter (fn [_] (< (rand-int 100) pct)) coll)))
(defn count-n-print [msg set]
(println msg (count set))
set)
(defn molecule-points [count density]
(let [centers (repeatedly count molecule-point)]
(println "centers" centers)
(reduce set/union (map (fn [x] (take-percent density (sphere x 10 #_(+ 20 (rand-int 30))))) centers))))
(defn molecule-tree [count density]
(let [tree (svo/voxeltree 1000 1)
points (molecule-points count density)]
(svo/apply-voxels svo/set-at tree points)))
(defn molecule-write-ply
[count density depth]
(with-open [o (io/output-stream "molecule.ply")]
(let [tree (time (molecule-tree count density))]
(mio/write-ply o (time (g/tessellate (g/scale (time (iso/surface-mesh tree depth 0.9)) 0.01)))))))
;;;
;;; scholar stones
;;;
#_(defn rand-int-between [low high]
(+ low (rand-int (- high low))))
#_(defn new-point [bounds]
(mapv #(rand-int-between (first %) (second %)) bounds))
#_(clisk.noise.Simplex/noise 0 0 0 1)
#_(defn molecule-point []
(let [bounds (vec (repeat 3 [350 650]))
point [363 456 540] #_(new-point bounds)]
(if (in-draw-bounds? point bounds)
point
(recur))))
(defn gongshi-points [radius]
(sphere [500 500 500] radius))
(defn average [coll]
(/ (reduce + coll) (count coll)))
(defn noise-at
"Return the simplex noise value (0-1) for the scaled point."
[p scale]
(apply #(clisk.noise.Simplex/noise %1 %2 %3) (v-* scale p)))
(defn noise-sum [p scale]
(let [first (noise-at p scale)
second (noise-at p (v-* scale (repeat 2)))
;;third (noise-at p (v-* scale (repeat 4)))
;;fourth (noise-at p (v-* scale (repeat 6)))
]
(average [first second])))
#_(defn noise-sum [p scale]
(noise-at p scale))
(defn filter-noise [coll scale cutoff]
(filter (fn [p] (> (noise-sum p scale) cutoff)) coll))
(defn gongshi-tree [radius scale cutoff]
(let [tree (svo/voxeltree 1000 1)
points (filter-noise (gongshi-points radius) scale cutoff)]
(svo/apply-voxels svo/set-at tree points)))
(defn gongshi-write-ply
[radius scale cutoff depth]
(with-open [o (io/output-stream "gongshi.ply")]
(let [tree (time (gongshi-tree radius scale cutoff))]
(mio/write-ply o (time (g/tessellate (g/scale (time (iso/surface-mesh tree depth 0.9)) 0.01)))))))
;; (gongshi-write-ply 150 0.003 0.5 8)
;; shell instead of filled
;; multiple primitives linked by tendrils
;; tweak surface mesh generation - add curves
;; https://github.com/cmaher/noise
;; https://github.com/mikera/clisk/
;; take 2d image or 3d input