JS - Efficient way to calculate shortest point between two boundaries - javascript

Basically what I am looking for is very similar to the following (although I am writing this in javascript):
Finding Minimum Distance between Contours
I have an image where I have already calculated outlines for multiple shapes and I want to connect the shapes if some point from object 1 and another point from object 2 share a minimum distance less than d.
The problem is that the accepted answer in that question seems to suggest looping through all points in object 2 for each point in object 1 which appears super inefficient to me. In my case scenario I will have multiple objects with large paths so that approach would not be feasible,
Is there some smarter method to approach this problem calculating the shortest point between two boundaries?

Related

GC friendly convex clipping (union and difference) algorithm

I'm looking for algorithm that will cut my convex polygon based on another convex polygon. It is gonna be for destructible terrain (diff) and for creating terrain (union) in 2D map in game.
Algorithm has to be Garbage Collector friendly and the only boolean operations that are neccessary are Union & Difference.
I've done some research and there are some github projects, but all of them produce some garbage more or less.
https://github.com/tmpvar/2d-polygon-boolean
https://github.com/w8r/GreinerHormann
I guess the best solution would be to learn one of these and re-make it my way. But maybe you've heard about some that suits my needs?
Thanks.
This problem involves two subproblems
find the intersection points between the two outlines
join the vertices that mus be joined.
For 1. you can exploit convexity: see both polygons as two monotone chains. When you travel the chains of the twopolygons simultaneously, say by increasing x, the intersections are detected when the ordinates cross each other between two abscissas.
For 2. notice that the union or difference are made of portions of the outlines alternating between one polygon and the other, at every interesection point.
Note that in the case of the difference, there can be several disconnected pieces.
I guess that you can implement this without any allocation/deallocation at all (but for the output polygon).

How to determine if two concave/convex shapes are at particular distance?

I have to determine whether two concave/convex shapes are at distance d from each other . I know Separating Axis theorem might come handy in determining the distance , but that runs in O(n2) time , and I am looking for O(n) or O(nlogn) algorithm for any shape . I want to implement that for any two SVGs in javascript
This is a broad and arduous problem.
To handle the most difficult cases (like ellipse/Bezier distance), you will need to somehow flatten the outlines so I recommend to flatten in all cases, and solve the problem for two polygons only.
Amazingly, you find little resources on the Web for the distance between two polygons.
Assuming that you are dealing with the inside of the shapes (and not just the outline), you will first have to check the polygons for void intersection (otherwise the distance is 0). I guess that this can be done in time O(N.Log(N)).
Then, if I am right, the closest distance between two polygons is the shortest of the closest distances of all vertices to the other polygon. If you construct the Voronoi diagram of both polygons (which is doable in time O(N.Log(N))), you get two planar subdivision, in which you can solve the point-location problem in time Log(N) per point.
All put together should lead to an O(N.Log(N)) solution. You will need a specialized Computational Geometry library to achieve this.

Rearrange Points that are too near to each other

My case is that I am dynamically positioning a bunch of icons on a static map image, each by CSS, positioned absolutely. Now it often happens, that two or even more points are too near to each other, so the icons overlap and they are not anymore distinguishable.
I am looking for an algorithm to find these "too near to each other" points, and then spread their icons out in a manner that they do not overlap each other anymore.
I am thinking of a radial spread, like finding the average middle point of all points that are too near and then spread them out relatively to that point.
Is there any pattern for such a problem of which you may know?
Thanks a lot in advance.
Here are a few solutions that might solve your problem:
Use a solution to the closest pair of points problem to find the two icons that are closest to one another. If the closest pair is "too close" by your definition, you can move them apart from one another and repeat this process.
Use a spatial data structure like a k-d tree or R-tree to store all the points. You can then execute fast nearest-neighbor searches to find points that are close to one another and move them apart.
Use a force-directed layout algorithm to find a layout for the points that globally minimizes some energy function. Algorithms like Fruchterman-Reingold are pretty straightforward to code up and produce good results.
Hope this helps!

Merge two svg path elements programmatically

I am rendering a map out of SVG paths (using jVectormap).
There are cases where one region has to be merged with the neighboring region.
Unfortunately both regions don't touch each other and I have to interpolate to fill the space in between.
jVectormap uses very simple SVG paths with M to set the the absolute startpoint and l to connect relative points.
Does any of the SVG libraries cover such an operation?
I haven't tried this, but you may get around it by running the converter at jVectormap with the following parameters:
--buffer_distance=0
--where="ISO='region_1' OR ISO='region_2'"
Where region_1 and region_2 are the two regions that you need to merge.
Solving the problem this way also means that the generated SVG paths are true to the original coordinates, whereas a following fix may lead to some (probably minor) inconsistencies.
This might not be the kind of answer you're looking for, but using Raphael.js you could loop over the entire length of the path of one region getPointAtLength(), comparing it with all points of the second region. If the coordinates are closer than n pixels from any coordinates on the second region and the previous coordinates weren't, than that could be regarded a "glue" point. You would then jump to the second regio and start looping over it, if the next point is still closer than n points, than go in the opposite direction, if still closer change direction and go farther along the path till finding a point that's farther away from the original region than n pixels. Continue looping in that direction till once again finding a new "glue" point, where once again you will switch to the original region in the manner described and all points which weren't covered in this final loop could be discarded (or you could simply create a new shape based on the points you came across whilst looping over the length of the original region.
True enough, it's not the easiest script to make, but it should be quite do-able I believe, especially when you can use a function like getPointAtLength to find the points between the defined svg points (though you need to only 'record' the defined points, and that's sort of the hard path as Raphael.js doesn't excitedly have any functions which would help with this, still even that shouldn't be too hard to match up by hand (in code of course)).

Draw outline of combined rectangles in canvas

Is there a good algorithmic way to combine multiple squares (each has four x/y points) to draw an outline of the joined figured in canvas?
The figures I would want to make sure work are as follows:
two squares joined to make a rectangle
four squares joined to make a larger square
two squares that are diagonal like a rectangle with triangles at each end at 45 degrees - this is probably the most irregular/special case...
three or four squares joined to make a concave shape like a Tetris(TM) piece 'L' piece
Is there an easy way to calculate the outer points to use to draw a line path (and maybe a filled figure) from all of the squares points?
Thanks!
Update: the reason we want to do this is because we want to show squares that are of the same group that are next to each other in a 2xn array specifically (but could also be 1xn in some cases). Maybe there is an easier answer if I just iterate through the different squares and form groupings some other way?
You're looking at it from the perspective of "I've got squares".
But you need to look at it from the perspective of "I've got points" (each square is just 4 points).
What you're actually looking for is called the "Convex Hull" - and the question has already been answered on SO here:
Polygon enclosing a set of points
I actually started diagramming your solution to go about solving it - and that's when this occurred to me.
I realized when I was making my diagrams that the outline of these shapes has several interesting properties - which is when I thought "yeah right - someone has already done this - this must be around already".
So I googled "construct smallest polygon enclosing other polygons"
And found the other S.O. question.
Although you do have two seemingly dis-similar requirements:
two squares that are diagonal like a rectangle with triangles at each
end at 45 degrees - this is probably the most irregular/special
case... three or four squares joined to make a convex shape like a
Tetris(TM) piece 'L' piece
In the first example above, you say you want the "Convex Hull".
But in the second example above (the tetris pieces), you'd need the "Concave Hull".
Good luck.
Here are my diagrams:
I'm curious as to why you'd want to do that.
In any case, my intuition is that you want to find is called "concave hull", but I'm no expert.
Check out this question and see if that's what you want.
Edit: also this question on gis.stackexchange.com

Categories

Resources