thi-ng / geom Goto Github PK
View Code? Open in Web Editor NEW2D/3D geometry toolkit for Clojure/Clojurescript
License: Apache License 2.0
2D/3D geometry toolkit for Clojure/Clojurescript
License: Apache License 2.0
++ faster
++ more flexible
++ needed to avoid potential casting errors with custom tessellation fns (see #8)
-- what about uses of current typed results?
This is maybe too specific to my use case but I'll try anyway.
I'm tied of manually constructing matrices in GLSL code. I'd rather symbolically compute some matrix and use gamma to emit the code. I especially don't want to rewrite the logic for various eg rotation or perspective transformations. Too easy to get it wrong unless you've done it before.
Although geom supports pluggable *,+ etc, that only applies at the matrix level. Operations on elements bottom out at macromath, which in principle is pluggable but the geom matrix types have been hardwired to specific operations.
So: can we have matrix types where the user supplies the elementwise arithmetic operations? If its an easy thing to do I think it would be quite cool.
For CLJ hiccup serializes SVG's as in
#?(:clj
(defn serialize
^String [svg] (str xml-preamble (html {:mode :xml} svg))))
I have tried multiple alternatives for CLJS (hiccups, hipo and sablono for react), which AFAIK each miss an :xml mode.
sablono works properly for the area and line plot example, but fails when used with the bar graph.
In Om the following returns a valid react component based on the line-plot example:
(ns geom-test.geom
(:require
[om.core :as om :include-macros true]
[sablono.core :refer-macros [html]]
[thi.ng.geom.viz.core :as viz]
[thi.ng.geom.svg.core :as svg]
[thi.ng.math.core :as m :refer [PI]]))
(defn test-equation
[t] (let [x (m/mix (- PI) PI t)] [x (* (Math/cos (* 0.5 x)) (Math/sin (* x x x)))]))
(def viz-spec
{:x-axis (viz/linear-axis
{:domain [(- PI) PI] :range [50 580] :major (/ PI 2) :minor (/ PI 4) :pos 250})
:y-axis (viz/linear-axis
{:domain [-1 1] :range [250 20] :major 0.2 :minor 0.1 :pos 50
:label-dist 15 :label {:text-anchor "end"}})
:grid {:attribs {:stroke "#caa"}
:minor-y true}
:data [{:values (map test-equation (m/norm-range 200))
:attribs {:fill "none" :stroke "#0af"}
:layout viz/svg-line-plot}]})
(defn line-plot [_ owner]
(om/component
(html
[:svg {:width 600 :height 320}
(viz/svg-plot2d-cartesian viz-spec)])))
Adding tessellation :fn arg as opt is a good thing, but currently causes (for many, not all impls) to run subdivide
first and the default config for that is 2x2, causing extraneous /unwanted results...
Options:
subdivide
from within tessellate. That means user code wanting both will have to be rewritten as:(-> (g/subdivide _ {}) (mapcat #(g/tessellate _)))
subdivide
default res to 1, causing no subdivision (not great...)I'm on a mac with Emacs For Mac OS X installed. When running ./tangle.sh src/*.org test/*.org
I've got the following error: Cannot open load file: ob
. Maybe you can add a short sentence on how to build the projects for people that are new to emacs.
(thi.ng.geom.aabb/fit-all-into-aabb
(thi.ng.geom.aabb/aabb)
[(thi.ng.geom.triangle/triangle3 [[0 0 0] [0.3 0.3 0] [0.3 0 1]])])
--> ClassCastException thi.ng.geom.core.vector.Vec3 cannot be cast to java.lang.Number clojure.lang.Numbers.minus (Numbers.java:135)
Expected:
(count (geom/subdivide (rect/rect 1) {:cols 5, :rows 1})) => 5
(count (geom/subdivide (rect/rect 1) {:cols 6, :rows 1})) => 6
(count (geom/subdivide (rect/rect 1) {:cols 7, :rows 1})) => 7
(count (geom/subdivide (rect/rect 1) {:cols 8, :rows 1})) => 8
Actual:
(count (geom/subdivide (rect/rect 1) {:cols 5, :rows 1})) => 5
(count (geom/subdivide (rect/rect 1) {:cols 6, :rows 1})) => 7
(count (geom/subdivide (rect/rect 1) {:cols 7, :rows 1})) => 8
(count (geom/subdivide (rect/rect 1) {:cols 8, :rows 1})) => 8
The root cause seems to be in these two lines with the following results:
((juxt count last) (range 0.0 1.0 (/ 1.0 5))) => [5 0.8]
((juxt count last) (range 0.0 1.0 (/ 1.0 6))) => [7 0.9999999999999999]
((juxt count last) (range 0.0 1.0 (/ 1.0 7))) => [8 0.9999999999999998]
((juxt count last) (range 0.0 1.0 (/ 1.0 8))) => [8 0.875]
Hi,
How to add a colorbar to a heatmap plot?
Thanks!
Hi, it would be useful to have an area (fill) plot that is defined between two curves. I'm thinking about something similar to svg-radar-plot-minmax but for Cartesian coordinates. Another reference is http://matplotlib.org/examples/pylab_examples/fill_between_demo.html .
I'm terribly sorry that I'm posing what's essentially a support question here on the issue tracker. But we've been unable to figure out how to use multiple textures with geom and have equally been able to find an example either among your workshops or in the given WebGL examples.
More specifically: What is it that determines :target
of the map returned by buf/load-texture? Because for our application it's always the same value, i.e. all textures get loaded into the same texture unit.
Or it may be that I'm misunderstanding the purpose of :target
Reading into the code of load-texture
and then make-texture
in buffers.cljc
I see that :target
is always set to glc/texture-2d
, i.e. 3553.
Looked up the documentation on glBindTexture
which seemed to indicate that I had completely misunderstood the purpose of :target
which brings my question back to 0.
On with my adventure through your code: Through a refresh of my WebGL knowledge I found that it's gl.activeTexture()
which selects which texture unit the texture is uploaded to, and in your buffers.cljc that's called in bind
. Thing is that make-texture
which in turn is what's called from load-texture
doesn't pass on a second argument unit
to bind
which means that texture unit 0
is only ever used. It seems to me like some modifications to thi.ng/geom are requiered to use multiple textures.
The samples say use:
[thi.ng.geom.gl.buffers :as glbuf]
...
(let [file-tex (glbuf/load-texture gl {:callback (fn [tex img] (vreset! tex-ready true))
:src "img/cubev.png"
:flip true})]
But I just get a thi.ng.geom.gl.buffers
not found. I've found this with all namespaces that start with thi.ng.geom.gl
. Is it possible I am missing a dependency? Or samples are outdated?
Hi, thanks for the cool library!
I couldn't find any reference, therefore I'm asking here: is it possible, and if yes, what's the recommended way to draw a legend to the plot generated with geom.viz module?
Hi @postspectacular
these links are broken so far in this page https://github.com/thi-ng/geom/blob/master/src/index.org
https://github.com/thi-ng/geom/blob/master/src/core.html
https://github.com/thi-ng/geom/blob/master/src/types.html
Have a good day!
Juan
geom/color/math, none compiles from a .cljs file
lein deps:
[org.clojure/clojure "1.7.0"]
[org.clojure/clojurescript "1.7.122"]
[figwheel-sidecar "0.4.0"]
[thi.ng/color "1.0.0"]
Filename: core.cljs
Content:
(ns geom-test.core
(:require [thi.ng.color.core :as col]))
Exception:
Exception in thread "main" clojure.lang.ExceptionInfo: No such namespace: thi.ng.color.core, could not locate thi/ng/color/core.cljs, thi/ng/color/core.cljc, or Closure namespace "thi.ng.color.core" {:tag :cljs/analysis-error}, compiling:(/Users/den/Dropbox/dev/code/vimsical/geom-test/script/repl.clj:3:1)
at clojure.lang.Compiler.load(Compiler.java:7239)
at clojure.lang.Compiler.loadFile(Compiler.java:7165)
at clojure.main$load_script.invoke(main.clj:275)
at clojure.main$script_opt.invoke(main.clj:337)
at clojure.main$main.doInvoke(main.clj:421)
at clojure.lang.RestFn.invoke(RestFn.java:421)
at clojure.lang.Var.invoke(Var.java:383)
at clojure.lang.AFn.applyToHelper(AFn.java:156)
at clojure.lang.Var.applyTo(Var.java:700)
at clojure.main.main(main.java:37)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140)
Caused by: clojure.lang.ExceptionInfo: No such namespace: thi.ng.color.core, could not locate thi/ng/color/core.cljs, thi/ng/color/core.cljc, or Closure namespace "thi.ng.color.core" {:tag :cljs/analysis-error}
at clojure.core$ex_info.invoke(core.clj:4593)
at cljs.analyzer$error.invoke(analyzer.cljc:543)
at cljs.analyzer$error.invoke(analyzer.cljc:541)
at cljs.analyzer$analyze_deps.invoke(analyzer.cljc:1649)
at cljs.analyzer$ns_side_effects.invoke(analyzer.cljc:2485)
at cljs.analyzer$analyze_STAR_$fn__2091.invoke(analyzer.cljc:2566)
at clojure.lang.PersistentVector.reduce(PersistentVector.java:333)
at clojure.core$reduce.invoke(core.clj:6518)
at cljs.analyzer$analyze_STAR_.invoke(analyzer.cljc:2566)
at cljs.analyzer$analyze.invoke(analyzer.cljc:2581)
at cljs.analyzer$analyze_file$fn__2142.invoke(analyzer.cljc:2825)
at cljs.analyzer$analyze_file.invoke(analyzer.cljc:2820)
at figwheel_sidecar.repl$analyze_build.invoke(repl.clj:242)
at figwheel_sidecar.repl$analyze_builds.invoke(repl.clj:247)
at figwheel_sidecar.repl$run_autobuilder_helper.invoke(repl.clj:295)
at figwheel_sidecar.repl$start_autobuild.invoke(repl.clj:366)
at figwheel_sidecar.repl$start_repl.invoke(repl.clj:466)
at figwheel_sidecar.repl$cljs_repl.invoke(repl.clj:488)
at figwheel_sidecar.repl$cljs_repl.invoke(repl.clj:475)
at figwheel_sidecar.repl_api$cljs_repl.invoke(repl_api.clj:77)
at user$eval16094.invoke(repl.clj:3)
at clojure.lang.Compiler.eval(Compiler.java:6782)
at clojure.lang.Compiler.load(Compiler.java:7227)
... 14 more```
Which CLJ/CLJS protocols needed?
IMeta, IFn, IHash, indexed, seq...
Currently I have to manage the reference to GL context in every namespace that uses thi.ng.geom.webgl
. It would clean the user code a lot if we could remove all the occurrences of gl
symbol that are not context creation. Having written a small WebGL library in CLJS myself, I used a dynamic var in the core module, to allow users bind it to their WebGL context somewhere in the app initialization. Then all other namespaces that need GL context, can simply use the symbol required. Eg.
;; core namespace
(ns thi.ng.geom.webgl.core)
(def ^dynamic *gl* nil)
;; any other thi.ng namespace
(ns thi.ng.geom.webgl.buffers
(:require [thi.ng.geom.webgl.core :refer [*gl*]]))
(defn make-attribute-buffer
[target draw-type data]
(let [buffer (.createBuffer *gl*)]
(.bindBuffer *gl* target buffer)
(.bufferData *gl* target data draw-type)
buffer))
;; user code
(ns example.gfx
(:require [thi.ng.geom.webgl.core :as gl :refer [*gl*]]))
(defn -main [canvas]
(binding [*gl* (gl/gl-context canvas)]
;; very interesting graphics goes here
))
Use copy from this commit until clojars/clojars-web#270 is fixed:
Calling (g/vertices mf)
raises missing protocol in CLJS. Calling (g/vertices mf {})
works.
this will fail if the size of one of the dimensions is 0:
(g/div (:size box) (:size b))
Additionally, morphogen depends on an outdated version of thi-ng.geom
. Trying to get this working but no luck so far.
Hi Karsten, just tracked down this error after tracing it to linear-axis
in thi.ng.geom.viz.core
.
In Java an exception is thrown, but in browser (Chrome, at least) it just overflows and ramps the memory usage up super quick. Happy to PR if you'd advise on how you'd like it fixed. Zero check and empty list return?
(defn lin-tick-marks
[[d1 d2] delta]
(if (zero? delta)
'()
(let [dr (- d2 d1)
d1' (m/roundto d1 delta)]
(filter #(do (println % (m/in-range? d1 d2 %))
(m/in-range? d1 d2 %)) (range d1' (+ d2 delta) delta)))))
(defn filter-attribs
[attribs]
(loop [acc (transient attribs), ks (keys attribs)]
(if ks
(recur
(if (= "__" (subs (name (first ks)) 0 2)) (dissoc! acc (first ks)) acc)
(next ks))
(persistent! acc))))
The call to subs
prevents passing in keys such as :x
or :y
in the attribute map of a SVG hiccup vector. It would be handy to be able to use these with svg/group
.
support 2d cases as well (via temp vec3)
In cljs this throws "Invalid arity: 0"
(defn test-gmesh
[]
(-> (gmesh)
(g/add-face [(vec3 0 0 0) (vec3 1 0 0) (vec3 1 1 0)])
(g/compute-vertex-normals)))
Am I missing something here? (like the mesh needing to be a manifold?)
Edit: (gmesh.cljx#243)
(transduce ntx g/+ (vec3 0 0 0))
Seems to fix the issue.
[org.clojure/clojure "1.7.0-beta3"]
[org.clojure/clojurescript "0.0-3291"]
[thi.ng/geom "0.0.783"]
[lein-cljsbuild "1.0.5"]
Is there a reason the SVG ellipse and polyline primitives are missing?
(-> (cuboid 40)
(g/as-mesh {:mesh (gm/gmesh)})
sd/butterfly)
;;=>
{:vertices
{nil
#{{:next [0.0 20.0 40.0], :prev [0.0 40.0 40.0], :f [[0.0 40.0 40.0] nil [0.0 20.0 40.0]]}
;; [...]
(-> (cuboid 80)
(g/as-mesh {:mesh (gm/gmesh)})
csg/mesh->csg)
... works as expected, but if I try to catmull-clark the mesh before converting to CSG, like this:
(-> (cuboid 80)
(g/as-mesh {:mesh (gm/gmesh)})
sd/catmull-clark
csg/mesh->csg)
... I get this stack overflow:
RT.java: 721 clojure.lang.RT/get
csg.cljc: 58 thi.ng.geom.mesh.csg$split_poly/invoke
csg.cljc: 143 thi.ng.geom.mesh.csg$csg_node$fn__18902/invoke
PersistentVector.java: 333 clojure.lang.PersistentVector/reduce
core.clj: 6518 clojure.core/reduce
csg.cljc: 142 thi.ng.geom.mesh.csg$csg_node/invoke
... do more complicated meshes push the recursive csg-node
function too deep?
hey there, this is the bug which we found on the workshop in bratislava
doing (-> (circle 20) (g/as-polygon 4) (g/extrude {:depth 1}) (g/translate [0 0 10]))
will result in an error
here's the stack
IllegalArgumentException No implementation of method: :+ of protocol: #'thi.ng.math.core/IMathOps found for class: java.lang.Double clojure
.core/-cache-protocol-fn (core_deftype.clj:568)
ws-bra-1.core=> *e
#error {
:cause "No implementation of method: :+ of protocol: #'thi.ng.math.core/IMathOps found for class: java.lang.Double"
:via
[{:type java.lang.IllegalArgumentException
:message "No implementation of method: :+ of protocol: #'thi.ng.math.core/IMathOps found for class: java.lang.Double"
:at [clojure.core$_cache_protocol_fn invokeStatic "core_deftype.clj" 568]}]
:trace
[[clojure.core$_cache_protocol_fn invokeStatic "core_deftype.clj" 568]
[clojure.core$_cache_protocol_fn invoke "core_deftype.clj" 560]
[thi.ng.math.core$eval1449$fn__1450$G__1424__1473 invoke "core.cljc" 8]
[thi.ng.geom.basicmesh$eval8466$fn__8507$fn__8508 invoke "basicmesh.cljc" 129]
[thi.ng.geom.utils$transform_mesh$fn__7797 invoke "utils.cljc" 426]
[clojure.core.protocols$iter_reduce invokeStatic "protocols.clj" 49]
[clojure.core.protocols$fn__6742 invokeStatic "protocols.clj" 75]
[clojure.core.protocols$fn__6742 invoke "protocols.clj" 75]
[clojure.core.protocols$fn__6684$G__6679__6697 invoke "protocols.clj" 13]
[clojure.core$reduce invokeStatic "core.clj" 6545]
[clojure.core$reduce invoke "core.clj" 6527]
[thi.ng.geom.utils$transform_mesh invokeStatic "utils.cljc" 425]
[thi.ng.geom.utils$transform_mesh invoke "utils.cljc" 417]
[thi.ng.geom.basicmesh$eval8466$fn__8507 invoke "basicmesh.cljc" 129]
[thi.ng.geom.core$eval3115$fn__3116$G__3106__3137 invoke "core.cljc" 43]
[ws_bra_1.core$make_rings_along_curve$fn__14626 invoke "core.clj" 59]
[clojure.core$map_indexed$mapi__7050$fn__7051 invoke "core.clj" 7022]
[clojure.lang.LazySeq sval "LazySeq.java" 40]
[clojure.lang.LazySeq seq "LazySeq.java" 49]
[clojure.lang.RT seq "RT.java" 521]
[clojure.core$seq__4357 invokeStatic "core.clj" 137]
[clojure.core$print_sequential invokeStatic "core_print.clj" 46]
[clojure.core$fn__6072 invokeStatic "core_print.clj" 153]
[clojure.core$fn__6072 invoke "core_print.clj" 153]
[clojure.lang.MultiFn invoke "MultiFn.java" 233]
[clojure.tools.nrepl.middleware.pr_values$pr_values$fn$reify__614 send "pr_values.clj" 35]
[clojure.tools.nrepl.middleware.interruptible_eval$evaluate$fn__648$fn__661 invoke "interruptible_eval.clj" 113]
[clojure.main$repl$read_eval_print__7408 invoke "main.clj" 241]
[clojure.main$repl$fn__7417 invoke "main.clj" 258]
[clojure.main$repl invokeStatic "main.clj" 258]
[clojure.main$repl doInvoke "main.clj" 174]
[clojure.lang.RestFn invoke "RestFn.java" 1523]
[clojure.tools.nrepl.middleware.interruptible_eval$evaluate$fn__648 invoke "interruptible_eval.clj" 87]
[clojure.lang.AFn applyToHelper "AFn.java" 152]
[clojure.lang.AFn applyTo "AFn.java" 144]
[clojure.core$apply invokeStatic "core.clj" 646]
[clojure.core$with_bindings_STAR_ invokeStatic "core.clj" 1881]
[clojure.core$with_bindings_STAR_ doInvoke "core.clj" 1881]
[clojure.lang.RestFn invoke "RestFn.java" 425]
[clojure.tools.nrepl.middleware.interruptible_eval$evaluate invokeStatic "interruptible_eval.clj" 85]
[clojure.tools.nrepl.middleware.interruptible_eval$evaluate invoke "interruptible_eval.clj" 55]
[clojure.tools.nrepl.middleware.interruptible_eval$interruptible_eval$fn__693$fn__696 invoke "interruptible_eval.clj" 222]
[clojure.tools.nrepl.middleware.interruptible_eval$run_next$fn__688 invoke "interruptible_eval.clj" 190]
[clojure.lang.AFn run "AFn.java" 22]
[java.util.concurrent.ThreadPoolExecutor runWorker "ThreadPoolExecutor.java" 1142]
[java.util.concurrent.ThreadPoolExecutor$Worker run "ThreadPoolExecutor.java" 617]
[java.lang.Thread run "Thread.java" 745]]}
ws-bra-1.core=>
ws-bra-1.core=> (-> (circle 20) (g/as-pol
g/as-polar g/as-polygon
ws-bra-1.core=> (-> (circle 20) (g/as-polygon 4))
#thi.ng.geom.types.Polygon2{:points [[20.0 0.0] [1.2246467991473533E-15 20.0] [-20.0 2.4492935982947065E-15] [-3.673940397442059E-15 -20.0]]
}
ws-bra-1.core=> (require 'ws-bra-1.core :reload)
CompilerException java.lang.IllegalArgumentException: No implementation of method: :+ of protocol: #'thi.ng.math.core/IMathOps found for cla
ss: java.lang.Double, compiling:(ws_bra_1/core.clj:63:1)
ws-bra-1.core=> (-> (circle 20) (g/as-polygon 4) (g/extrude)
g/extrude g/extrude-shell
ws-bra-1.core=> (-> (circle 20) (g/as-polygon 4) (g/extrude {:depth 1}))
#thi.ng.geom.types.BasicMesh{:vertices #{0.0 1.0 20.0 [-3.673940397442059E-15 -20.0 0.0] [-20.0 2.4492935982947065E-15 0.0] [-20.0 2.4492935
982947065E-15 1.0] [-3.673940397442059E-15 -20.0 1.0] [20.0 0.0 1.0] [1.2246467991473533E-15 20.0 1.0] [20.0 0.0 0.0] [1.2246467991473533E-1
5 20.0 0.0]}, :faces #{#object[thi.ng.geom.meshface.MeshFace 0x1e1905bf "[[[-20.0 2.4492935982947065E-15 0.0] [-3.673940397442059E-15 -20.0
0.0] [-3.673940397442059E-15 -20.0 1.0] [-20.0 2.4492935982947065E-15 1.0]]]"] #object[thi.ng.geom.meshface.MeshFace 0x6bfd871b "[[[-3.67394
0397442059E-15 -20.0 0.0] [20.0 0.0 0.0] [20.0 0.0 1.0] [-3.673940397442059E-15 -20.0 1.0]]]"] #object[thi.ng.geom.meshface.MeshFace 0x762cb
26f "[[[1.2246467991473533E-15 20.0 0.0] [-20.0 2.4492935982947065E-15 0.0] [-20.0 2.4492935982947065E-15 1.0] [1.2246467991473533E-15 20.0
1.0]]]"] #object[thi.ng.geom.meshface.MeshFace 0x2657b8ec "[[[20.0 0.0 0.0] [1.2246467991473533E-15 20.0 0.0] [1.2246467991473533E-15 20.0 1
.0] [20.0 0.0 1.0]]]"] #object[thi.ng.geom.meshface.MeshFace 0x70357564 "[([-3.673940397442059E-15 -20.0 0.0] [-20.0 2.4492935982947065E-15
0.0] [1.2246467991473533E-15 20.0 0.0] [20.0 0.0 0.0])]"] #object[thi.ng.geom.meshface.MeshFace 0x77f7e126 "[[20.0 0.0 1.0]]"]}, :fnormals {
}}
ws-bra-1.core=> (-> (circle 20) (g/as-polygon 4) (g/extrude {:depth 1}) (g/translate [0 0 10]))
IllegalArgumentException No implementation of method: :+ of protocol: #'thi.ng.math.core/IMathOps found for class: java.lang.Double clojure
.core/-cache-protocol-fn (core_deftype.clj:568)
Add helper fn to return hashmap w/ react lifecycle methods to specify WebGL canvas components (but without requiring additional deps)
https://github.com/thi-ng/ws-ldn-8/blob/master/day1/ex03/src/ex03/webgl04.cljs
If you use :flags :nesw
(for example) on the aabb, the texture appears to map to the wrong faces. So, 'front' and 'back' are removed but the texture still labels two of the sides 'front' and 'back' rather than 'east' and 'west'. It appears to have something to do with which faces are omitted, because :flags :ewfb
works fine.
As the title says, I am getting and error when using the latest version of clojurescript 1.10.x
with thi.ng/geom. When using together with figwheel i get this following error.
---- Could not Analyze resources/public/js/compiled/out/thi/ng/geom/gl/core.cljc line:437 column:41 ----
Can't recur here at line 437 resources/public/js/compiled/out/thi/ng/geom/gl/core.cljc
435 (set! (.-onselectstart canvas) (constantly false))
436 (if ctx ctx (recur (next ids))))
437 (catch js/Error e (recur (next ids))))))]
^--- Can't recur here at line 437 resources/public/js/compiled/out/thi/ng/geom/gl/core.cljc
438 (or ctx (err/unsupported! "WebGL not available"))))))
439 #?(:clj
440 (defn clear-color-buffer
---- Analysis Error : Please see resources/public/js/compiled/out/thi/ng/geom/gl/core.cljc ----
I use this version [org.clojure/clojurescript "1.9.89"] to make it work.
I'm writing a CLJS program that makes a mesh for a dodecahedron by calculating all of its faces, but I'm unable to get its surface area with a call to thi.ng.geom.core/area
. I've reduced my program to what's necessary to reproduce the problem below
(ns dodecahedron.core
(:require [thi.ng.math.core :as math]
[thi.ng.geom.core :as geom]
[thi.ng.geom.gmesh :as gmesh]
[thi.ng.geom.types.utils :as tu]))
(def ^:const τ math/TWO_PI)
;; spherical coordinates are in the physics convention
;; (radial distance, polar angle, azimuthal)
(defn ->cartesian [[r theta phi]]
[(* r (js/Math.sin theta) (js/Math.cos phi))
(* r (js/Math.sin theta) (js/Math.sin phi))
(* r (js/Math.cos theta))])
(defn dodecahedron [s]
(let [r (* math/SQRT3 math/PHI s 0.5)
theta (js/Math.asin (/ (* math/SQRT3 math/PHI)))
central-angle (/ τ 5)
offset (* central-angle 0.5)
quad #(let [a (* % central-angle)]
(vector [r (* 2 theta) a]
[r (* 4 theta) a]
[r (* 5 theta) (+ a offset)]
[r (* 7 theta) (+ a offset)]))
spherical-coords (mapcat quad (range 5))
cart-coords (map ->cartesian spherical-coords)
[b a f z g k p t l q r s h m i n c d e j] cart-coords
faces [[a b c d e] [k g b a f] [q l g k p] [m h l q r] [d c h m i] [l h c b g]
[z f a e j] [t p k f z] [s r q p t] [n i m r s] [j e d i n] [t z j n s]]]
(tu/into-mesh (gmesh/gmesh) gmesh/add-face faces)))
(geom/area (dodecahedron 5))
#object[Error Error: No protocol method PMathOps.- defined for type cljs.core/PersistentVector: [3.142002665914173 2.2827985598928664 -5.831362385532202]]
cljs.core/missing-protocol (jar:file:/Users/cjlarose/.m2/repository/org/clojure/clojurescript/1.7.170/clojurescript-1.7.170.jar!/cljs/core.cljs:261:4)
Function.thi.ng.geom.core._.cljs$core$IFn$_invoke$arity$2 (jar:file:/Users/cjlarose/.m2/repository/thi/ng/geom-core/0.0.908/geom-core-0.0.908.jar!/thi/ng/geom/core.cljc:6:1)
thi.ng.geom.core/- (jar:file:/Users/cjlarose/.m2/repository/thi/ng/geom-core/0.0.908/geom-core-0.0.908.jar!/thi/ng/geom/core.cljc:6:1)
thi.ng.geom.core.utils/norm-sign3 (jar:file:/Users/cjlarose/.m2/repository/thi/ng/geom-core/0.0.908/geom-core-0.0.908.jar!/thi/ng/geom/core/utils.cljc:259:28)
Function.thi$ng$geom$core$utils$tri_area3 (jar:file:/Users/cjlarose/.m2/repository/thi/ng/geom-core/0.0.908/geom-core-0.0.908.jar!/thi/ng/geom/core/utils.cljc:265:19)
Function.cljs.core.apply.cljs$core$IFn$_invoke$arity$2 (jar:file:/Users/cjlarose/.m2/repository/org/clojure/clojurescript/1.7.170/clojurescript-1.7.170.jar!/cljs/core.cljs:3448:18)
cljs$core$apply (jar:file:/Users/cjlarose/.m2/repository/org/clojure/clojurescript/1.7.170/clojurescript-1.7.170.jar!/cljs/core.cljs:3439:1)
Function.G__7855__2 (jar:file:/Users/cjlarose/.m2/repository/org/clojure/clojurescript/1.7.170/clojurescript-1.7.170.jar!/cljs/core.cljs:4202:24)
Am i constructing the mesh incorrectly in some way? Or is this a legitimate bug in the area
implementation?
Currently common protocol methods like translate
, scale
and the various basic vector math ops allow specifying coordinate args as vectors or individual coords, e.g.
(g/translate (a/aabb 1) (vec3 10 20 30))
(g/translate (a/aabb 1) [10 20 30])
(g/translate (a/aabb 1) 10 20 30)
About the last case:
Pros:
Cons:
Proposal:
Thoughts?
Hi there - thanks for the amazing tools. 😄 I've got a bar graph working in my reagent project and am now looking at adding the GitHub-commit style visualisation.
commits->matrix
function I'm stuck as byte-array
doesn't exist in ClojureScript. I tried binding mat
to ((nd/ndarray :int32 (repeat (* 7 weeks) 0) [7 weeks])
but it didn't make any difference - I get a weird error down the line:[Error] TypeError: f.call is not a function. (In 'f.call(null,x)', 'f.call' is undefined)
(anonymous function) (core.js:125)
(anonymous function) (core.js:980)
(anonymous function) (core.js:18375:140)
(anonymous function) (core.js:7888:101)
cljs$core$IFn$_invoke$arity$3 (core.js:7889)
cljs$core$IReduce$_reduce$arity$3 (core.js:11385)
cljs$core$IFn$_invoke$arity$3 (core.js:7983)
cljs$core$IFn$_invoke$arity$2 (core.js:18374:82)
cljs$core$mapv (core.js:18355)
thi$ng$geom$viz$core$svg_axis_STAR_ (core.js:950:502)
thi$ng$geom$viz$core$svg_x_axis_cartesian (core.js:968)
thi$ng$geom$viz$core$svg_plot2d_cartesian (core.js:1063:172)
**manul_frontend$core$github (core.js:660:274)**
manul_frontend$core$home_page (core.js:687:1182)
G__9104__1 (core.js:3733:125)
G__9104 (core.js:3886)
(anonymous function) (component.js:127)
reagent$impl$component$wrap_render (component.js:150)
reagent$impl$component$do_render (component.js:196)
(anonymous function) (component.js:222)
reagent$ratom$in_context (ratom.js:61)
reagent$ratom$deref_capture (ratom.js:70)
reagent$ratom$run_in_reaction (ratom.js:1424)
home-page_render (component.js:220)
measureLifeCyclePerf (react-dom.inc.js:4529)
_renderValidatedComponentWithoutOwnerOrContext (react-dom.inc.js:5249)
_renderValidatedComponent (react-dom.inc.js:5276)
performInitialMount (react-dom.inc.js:4816)
mountComponent (react-dom.inc.js:4712)
mountComponent (react-dom.inc.js:11542)
mountChildren (react-dom.inc.js:10429)
_createInitialChildren (react-dom.inc.js:6164)
mountComponent (react-dom.inc.js:5983)
mountComponent (react-dom.inc.js:11542)
performInitialMount (react-dom.inc.js:4825)
mountComponent (react-dom.inc.js:4712)
mountComponent (react-dom.inc.js:11542)
performInitialMount (react-dom.inc.js:4825)
mountComponent (react-dom.inc.js:4712)
mountComponent (react-dom.inc.js:11542)
mountComponentIntoNode (react-dom.inc.js:9757)
perform (react-dom.inc.js:14724)
batchedMountComponentIntoNode (react-dom.inc.js:9779)
perform (react-dom.inc.js:14724)
_renderNewRootComponent (react-dom.inc.js:9973)
_renderSubtreeIntoContainer (react-dom.inc.js:10054)
reagent$dom$render_comp (dom.js:49)
cljs$core$IFn$_invoke$arity$3 (dom.js:121)
reagent$dom$render (dom.js:102)
cljs$core$IFn$_invoke$arity$2 (dom.js:112)
reagent$dom$render (dom.js:98)
cljs$core$IFn$_invoke$arity$2 (core.js:182)
reagent$core$render (core.js:168)
manul_frontend$core$mount_root (core.js:750)
cljs$core$IFn$_invoke$arity$2 (core.js:13060)
cljs$core$apply (core.js:13028)
G__35851__delegate (build_app.js:11)
cljs$lang$applyTo (build_app.js:27)
cljs$core$IFn$_invoke$arity$2 (core.js:13057)
cljs$core$apply (core.js:13028)
(anonymous function) (file_reloading.js:2046)
Can I drop in a replacement for byte-array? I used int64 because int32 is not available in the CLJS version of ndarray.
commits
to my raw data in the actual example hm-github.clj
(so running on Clojure, not ClojureScript) and it actually doesn't work, saying CompilerException java.lang.IllegalArgumentException: Value out of range for byte: 228, compiling:(/Users/farhan/code/geom/geom-viz/babel/examples/hm-github.clj:57:1)
- I definitely never had 228 commits in a day! But I guess the use of a byte array assumes a certain number of commits per day? Maybe if you can talk me through generally what's happening in this code I can fix it myself...It's worth mentioning that my timestamp data is from another source, not GitHub commits. Here is the data as a list:
(1467504000 1467504000 1467849600 1467936000 1467936000 1468108800 1468108800 1468108800 1468108800 1468108800 1468368000 1468368000 1468454400 1468454400 1468454400 1468454400 1468454400 1467849600 1468627200 1468627200 1468627200 1479600000 1468540800 1468540800 1468713600 1468713600 1468713600 1468886400 1468886400 1468972800 1468972800 1469059200 1469059200 1469059200 1469145600 1469232000 1469232000 1469232000 1469577600 1469577600 1469750400 1469750400 1470182400 1470182400 1470268800 1470268800 1470268800 1470268800 1470355200 1470355200 1470528000 1470528000 1470528000 1470528000 1471132800 1471132800 1471132800 1471478400 1471478400 1471478400 1473292800 1473292800 1473292800 1473292800 1474416000 1474416000 1476316800 1476316800 1476316800 1476316800 1477094400 1477094400 1477699200 1477699200 1477785600 1477785600 1477785600 1477958400 1477958400 1477958400 1478044800 1478044800 1478044800 1478044800 1478131200 1478131200 1478131200 1478217600 1478217600 1478304000 1478304000 1478390400 1478390400 1478649600 1478649600 1478736000 1478736000 1478736000 1478822400 1478822400 1478908800 1478908800 1478908800 1478908800 1478908800 1478908800 1478908800 1478908800 1478908800 1478908800 1479254400 1479254400 1479254400 1479340800 1479340800 1479340800 1479600000 1479600000 1479600000 1479600000 1479600000 1479600000 1479600000 1479600000 1479600000 1479686400 1479686400 1479686400 1486771200 1486771200 1486857600 1486857600 1486944000 1486944000 1487203200 1487203200 1487203200 1487376000 1487376000 1487376000 1487721600 1487721600 1487894400 1487894400 1487894400 1487894400 1487894400 1487894400 1487894400 1487894400 1487980800 1487980800 1487980800 1488240000 1488326400 1488326400 1488326400 1488412800 1488412800 1488412800 1488412800 1488758400 1488758400 1488758400 1488931200 1488931200 1488931200 1489363200 1489363200 1489363200 1489536000 1489536000 1490227200 1490227200 1490227200 1490400000 1490400000 1490400000 1490400000 1490400000 1490400000 1490400000 1490400000 1490400000 1490400000 1490400000 1490400000 1490400000 1490832000 1490832000 1490832000 1491696000 1491696000 1492214400 1492214400 1492819200 1492819200 1492819200 1492819200 1492819200 1492819200 1492819200 1495065600 1495065600 1495065600 1495324800 1495324800 1495324800 1495324800 1495324800 1495411200 1495411200 1496275200 1496275200 1496275200 1496275200 1497830400 1497830400 1497830400 1498262400 1498262400 1498262400 1498262400 1498262400 1498262400 1498262400 1498262400 1498262400 1498262400 1498262400 1498694400 1498694400 1498694400 1499558400 1499558400 1500681600 1500681600 1500681600 1500681600 1500681600 1500681600 1500681600 1501891200 1501891200 1502064000 1502064000 1502064000 1502323200 1502323200 1502323200 1502928000 1502928000 1502928000 1502928000)
Thanks for any help you can give.
Alternatively, could you maybe show me the code for this stuff on the thi.ng homepage?
I'm aware the below polygons aren't a valid 'solid', omitting some polygons for clarity.
In my 'real' code I'm using g/extrude some-poly {:depth 280}
on some 100 different extruded polygons, which all are succeeding apart from the one below.
This fails with "call stack size exceeded":
(def polys
[
[(vec3 942 440 0) (vec3 879 515 0) (vec3 884 527 0) (vec3 954 445 0)]
[(vec3 942 440 0) (vec3 879 515 0) (vec3 879 515 280) (vec3 942 440 280)]
])
(mesh->csg
(reduce
(fn [m f]
(g/add-face m f))
(basic-mesh)
polys))
But with the first polygon only mesh->csg
succeeds:
(def polys
[
[(vec3 942 440 0) (vec3 879 515 0) (vec3 884 527 0) (vec3 954 445 0)]
])
With the second polygon only mesh->csg
throws "call stack size exceeded" (?!)
(def polys
[
[(vec3 942 440 0) (vec3 879 515 0) (vec3 879 515 280) (vec3 942 440 280)]
])
This is bizarre :-) Seems the call to csg-node
ends up in an endless loop.
Question of course is: how the hell can that happen with a single polygon?
It looks like some specific polygon orientations induce the problem.
Below the full "problem" mesh:
#thi.ng.geom.types.BasicMesh{
:vertices #{
#<[942 440.8021545410156 0]>
#<[879.2171630859375 515 0]>
#<[884.7828369140625 527 0]>
#<[954 445.1978454589844 0]>
#<[884.7828369140625 527 280]>
#<[954 445.1978454589844 280]>
#<[879.2171630859375 515 280]>
#<[942 440.8021545410156 280]>},
:faces #{
(#<[942 440.8021545410156 0]> #<[879.2171630859375 515 0]>
#<[884.7828369140625 527 0]> #<[954 445.1978454589844 0]>)
[#<[954 445.1978454589844 0]>
#<[884.7828369140625 527 0]>
#<[884.7828369140625 527 280]>
#<[954 445.1978454589844 280]>]
[#<[884.7828369140625 527 0]>
#<[879.2171630859375 515 0]>
#<[879.2171630859375 515 280]>
#<[884.7828369140625 527 280]>]
[#<[879.2171630859375 515 0]>
#<[942 440.8021545410156 0]>
#<[942 440.8021545410156 280]>
#<[879.2171630859375 515 280]>]
[#<[942 440.8021545410156 0]>
#<[954 445.1978454589844 0]>
#<[954 445.1978454589844 280]>
#<[942 440.8021545410156 280]>]
[#<[954 445.1978454589844 280]>
#<[884.7828369140625 527 280]>
#<[879.2171630859375 515 280]>
#<[942 440.8021545410156 280]>]}, :fnormals {}, :attribs {}}
The polygon used with (g/extrude poly {:depth 280})
#thi.ng.geom.types.Polygon2{
:points [
#<[942 440.8021545410156]>
#<[879.2171630859375 515]>
#<[884.7828369140625 527]>
#<[954 445.1978454589844]>]}
Which means I can't require thi.ng.geom.vector in clojurescript files.
I don't know enough about org files to really understand if I've found a bug or just getting something wrong here :)
The simple voxel eroded cube demonstration works a treat with clojure, but throws this exception when run with clojurescript in the browser:
Uncaught TypeError: vertices__$1.call is not a functionthi.ng.geom.voxel.isosurface.cell_vertice_builder @ isosurface.cljc:360(anonymous function) @ core.cljs:2138cljs.core.seq_reduce.cljs$core$IFn$_invoke$arity$3 @ core.cljs:2138cljs.core.LazySeq.cljs$core$IReduce$_reduce$arity$3 @ core.cljs:3047cljs.core.reduce.cljs$core$IFn$_invoke$arity$3 @ core.cljs:2182cljs$core$reduce @ core.cljs:2153thi$ng$geom$voxel$isosurface$surface_mesh @ isosurface.cljc:391(anonymous function) @ voxels.cljs:24
reload.cljs:62 Reload
Hi,
I'm trying to retrieve thi.ng/geom-core 0.3.0-SNAPSHOT which is published on Clojars, but it depends form thi.ng/macromath 0.3.0-SHAPSHOT, which is not published
https://clojars.org/thi.ng/macromath
Is this expected/wanted?
thanks in advance, and thank you for this wonderful project
Hi!
Sorry, I understand that this is not the right place where to ask this.
I'm a big fan of processing.org and toxiclibs but I'm a little bit bored about java as a language itself.
So here is a question: is there any tutorial or getting started or any other kind of advice to use thi.ng?
Some of the triangles are missing, e.g.
(ns foo.core
(:require [thi.ng.geom.sphere :as sphere]
[thi.ng.geom.core :as g]))
(def sm (-> (sphere/sphere 2) (g/as-mesh {:res 3})))
(count (:faces sm)) ;; ==> 9
Visual inspection of the mesh in a stl viewer shows 3 triangles at each of the "poles". It seems there ought to be 6 triangles around the "equator", but I see only 3, leaving three holes.
https://github.com/thi-ng/geom/blob/master/geom-viz/src/core.org#force-directed-graph-layout
It looks like this project is on pause, but I'm wondering if a graph layout could be in the works.
I don't have too much opengl experience but I'm looking to do some visualisations using geom and worldwind.
I saw that both libraries use org.jogamp.jogl/jogl-all, if that helps integration at all.
I'm hoping to get some tips on how and where to start.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.