We are about to switch to a new forum software. Until then we have removed the registration on this forum.
I am trying to interact with Toxiclibs vornonoi objects and I am missing something. Namely I am trying to interact with the centroids of each region in a Voronoi class, and also the sites of the Voronoi class.
For example:
println("Original Sites"); for (Vec2D site : voronoi.getSites()) { println(site); } println("Original Centroids"); for (Polygon2D poly : voronoi.getRegions()) { println(poly.getCentroid()); }
My output is:
Original Sites {x:78.0, y:78.0} {x:525.0, y:77.0} {x:525.0, y:528.0} {x:76.0, y:527.0} {x:303.0, y:305.0} < -- center Original Centroids {x:-3205.746, y:-3205.5093} {x:3815.8723, y:-3015.4072} {x:302.67184, y:304.48938} < -- center {x:-6293.649, y:2903.7415} {x:7501.3203, y:3228.6487}
Mind you my fundamentals are pretty poor and I'm not real solid on what is going on in my for loops, but the way I see it, I am continually creating new Polygon2D or Vec2D objects, that exist only until the bottom of the for loop. Then, I continue looping until I've iterated through the entire voronoi object. The issue is the "center" centroid and the "center" site don't happen at the same iteration. This is really messing up my ability to interact with the system. Notice the center site came out of the for loop last, while the center centroid came out of the for loop 3rd? In order of points placed on screen the sites output is correct.
Anyway, my goal is to use an ArrayList to create new voronoi objects after I've modified the sites, but I can't do this correctly if the order is different between sites and centroids. If anyone has an tips on how I could go about solving this I would appreciate the help.
Also, Toxiclibs states the the output of his voronoi method "getRegion()" is java.util.List, I don't even know what a list is in processing. ArrayList sure, but I don't think he means an ArrayList. His output for method "getSites()" is java.util.List. So, maybe my issue is a misunderstanding of a List.
Answers
List<Polygon2D> polies = new ArrayList();
for (Polygon2D poly : voronoi.getRegions()) polies.add(poly);
First, the library is called Toxiclibs. Fixed. :-)
Second, do you really need it to be in the same order?
Third, if you really need the same order, then sort it. Per site, go over the list of polygons until you find the one that the site is in (point in polygon), then add it to a (new) list. Once you have gone over all sites, you should have a list of polygons in the same order as the sites. Then you get the centroids.
Thank you GoTo, that makes a lot of sense. I'll start working with that to become more familiar.
amnon, here we go again! :D
I'll try implementing your "third." Any idea why the library wouldn't just output sites and regions in the same order? Seems like that would be fairly intuitive. I guess I just assumed I was doing something wrong when calling them.
I assume this is because of the algorithm that generates the regions. Not sure if this is the same algorithm that is used, but this visualization gives an insight in the way voronoi regions are generated. Press "Animate sweep line".
GoToLoop, I was trying our your List expression but I get the error message of 'Cannot find a class or type named "List."' Also, the List identifier isn't being assigned a color like other data types do (orange). Seems like processing isn't recognizing List as a data type.
All Collection classes/interfaces, like List, ArrayList, HashMap, etc., belong to Java's API, not Processing: @-)
https://docs.oracle.com/javase/8/docs/api/java/util/Collection.html
In order to use List interface, we 1st need to import it:
import java.util.List;
:https://docs.oracle.com/javase/8/docs/api/java/util/List.html
B/c it's not an "official" Processing's API. Although I don't see why they couldn't standardize it since it doesn't interfere w/ "JS Mode" after all. *-:)
Update, I used this:
And got this output:
So now the order matches up. Thanks for the tip amnon.
Great, thank you GoTo. Between the two of you this has helped quite a bit. I suppose I do have one last question regarding lists. When would I want to use an ArrayList vs a List? Since list wasn't working I basically did what you said just using ArrayList and it seemed to work. I'm not sure I understand the distinction. My guess is if I had matched the output type of the getRegions() function (List), I could have done something like..
polies = voronoi.getRegions();
Skipping the for() statement.
Update: This site shows what I am trying to do with these regions quite well (Lloyd Relaxation). http://www.jasondavies.com/lloyd/
However, by ignoring regions who's centroids are outside the sketch I was able to reproduce something fairly similar. Code below. I made a case that by pressing L (lower case), you produce one iteration of lloyd relaxation.
If anyone knows how to handle the edge cases, please let me know.
Since ArrayList inherits from List, we may choose the latter for the a variable and the former for the object:
It's more a matter of taste! Although using the most generic is more pro 1337! ;;)
Since I dunno that library, I chose to present you the safer
for ()
+ add() option! X_XBut of course, if getRegions() indeed returns a List<Polygon2D>, a simpler
List<Polygon2D> polies = voronoi.getRegions();
is the most correct way! =:)To handle the edges case, you can use constrain instead of completely discarding those centroids. Also there are some optimizations possible. See the code below (I stripped away some stuff so I could focus on the relevant code better).
Adapted Code
Nice amnon, those changes make a lot of sense. I wasn't aware of that constrain function, that makes those edge cases behave well.
PS. I spent the last hour or so looking through forums on how to download and install java libraries, but I guess you don't have to?! I ended up just adding that import line and I was able to implement List.
You already have all java libraries, because you have java. You can import any java.* you need. See the full list here: http://docs.oracle.com/javase/7/docs/api/
@amnon
I really like your relaxation and I made a class to interpolate. I tried to make it as optimized as I could. I think there is a lot of room for optimization in the Voronoi class itself by reusing created object but that could be quite some work.
http://hg.postspectacular.com/toxiclibs/src/44d9932dbc9f9c69a170643e2d459f449562b750/src.core/toxi/geom/mesh2d/Voronoi.java?at=default