How can I get the intersection of three shapes colliding and delete the parts that are not colliding in KonvaJs? - konvajs

If I am given 3 circles and they are positioned as the primary colors circles (3 circles intersecting each other), is there a function that might help me to delete the parts that are not colliding with anything and just keep the intersecting parts?
Another example could be drawing three lines in such a way that it forms a triangle. By deleting the parts that are not colliding, we would end up with 3 points (at least visually, not sure if I end up with 3 in total or 6 from stacking up), which are the edges of the previous triangle.
I have been checking the ClipFunc and the HitFunc, but I am not sure if I am going through the correct/best path to solving my problem.

Related

Creating triangular UIRegions

I need to separate the screen into regions that look like this (separated by black lines):
The documentation says Most regions are rectangular or elliptical in shape, but you can use the methods of this class to create more complex shapes by adding, subtracting, and intersecting other regions. I can't figure out how to create these.
For context I am trying to replicate the StickyCorners: Using UIFieldBehavior and other UIDynamicBehaviors demo, but adding 4 more sticky points, 1 at each midpoint (indicated by red circles).

Opencv divide a contour in two sections

I have a contour in Opencv with a convexity defect (the one in red) and I want to cut that contour in two parts, horizontally traversing that point, is there anyway to do it, so I just get the contour marked in yellow?
Image describing the problem
That's an interesting question. There are some solutions based on how the concavity points are distributed in your image.
1) If such points does not occur at the bottom of the contour (like your simple example). Then here is a pseudo-code.
Find convex hull C of the image I.
Subtract I from C, that will give you the concavity areas (like the black triangle between two white triangles in your example).
The point with the minimum y value in that area gives you the horizontal line to cut.
2) If such points can occur anywhere, you need a more intelligent algorithm which has cut lines that are not constrained by only being horizontal (because the min-y point of that difference will be the min-y of the image). You can find the "inner-most" corner points, and connect them to each other. You can recursively cut the remainder in y-,x+,y+,x- directions. It really depends on the specs of your input.

OpenCV find polygons

I'm using EmguCV and trying to find polygons within an image. Here are some facts about the problem:
1) The polygons are irregularly shaped, but the sides are always at one of two angles.
2) Often the polygons have gaps in their sides that need to be filled.
3) If a polygon is contained within another polygon, I want to ignore it.
Consider this image:
And I want to find the polygons highlighted in red, omit the polygon highlighted in green and make connections across gaps as shown in blue here:
I've had some success using HoughLinesBinary and then connecting the closest line segment end points to each other to bridge gaps to build a complete polygon, but this doesn't work when multiple polygons are involved since it will try to draw lines between polygons if they happen to be close to each other.
Anybody have any ideas?
I think that the problem could be your image threshold.
I don't know how you did but you can get better results if the binary image is better.
I like of your idea to connect the polygons segment, try to secure that the line you will connect has a maximum and minimum length to avoid connect to nearest objects.
Verify if the new joint of lines forms 90 degrees angle, even if its a corner.
Added:
You can use moephological operators to grow the lines acord to angles. As you said that the lines has known angles do dilations using a mask like this
0 0 0
1 1 0
0 0 0
This mask will grow lines only to rigth until conect to other side.
A general solution will be hard, but for your particular problem a relatively simple heuristic should work.
The main idea is to use the white pixels on one side of a wall as an additional feature. The walls in your image always have one almost black side, and one side with many white noise pixels. The orientation of the white noise in relation to the wall does not switch on corners, so using this information you can eliminate a lot of possible connections between lines.
First some definitions:
All walls in the picture go either from the lower left to the upper right (a rising line) or from the upper left to the lower right (a falling line).
If there are more white pixels on the left side of a falling line, call it falling-left-wall, otherwise falling-right-wall. Same for rising lines.
Each line ends in two points. Call the leftmost one start, the rightmost one end.
Now for the algorithm:
classify each line and each start/endpoint in the image.
Check the immediate area on both sides of each line, and see which side contains more white pixels.
Afterwards, you have a list of points labeled falling-left-wall-start, rising-left-wall-end, etc.
for each start/end point:
look for nearby start/end points from another line
if it is a falling-left-wall-start, only look for:
a falling-left-wall-end
a rising-left-wall-start, if that point is on the left side of the current line
a rising-right-wall-end, if that point is on the right side of the current line
pick the closest point among the found points, connect it to the current point.

Calculating the neighborhood distance

What method would you use to compute a distance that represents the number of "jumps" one has to do to go from one area to another area in a given 2D map?
Let's take the following map for instance:
(source: free.fr)
The end result of the computation would be a triangle like this:
A B C D E F
A
B 1
C 2 1
D 2 1 1
E . . . .
F 3 2 2 1 .
Which means that going from A to D, it takes 2 jumps.
However, to go from anywhere to E, it's impossible because the "gap" is too big, and so the value is "infinite", represented here as a dot for simplification.
As you can see on the example, the polygons may share points, but most often they are simply close together and so a maximum gap should be allowed to consider two polygons to be adjacent.
This, obviously, is a simplified example, but in the real case I'm faced with about 60000 polygons and am only interested by jump values up to 4.
As input data, I have the polygon vertices as an array of coordinates, from which I already know how to calculate the centroid.
My initial approach would be to "paint" the polygons on a white background canvas, each with their own color and then walk the line between two candidate polygons centroid. Counting the colors I encounter could give me the number of jumps.
However, this is not really reliable as it does not take into account concave arrangements where one has to walk around the "notch" to go from one polygon to the other as can be seen when going from A to F.
I have tried looking for reference material on this subject but could not find any because I have a hard time figuring what the proper terms are for describing this kind of problem.
My target language is Delphi XE2, but any example would be most welcome.
You can create inflated polygon with small offset for every initial polygon, then check for intersection with neighbouring (inflated) polygons. Offseting is useful to compensate small gaps between polygons.
Both inflating and intersection problems might be solved with Clipper library.
Solution of the potential neighbours problem depends on real conditions - for example, simple method - divide plane to square cells, and check for neighbours that have vertices in the same cell and in the nearest cells.
Every pair of intersecting polygons gives an edge in (unweighted, undirected) graph. You want to find all the path with length <=4 - just execute depth-limited BFS from every vertice (polygon) - assuming that graph is sparse
You can try a single link clustering or some voronoi diagrams. You can also brute-force or try Density-based spatial clustering of applications with noise (DBSCAN) or K-means clustering.
I would try that:
1) Do a Delaunay triangulation of all the points of all polygons
2) Remove from Delaunay graph all triangles that have their 3 points in the same polygon
Two polygons are neightbor by point if at least one triangle have at least one points in both polygons (or obviously if polygons have a common point)
Two polygons are neightbor by side if each polygon have at least two adjacents points in the same quad = two adjacent triangles (or obviously two common and adjacent points)
Once the gaps are filled with new polygons (triangles eventually combined) use Djikistra Algorithm ponderated with distance from nearest points (or polygons centroid) to compute the pathes.

How to compute the overlapping ratio of two rotated rectangles?

Given two rectangles, and we know the position of four corners, widths, heights, angles.
How to compute the overlapping ratio of these two rectangles?
Can you please help me out?
A convenient way is by the Sutherland-Hodgman polygon clipping algorithm. It works by clipping one of the polygons with the four supporting lines (half-planes) of the other. In the end you get the intersection polygon (at worst an octagon) and find its area by the polygon area formula.
You'll make clipping easier by counter-rotating the polygons around the origin so that one of them becomes axis parallel. This won't change the area.
Note that this approach generalizes easily to two general convex polygons, taking O(N.M) operations. G.T. Toussaint, using the Rotating Caliper principle, reduced the workload to O(N+M), and B. Chazelle & D. P. Dobkin showed that a nonempty intersection can be detected in O(Log(N+M)) operations. This shows that there is probably a little room for improvement for the S-H clipping approach, even though N=M=4 is a tiny problem.
Use rotatedRectangleIntersection function to get contour and use contourArea function to get area and find the ratios
https://docs.opencv.org/3.0-beta/modules/imgproc/doc/structural_analysis_and_shape_descriptors.html#rotatedrectangleintersection
Lets say you have rectangle A and B the you can use the operation:
intersection_area = (A & B).area();
from this area you can calculate de respective ratio towards one of the rectangles. there will be harder more dynamic ways to do this as well.

Resources