@mikera: What do I need to do to get a Vec3 vector from core.matrix with (set-current-implementation :vectorz)
? Or does this do the trick:
(array [1 2 3])
=> #vectorz/vector[1.0 2.0 3.0]
The current string versions of vectors and matrices doesn't match the documentation so it gets a little confusing.
That's actually a dense array backed Vector. If you want the primitive Vector3 you can use mikera.vectorz.core/vec3
Or you van just use Java interop to instantiate a Vector3 directly... that will actually be faster as it avoids some Clojure overhead
This is to store a whole bunch of vertices, so faster is better.
So what would that Java interop look like?
I guess I need to import something from vectorz?
I have to say as someone new to matrices that my impression so far of core.matrix is that the code looks really good - well organized namespaces, docstrings on everything, readable code, etc. Very nice.
The documentation, on the other hand, is not up-to-par. It has taken me far too long to understand the relationship between all the pieces and I don't know how to do something basic, like create a Vector3, and there is nothing to walk me from a beginner level to an intermediate level. And I think I'm reasonably intelligent and have been coding for some time now, so I don't think it's just me. And if what I say is true then you are probably losing a lot of people who might otherwise give core.matrix a shot.
Take that as tough love from someone who does actually care about your project and wants it to succeed.
So are these examples on the wiki no longer valid? https://github.com/mikera/vectorz-clj/wiki/Examples
@mikera: ^
Hmmm example should still be valid but the underlying types might have changed, as has the string representation
That very first example contradicts what you just told me:
(def v (array [1 2 3]))
; => #<Vector3 [1.0,2.0,3.0]>
No offense, but, frustrating as fsck, if you don't mind me saying so. 😱
Yeah, you now get a Vector with length 3
I'll have a check through the docs and see what is useful to update. Contributions also welcome, if you find anything that can be improved.
Using nREPL in Cursive this is what I see:
(def v (array [1 2 3]))
=> #'cad.mesh.core/v
v
=> #vectorz/vector[1.0 2.0 3.0]
First I have to understand how to make any improvements before I can contribute. And I'd be happy to contribute, unless I give up.
Yeah the string representation changed to support tagged reader literals
It should still behave the same however, it is still a mutable length 3 vector
But is it the magical Vector3 that is listed as a feature and that you just told me I should use Java interop to create?
The old string rep looked that way.
This is me taking my very first step to make use of a Vector3 in my mesh processing code. That's all I'm trying to do at this point.
I've got:
(:require [clojure.core.matrix :refer :all]
[clojure.core.matrix.operators :refer :all]
and (set-current-implementation :vectorz)
and I can follow the examples in the REPL. That's where I'm at.And I'm looking at examples the have use
which I never use because I thought it was not considered good practice any more and the examples don't match what I'm seeing in the REPL and they don't match in a way that is hard to ignore because I can't tell what type I'm dealing with and that's kind of the point of using core.matrix and optimizing my code. 😞
(class (array :vectorz [1 2 3])) => mikera.vectorz.Vector
(class (Vector3/of 1 2 3)) => mikera.vectorz.Vector3
(class (mikera.vectorz.core/vec3 1 2 3)) => mikera.vectorz.Vector3
It sounds like you want one of the latter two options
Okay, how are you getting a Vector3? It isn't available in my current setup. I need another :require
It's a Java import, add following to your ns
(:import [mikera.vectorz Vector1 Vector2 Vector3 Vector4])
Sweet. TYVM
(class (Vector3/of 1 2 3))
=> mikera.vectorz.Vector3
This is to store the [x y z] vertices so that should work.
:simple_smile:
Making this change is going to break Humpty Dumpty into a bunch of pieces that I'll need to put back together. Wish me luck. 😉
Good luck! Excited to see the results!
@mikera: I will definitely let you know. Working on it now.
So it looks like all the namespaces where I'm doing matrix manipulations will need to have this added to them:
(:refer-clojure :exclude [+ - * / == min max])
(:require [clojure.core.matrix.operators :refer :all]
@mikera: Question for you. I need an interpolate function and seem to recall that vectorz had one but it isn't in the core.matrix api. Is that correct?
You can use scale-add!
for interpolation in the core.matrix API, it's a relatively new function
normalise instead of normalize? Got something against American English?
@mikera: I don't think core.matrix is the place to fight a language battle - I suggest giving in and using normalize
.
and whatever other variations are lurking in there
colour
All unnecessary and easily avoidable barriers to adoption should be removed.
core.matrix uses international / british english as standard. Not going to change :simple_smile:
@mikera: I'm calculating the area of triangles and the old code used a magnitude
of a vector with code like this:
(vm/rewrite-v3 buf (Math/sqrt (mm/madd x x y y z z))))
Is there a simple equivalent in core.matrix - with or without british spelling... 😉
This is the untested code I've got so far for this:
(defn mag [[x y z]]
(Math/sqrt (+ x x y y z z)))
(defn norm-sign3
[a b c] (mag (cross (- b a) (- c a))))
(defn tri-area3
[a b c] (* 0.5 (norm-sign3 a b c)))
You can use length
to get the Euclidean length and cross
for the cross product
And this pulls it all together:
(defn area
[face]
((if (= 3 (count face))
(apply tri-area3 face)
(let [cent (centroid face)]
(reduce + (map (fn [[v1 v2]] (tri-area3 cent v1 v2))
(vert-pairs face)))))))
I still need to brush up on my maths. Been a long time.
You can avoid using the centroid too I think, just use one of the points
See how I said "maths" instead of "math" - so British of me. 😉
Though you need to be careful about signs if the face is non-convex....
Well, the face might not be planar, so area is not going to be %100 relevant or accurate, but I don't care so I figured triangulating it with the centroid would be reasonable.
Ah that makes sense
Yeah, I'm just using it as a characteristic for some of the face coloring algorithms.
And, actually, at the point I apply it they are all triangles, but I generalize the code regardless.
Hopefully the code I have will work and then we can clean it up later.
The old code worked...
I'm just trying to do the least possible to convert to core.matrix and then let you review it.
My brain is about fried. Not sure if I can convert this to core.matrix:
(defn centroid
[[x & xs :as coll]]
(case (count coll)
0 nil
1 x
2 (gc/mix x (first xs))
(let [s (/ 1.0 (count coll))
f (fn [x _] (* x s))]
(gc/reduce-vector x + f xs))))