I have a spec for a "vertex" (a 2D point in the plane, represented with a map holding two double values) and a "rectangle" (an axis-aligned rectangular area in the plane, represented by a map of two "vertex" values), defined as follows:
; vertex coordinates are doubles (need to make sure "=" doesn't try to
; compare floats in one vertex and doubles in another one, which fails)
(s/def ::vtx-x double?)
(s/def ::vtx-y double?)
; vertex is a map representing a 2D point
(s/def ::vertex (s/keys :req [::vtx-x ::vtx-y]))
; rectangle corners "low" (low x,y) and "high" (high x,y) are vertexes
(s/def ::rec-lo ::vertex)
(s/def ::rec-hi ::vertex)
; rectangle has internal sorting constraint, specified via a predicate
(s/def ::rectangle-internally-sorted
(fn [rect]
(let [lo-vtx (::rec-lo rect)
hi-vtx (::rec-hi rect)
lo-x (::vtx-x lo-vtx)
lo-y (::vtx-y lo-vtx)
hi-x (::vtx-x hi-vtx)
hi-y (::vtx-y hi-vtx)]
(< lo-x hi-x) (< lo-y hi-y))))
; rectangle is a map of two vertexes
; representing an axis-aligned rectangular area
(s/def ::rectangle
(s/and
(s/keys :req [::rec-lo ::rec-hi])
::rectangle-internally-sorted))
Client code should be able to use specs ::vertex and ::rectangle only.
Can I hide (make private) the supporting specs?
You can’t and you shouldn’t. Hiding the underlying specs would only hamper users of your specs as they would not be able to make sense of spec or gen failures, or of the form returned by s/form. In that sense component specs are not an implementation detail, they inevitably surface to consumers in one way or another.
Specs are namespaced, though. You could certainly move internals to a different namespace, which you could declare out of bounds for consumers. I would ask what is to be gained from this; information hiding has never been stressed much in Clojure, and with spec in particular (a data description language), the public/private distinction seems to me somewhat out of place.
Related
I've been using SDL for input on ios but whenever I get the finger's coordinates from the event structure they are normalized. Now I'm wondering how I change these normalized coordinates to device space so I can use?
Examples of how they look normalized:
2.8026e-45
"Normalized", in this instance, simply means "between 0 and 1". That is a really, really unusually small number to be getting out of the structure, regardless of the units, and suggests that the data is either uninitialized, or being interpreted using the wrong typecasting (if you reinterpreted the bits of the integer 2 as a float32, you would get that value).
I'm working on a 3d map generator platform on C++/OpenGL and, after finishing with Perlin's Noise, I needed to load some 3d models into my screen. I never tried it before and after read about it I decided to use COLLADA's model format. The first thing I did was to read the XML file through TinyXML and convert it to understandable classes inside my code. I can access everything with no problem. So far all was well, but the problem to me appeared when I tried to properly convert the XML's information in 3d static models. I read many tutorials about, but I think I didn't catch the "essence" of COLLADA and then I'm here asking for help. My ".dae" file consists of a simple sphere created on Blender. It doesn't matter what I do, whenever I try to load it into my screen what I get is always something as a "thorny thing", like this image:
http://s2.postimg.org/4fdz2fpl4/test.jpg
Surely I'm not taking the correct coordinates or at least I'm not implementing them correctly.
Here is the exactly COLLADA file that I'm testing. In short, what I'm doing is the following:
1 - First I access "polylist" and get the values of "p", also the ID whose semantic is VERTEX, in this case "ID2-mesh-vertices"
2 - I access "vertices" and get the source ID whose semantic is POSITION, in this case "#ID2-mesh-positions"
3 - I access the source "#ID2-mesh-positions" and take the float values
4 - After that I started to loop through the "p" values from three to three (accordingly to "technique_common") to get, respectively, the indexes of vertices X, Y and Z located within the float values of the source. For example, what the code does =>
0 0 1 = {X -> 0.4330127;Y -> 0.4330127; Z -> 0.25}
1 2 2 = {X -> 0.25;Y -> 0; Z -> 0}
1 1 0 = {X -> 0.25;Y -> 0.25; Z -> 0.4330127}
Obviously I'm doing something very wrong, because I cannot get a simple sphere.
*
<input semantic="VERTEX" source="#ID2-mesh-vertices" offset="0"/>
<input semantic="NORMAL" source="#ID2-mesh-normals" offset="1"/>
This tells you that for each vertex, you have 2 indices poking into the referenced sources. 0 0 is the first set, 1 1 is the second, 2 2 is the third. since your first polylist value is 3 (really, all of them are), that makes up your first triangle.
Now, those indices are going through the source accessor for the float array...
<accessor source="#ID2-mesh-normals-array" count="266" stride="3">
<param name="X" type="float"/>
<param name="Y" type="float"/>
<param name="Z" type="float"/>
</accessor>
This tells you that to read the normal associated with an index, you have to stride the array by 3 elements, and each vector is made up of 3 floats (X, Y, Z). Note that stride does not have to be the number of elements in each vertex, though it is often the case.
So, to conclude that example, to read the index 2 of the normal array, you need to go read the elements indexed with X_index=index*stride=6, Y_index=X_index+1=7, Z_index=X_index+2=8, to find the normal (X,Y,Z) = (-0.2561113 0 -0.8390759 -0.4953154)
And yes, this means that you have multiple indices per vertex, something that OpenGL does not support natively. See those various questions as reference material.
Rendering meshes with multiple indices
How to use different indices for tex coords array and vertex array using glDrawElements
3 index buffers
Use the collada de-indexer to pre-process the .dae and eliminate multiple indices per vertex. While you are at it, convert to triangles in the pre-process to simplify even further your loader.
https://collada.org/mediawiki/index.php/COLLADA_Refinery
Let's assume I'd like to wright an ocr algorithm. Therefore I want to create a binary image. Using clojure and quil I came up with:
(defn setup []
(load-pixels)
(let [pxls (pixels)
]
(letfn [(pxl-over-threshold? [idx] (if (> (red (aget pxls idx)) 128) true false))
]
(time (dotimes [idx 25500] (aset pxls idx (color (rem idx 255)))))
(time (dotimes [idx 25500] (if (pxl-over-threshold? idx)
(aset pxls idx (color 255))
(aset pxls idx (color 0)))))))
(update-pixels))
(defn draw [])
(defsketch example
:title "image demo"
:setup setup
:draw draw
:size [255 100]
:renderer :p2d)
;"Elapsed time: 1570.58932 msecs"
;"Elapsed time: 2781.334345 msecs"
The code generates a grayscale and afterwards iterates over all pixels to set them black or white. It performs the requested behavior, but takes about 4.3 sec to get there (1.3 dual core). I don't have a reference to put the 4.3 sec in context. But thinking of processing a larger image, this must become incredibly slow.
Am I doing something terribly wrong or is there a way to fasten up things? Is the combination of clojure and quil even capable of doing pixel transformations faster or should I choose a different language/environment?
Please also let me know if I'm doing something weird in the code. I'm still new to clojure.
Thanks in advance.
The timings you've taken aren't particularly meaningful because the code isn't warm yet. You need to "warm up" the code so that the JVM will JIT-compile it, and that's when you should start seeing good speed. You should look at How to benchmark functions in Clojure? (You should use Criterium.)
As for your code, you're using arrays, so that should give you good performance. Style-wise, the two hanging ] you have are really weird. Maybe that's just a formatting error? It's usually good to eliminate as much duplicate code as possible, so I'd also change this
(if (pxl-over-threshold? idx)
(aset pxls idx (color 255))
(aset pxls idx (color 0)))
to this
(aset pxls idx (color (if (pxl-over-threshold? idx) 255 0)))
If you feel looks too confusing/complex (I'm kind of right on the edge as to whether I'd consider that too hard to read or not), you could alternatively write it either of these ways instead:
(let [c (if (pxl-over-threshold? idx) 255 0)]
(aset pxls idx (color c)))
(->> (if (pxl-over-threshold? idx) 255 0) color (aset pxls idx))
I am a beginner in using Quil and Clojure and am attempting to draw some rectangles from some existing data structures. If I define the draw function to take a structure of some kind how do I pass the structure to draw using defsketch?
(defn draw [x]
(stroke 80)
(stroke-weight 3)
(fill 23 181 100)
(rect x x x x))
(defn create-sketch []
"Automatically uses the given setup and draw functions. Magic."
(defsketch example
:setup setup
:draw draw
:size [2000 2000]))
In the code above (taken from one of Quil's examples) I could define draw to take a random parameter x which it would then use. I can't figure out how to pass in a parameter when defining the sketch. The :draw draw declaration as it is now works for a function with an empty parameter-list. I have tried every way I can think of to pass it in some x value. I'm not knowledgeable enough on what the problem actually is to be able to fix it.
quil draw takes no arguments. The partial trick shown in the comments works if you always draw the same list of rectangles.
If you want to have an animation draw must access a mutable state (eg an atom).
I'm creating a plot of a robot's belief of its distance to a landmark. The x-axis is number of measurements, and the y-axis is distance to landmark, which should include error bars to indicate the confidence in this estimate.
I haven't been able to find an good way to add error bars to the plot based off a value for the variance. Currently I'm creating a box-plot at each measurement by generating sample data about the mean with my value for the variance. This is clearly not ideal, in that it is computationally inefficient and is an imprecise representation of the information I'm trying to display.
Any ideas for how to do this? Ideally it would be on an xy-plot, and it could be done without having to resort to JFreeChart commands.
I think I have something pretty close. First let's create some random data to graph:
(def y (for [i (range 20)] (rand-int 100)))
user> (11 14 41 33 25 71 52 34 83 90 80 35 81 63 94 69 97 92 4 91)
Now create a plot. You can use xy-plot but I like the look of scatter-plot better.
(def plot (scatter-plot (range 20) y))
(view plot)
That gives me the following plot
Now we have to define a function that takes a point (x,y) and returns a vector of the lower and upper bounds of the error bar. I'll use a simplistic one that just calculates 5% above and below the y value.
(defn calc-error-bars [x y]
(let [delta (* y 0.05)]
[(- y delta) (+ y delta)]))
Now we just map that function over the set of data using the add-lines function like this...
(map #(add-lines plot [%1 %1] (calc-error-bars %1 %2)) (range 20) y)
And that gives us this plot:
The main problem is that all the bars are different colors. I'm not sure if there is a way around this without using JFreeChart calls. Hopefully, someone will see this and tell me how to fix it. Anyway, that's pretty close.