I have an algorithm where I trace convex polygons from a light source, all contained between 4 walls.This is the algorithm:
Preparation - add all vertices to an array, sorted by their angle from the light source and then add all lines made by all vertices in another array.
Loop all vertices and rotate the ray to their angles
Set each vertex to be the nearest point.
For each vertex loop all lines and intersect the ray with them, if a line/ray intersection point is closer than the previous nearest point then set this as the nearest point.
This works perfectly except for this case:
The green lines aren't being considered by the algorithm.How can I make it continue beyond the ends of the polygon?
I don't see any reason why the green lines should be considered! The ray falls on the vertex, which is still part of the solid polygon. It is therefore logical that the ray will not continue further (along the green line). Your algorithm is correct and consistent!
Related
I'm having troubles figuring out an algorithm to solve the following problem:
I want the user to be able to snap the rectangle (Could be any type of polygon) to the 4 corners of the polygon such that it's as far inside the polygon as it can be.
What I'm trying so far:
Allow user to get the object.
Find the nearest vertice on the polygon to the rectangle.
Find the furthest vertice on the rectangle to the polygon's nearest vertice.
Use a plane to find the first intersection point with the furthest rectangle's point to the polygon's point.
Shift up or down using the corresponding x/y plane based on whether the furthest point is further in the x/y coordinate.
Keep repeating the steps above until everything is inside.
As long as the enclosing polygon is convex, you can write this as a linear programming problem and then apply https://en.wikipedia.org/wiki/Simplex_algorithm to find the answer. The smaller polygon you are putting inside can be as complicated as you want.
Your inequalities are all of the conditions to make sure that each vertex of the smaller polygon is inside of the larger. You don't have to be clever here, there is no cost to extra inequalities that don't come into play.
The function to optimize is constructed as follows. Look at the interior angle of the vertex you are trying to get close to. Draw a coordinate system at that point with one axis pointing directly into the polygon (call that axis y) and the other at right angles to the first (call that axis x). You want to minimize the y value of the nearest vertex on the polygon you are putting in. (Just put the polygon you are putting in in the middle, and search for the nearest vertex. Use that.
The solution that you find will be the one that puts the two vertices as close together as possible subject to the condition that the smaller polygon has to be inside of the larger.
I'm working on an assignment 2d art gallery problem to find a minimum number of vertex guards. As part of solving the problem using genetic algorithms, I would need to find out the area of the polygon that is visible for a guard placed on a vertex.
The input is a polygon with known 2d (x,y) coordinates. Could you please help me know how to calculate the visibility of the guard(i.e what part of the polygon he could possibly see) placed on a vertex of the polygon?
This is a solution for finding visible area from an arbitrary point inside the polygon. You can change it to restrict point to polygon vertices:
Step 1: Draw rays from guard toward each vertex and find intersection points with all edges of polygon.
Step 2: Check if ray crosses polygon (yellow) or just touches it (purple).
Step 3: Sort intersections on a ray by their distances from the guard and find closet cross point. Call all further points invisible (red) and closer ones visible (green).
Step 4: Now each edge of polygon is equivalent to one or multiple segments, each segment that its both end points are labeled as visible will be visible. Sum length of such segments.
Here is a more complicated sample:
And keep in mind that it is just a start and you can optimize it. Think about Niko's comment for first improvement.
What algorithm to use so that we can determine that if the red dot belongs to Area1 or Area2.
my original idea was to divide the polygons into triangles using consecutive points and then use a known algorithm to determine if a point belongs to one of these triangles however there is a problem shown in the figure.p4 p5 p6 are point in Area 1 but they make a triangle in area 2.
Continue inifite ray from red point to any direction. Count intesections of such ray with any polygon. Even count of intersections indicates that point lies outside of polygon
You can use the idea of the polygon filling algorithm for that. If you know the vertices of a polygon, you can lay a horizontal ray through the red point and count the vertices it intersects. If the count is even, it is outside, otherwise it is inside.
If you imagine coming from the far left along that ray, the first intersection is entering the polygon, the second is leaving it, the third is entering again... and so on. So if the number is odd (1,3,5,...) you are inside the polygon when you hit the point, otherwise you are outside.
Here is the idea -
Draw a horizontal line to the right of red point and extend it to infinity
Count the number of times the line intersects with polygon edges.
A point is inside the polygon if either count of intersections is odd or
point lies on an edge
See Check if a point lies inside or outside a polygon.
the polygons image
All of the polygons are simply, there are no holes in them.
board polygon(P0 to P7)
Red polygon (R0 to R6)
Green polygon (G0 G1 P2 G3)
Yellow polygon(Y0 to Y3)
I want to got new four polygons marked as 1 to 4 , polygon 1's coordinates are(J7 J10 R5 R4).
When I use polygon clipping algorithm, I can got the results easy , board diff(red union green union yellow). But when I have more than 10,000 polygons, I need a long time to get my results. My polygons are simply and my result polygons are simply also, there are no holes in the result polygons also.
You know I can find out the four polygons form the image easy using eyes, but how to find them using algorithm.
Thanks.
If all vertices of your computed black polygons do not have more than 2 edges intersecting at the vertex, then there may be a faster way than a more general tool.
Since the number of polygons is on the order of 10000, first try computing the intersection points of all pairs of polygons, and hopefully the number of intersection points is small enough (like 10 million or less). Then, for each intersection point test to see if it is contained in the interior of another polygon (in case you have multiple polygons that jointly overlap). Testing to see if a point is contained in the interior of a polygon can be done quickly, you can read how online. Then, all intersection points that are not contained in another polygon, which note also contains all the original polygon vertices that are not contained in the interior of a polygon, these are the vertices for the "black" polygons you want to compute. These points should be stored with a secondary structure that for each polygon edge, it stores all the stored intersection points along that edge, in sorted order. Similarly, for each stored vertex and intersection point you should store the edges that intersect at that point, and the location of the intersection point in the previous structure. So then pick any stored intersection point that hasn't been used yet in a black polygon, and pick one edge that defines the intersection point. Then you move to the neighboring intersection point along the edge which has the property that the part of the edge between the two intersection points does not pass inside a polygon. Then continue by similarly moving along the other edge that defines the neighboring intersection point. Continue until you reach the vertex you started at; this defines one black polygon. Then you can pick a new unused stored intersection point and repeat. Since your polygons have no holes, this will find all black polygons.
I have two 2D rectangles, defined as an origin (x,y) a size (height, width) and an angle of rotation (0-360°). I can guarantee that both rectangles are the same size.
I need to calculate the approximate area of intersection of these two rectangles.
The calculation does not need to be exact, although it can be. I will be comparing the result with other areas of intersection to determine the largest area of intersection in a set of rectangles, so it only needs to be accurate relative to other computations of the same algorithm.
I thought about using the area of the bounding box of the intersected region, but I'm having trouble getting the vertices of the intersected region because of all of the different possible cases:
I'm writing this program in Objective-C in the Cocoa framework, for what it's worth, so if anyone knows any shortcuts using NSBezierPath or something you're welcome to suggest that too.
To supplement the other answers, your problem is an instance of line clipping, a topic heavily studied in computer graphics, and for which there are many algorithms available.
If you rotate your coordinate system so that one rectangle has a horizontal edge, then the problem is exactly line clipping from there on.
You could start at the Wikipedia article on the topic, and investigate from there.
A simple algorithm that will give an approximate answer is sampling.
Divide one of your rectangles up into grids of small squares. For each intersection point, check if that point is inside the other rectangle. The number of points that lie inside the other rectangle will be a fairly good approximation to the area of the overlapping region. Increasing the density of points will increase the accuracy of the calculation, at the cost of performance.
In any case, computing the exact intersection polygon of two convex polygons is an easy task, since any convex polygon can be seen as an intersection of half-planes. "Sequential cutting" does the job.
Choose one rectangle (any) as the cutting rectangle. Iterate through the sides of the cutting rectangle, one by one. Cut the second rectangle by the line that contains the current side of the cutting rectangle and discard everything that lies in the "outer" half-plane.
Once you finish iterating through all cutting sides, what remains of the other rectangle is the result.
You can actually compute the exact area.
Make one polygon out of the two rectangles. See this question (especially this answer), or use the gpc library.
Find the area of this polygon. See here.
The shared area is
area of rectangle 1 + area of rectangle 2 - area of aggregated polygon
Take each line segment of each rectangle and see if they intersect. There will be several possibilities:
If none intersect - shared area is zero - unless all points of one are inside the other. In that case the shared area is the area of the smaller one.
a If two consecutive edges of one rectactangle intersect with a single edge of another rectangle, this forms a triangle. Compute its area.
b. If the edges are not consequtive, this forms a quadrilateral. Compute a line from two opposite corners of the quadrilateral, this makes two triangles. Compute the area of each and sum.
If two edges of one intersect with two edges of another, then you will have a quadrilateral. Compute as in 2b.
If each edge of one intersects with each edge of the other, you will have an octagon. Break it up into triangles ( e.g. draw a ray from one vertex to each other vertex to make 4 triangles )
#edit: I have a more general solution.
Check the special case in 1.
Then start with any intersecting vertex, and follow the edges from there to any other intersection point until you are back to the first intersecting vertex. This forms a convex polygon. draw a ray from the first vertex to each opposite vetex ( e.g. skip the vertex to the left and right. ) This will divide it into a bunch of triangles. compute the area for each and sum.
A brute-force-ish way:
take all points from the set of [corners of
rectangles] + [points of intersection of edges]
remove the points that are not inside or on the edge of both rectangles.
Now You have corners of intersection. Note that the intersection is convex.
sort the remaining points by angle between arbitrary point from the set, arbitrary other point, and the given point.
Now You have the points of intersection in order.
calculate area the usual way (by cross product)
.