crawls out of the woodwork ooft missed some good stuff. @meow ported a swarm over to core.matrix, i like core.matrix, it turned out that the current implementation in Brevis is still faster than pure matrix just because of KD-trees (@mikera the comment about speed was skewed, because I’d left my video recording code enabled when doing the initial speed comparisons). @eggsyntax i was playing with that three.js playground code over break, but ran into some issues linking cljsjs/mathbox in a bootstrapped environment (i think that is cljs naivety that just requires a fresh start though) [also noting @meow that the approach was to link to that cljs-bootstrap-repl repo]
still going to port brevis’ matrix code to core.matrix, but that’ll be stalled a bit since 1-10k swarm agents are bearable now
and time constraints have me thinking about swapping back to a non-bootstrapped cljs-mathbox for now
I have a few minor issues with core.matrix but I have to say I have been quite pleased with it so far as a library.
Starting with the bad - I think there needs to be more documentation and I don't like some aspects of the current docs as far as how to use
the library in your namespace. I've settled on simply doing (:require [clojure.core.matrix :as mx])
which doesn't pollute my namespace. I don't bother with the operators (which then have to be excluded from clojure otherwise you keep getting warnings).
Not a big deal but this little crap sure slows you down when you first start using a new library.
Next complaint is that the docstrings in the source code are of an inconsistent length and too many of them are > 80 chars which doesn't work well with the way I've got my code and repl windows arranged in Cursive.
Which quickly brings us to the good stuff. There actually are docstrings! :simple_smile:
Seriously. There are docstrings and they are pretty good. The code is readable and does a nice job of using protocols. I feel like it was a good move for me and I will have much better control and understanding of my use of matrices and vectors (in the matrix/vector sense, not to be confused with basic Clojure vectors, just like the map function shouldn't be confused with the map structure, oy vey!)
mmm, i do like it as well, and also immediately put it into its own namespace instead of how it is setup in the examples
Performance is good and maybe slightly better than what was in the http://thi.ng library.
on what kind of operations?
specifically, things at the level of individual vertices represented as core.matrix vectors?
So here is the fun part. At this point a mesh is a defrecord with one attribute which is a clojure set of faces, and a face is just a clojure vector of vertices, where a vertex is a Vector3 from vectorz. Everything else is a computed index that may or may not get assoc'd with the mesh.
Which means there is lots of room for experimentation with alternate structures.
ah, so the operations are for small matrix ops?
1x3 and 3x3 inputs?
well, there are small things like scale and normalize and so forth that get applied at the Vector3 level.
But I'm putting the entire mesh through multiple operators, each of which builds a new mesh based on the old mesh and those end up producing into the millions of faces so I want to explore storing those faces in matrices instead of a clojure set.
gotcha
What I have, though, is a situation where each operation might need to have different indexes into the mesh data. So rather than try to have one monolithic approach to the structure of a mesh I've adopted an approach where each operator expects to receive a mesh in some minimal representational form. Then it creates indexes that it may just hold onto locally or it can assoc to the mesh (because a mesh is just a simple defrecord that is primarily about protocol implementation, not about data structure) to do whatever the operation needs to do. Then it returns a new, simple mesh again.
So what I will probably end up with is a wide variety of ways to quickly/temporarily get mesh data in whatever structure is needed for the duration of some function operator.
One mesh defrecord with lots of ways to index it as opposed to several different defrecords defining different mesh structures.
To take a seed shape, mutate the heck out of it, and produce an X3D file or anything similar, all you need is a collection of faces where a face is an ordered sequence of vertices in counter-clockwise order. That's it. Everything else is just indexing it to make it easier to perform an operation.
This is true because I'm not trying to create a GUI editing environment where the user needs to be able to select and mutate stuff.
If that were the case I would have to pick something like a winged-edge data structure or something.
But I'm targeting doing everything in clojure so there functions rule the day.
All the code is here if anyone wants to look at it or comment on the approach. I'm open to alternative points of view. https://github.com/pkobrien/cad/tree/master/src/cad/mesh
@kephale: awesome — Lemme know if you get stuck, I’d be happy to see if I can help (although my availability is intermittent this week).
@eggsyntax: have you seen https://github.com/evanw/theta
not cljs, but just saw it released
No, that’s cool! Haven’t heard of Skew before. I tend to just jump to http://wolframalpha.com if I just need a quick graph. For something to include in code, I’ve gone a bunch of different ways. For graphing data (in my code), I often turn to http://multigraph.org/, which a friend of mine wrote and should be much better-known IMO...
Oh neat, multigraph looks good… i think i’ll still try to stick it out until getting the bootstrapped cljs-mathbox working in terms of web-based plotting, but we shall see… the semester is quickly approaching