the goal is to find all the rectangles you get when you come from all sides (north, west, east, south) in an orthogonal polygon. However, I can't get any further on concrete implementation.
So here is what I've done so far.
First: I have a list of coordinates (in a XML file), I want to read them into Java to determine the points and the edges of the polygon.
So now coming to my main problem. I want to find all rectangles that lie within this polygon,
[![the polygon]starting from all sides (north, east, south, west). I have a problem with this step. It occurred to me to use a SweepLine algorithm, but I am unsure how to implement it to get the desired result (overlapping rectangles coming from all sides). For that I have painted those pictures to clarify what I mean. If you come from the north edges of the polygon you would find the green rectangles. [![rectangles in the polygon coming from the north edges]
If you come from the west edges of the polygon you would find the red rectangles.
[rectangles in the polygon coming from the west edges]
and with that the overlapping rectangles..
[overlap of green and red rectangles]
However, I'm not sure how to do this the most easiest way. I researched a lot sweep line Algorithms, but I'm not sure how to implement it and whether this is an efficient way. My goal is to find those rectangles and save them in a proper way so that I can use them for further steps (e.g. finding positions in the polygon where many rectangles overlap)
Maybe someone could help me with that. Would appreciate this a lot!
If you already know all the edges and have determined whether they face North, South, East or West, determining the rectangles could be done like this:
Iterate through the edges.
Let's say we have a north-facing edge between (n.x1, n.y) and (n.x2, n.y). The corresponding rectangle must have its north-facing edge be the one we just looked at and its south-facing edge must, at least in part, consist of one or more south-facing edges.
We iterate through all south-facing edges and find the ones such that at least one point on the edge has an X coordinate within the range (n.x1, n.x2).
Additionally, they need to actually be south of the north-facing edge, so keep the ones where s.y > n.y.
Now, what we have left is a list of all south-facing edges that could possibly limit our rectangle's height. However, the rectangle is limited by whichever is the closest, so we simply pick the remaining south-facing edge, s, with the lowest y coordinate.
We now have a rectangle between (n.x1, n.y) and (n.x2, s.y).
Corresponding logic is implemented for each cardinal direction.
Related
I have a Łquestion about the graphstream library
I want to write a program that counts the number of intersections between the nodes that are represented as a square with a specified size.
The main Problem is that, the nodes will be visualized as squares but if the coordinates of these nodes are just points x,y and here is exactly my Problem, because I want to check the intersections with the edges with the x,y coordinates but I can not do this properly!
because in some cases the corner of the square or its edges intersect with the edges but the original point that represents the square or the node in graphstream does not, I tried all the possible solutions with collinear points , slopes and everything but nothing worked for me, the question is, is there anyway in Grpahstream so that I can find out the coordinates of the edges or the corners of the square so that I can check with the line segment equation if they intersect ?
I mean something like that as shown in the picture
https://i.stack.imgur.com/PG4Dv.png
Best regards
Following is the problem statement.
You have been given k number of equilateral triangles (There is a upper cap on
k, lets say k=<15). The triangles can be overlapping.
Now you have to find a parallelogram enclosing all the triangles and has the
minimum area. It is given that two opposite edges of the four edges are
parallel to either X axis or Y axis(That is your choice).
My Approach:
Let's say two of them are parallel to Y axis.
Then the leftmost point and the rightmost point of the set of triangles
will lie in two opposite edges of the parallelogram. Now I will draw two straight lines which pass through these points and are parallel to the Y axis.
This way I have found two edges its not so difficult.
Now I am stuck and don't know how to find other two.
I thought a lot but since I was unable to make it out I am posting it here.
Any help will be appreciated!!!!!!!
Build convex hull around all triangles vertices.
Then use rotating calipers to get a pair of parallel lines with the smallest vertical distance between them (parallelogram area is defined by height (here horizontal) - it is already fixed, and by vertical base length - choose minimum)
Firstly, apologies for the long title; I could not think of a way to sufficiently cover my problem yet also compact it further.
I am in the process of creating a 2D game in Java with a character in the centre of the screen. My character has a collision box and I have images on the map (looking from above) which also have collision boxes.
However, I'd like to be able to have a "slide" situation if a collision occurs into a side that is not perpendicular to my direction.
For example, if my character is moving east, and there is a wall to his east going in the southwest to northeast direction, instead of just noting that there is an object to the east and not moving, I'd like my character to be able to "slide" along the wall, moving northeast to achieve the attempted Eastern movement.
Is there any easy way to do this?
If it helps in any way, I am using Java Slick2D, and have the collision box of the character as a rectangle where he stands, and the collision boxes of other objects as polygons.
Thanks in advance for any replies!
When you have solved the problem of identifying when a collision has occurred, the sliding motion can be achieved by calculating the component of the motion that is perpendicular to the wall and subtract that from your motion vector.
Say you have a motion vector v = (v_x, v_y) and the normal of the wall n = (n_x,n_y). The normal vector should be of length 1.
Then your new motion vector should be
v_new = v - (v * n) * n.
That in X and Y separately is
v_new_x = v_x - (v_x * n_x + v_y * n_y) * n_y,
and the same way for Y
Class java.awt.geom.Area has a method intersects( Area a ) which should be useful for determining the "point" of impact, call it P. If the character's collision box is a rectangle and the obstacle is bounded by an arbitrary polygon you'll have to determine
the point or side of the rectangle participating in the collision
the point or side of the polygon participating in the collision
If side meets side (they should be parallel), the charcter can't move any more in the current direction; no slide should occur. Equally, if a rectangle side meets a polygon point, movement is blocked.
If a point meets a point, you might resolve this by (arbitrarily?) select one of the sides of the polygon and handle the situation based on that.
Finally, if a rectangle corner meets a slanting side, you'll have to analyze the geometry of this side. (Verify that a 10-to-4 side is met by the upper right (lower left) hand corner if going north or east (south or west), or a 7-to-1 side is met by the upper left (lower right) hand corner when going north or west (south or east)). Then you can determine the forced path along the slanted side.
While this sounds relatively simple, there may be much more complex situations lurking literally round the corner if the collision boxes of objects - polygons - may have concave sections.
For a school assignment we have to make a graph editor like the next one (given example):
Most of the assignment goes well, we're stuck on one point: drawing the edges between vertices. In the given example, the lines are nicely drawn from points relatively close to the connecting vertex. For example the top one has two lines on its bottom edge, one more to the left and one more to the right.
We are not sure on how to let the drawing of the lines keep the positions of the connecting vertex in account and how to adjust the positions of the beginning and end points on that (what calculations to make). Can someone help out?
In fact, that's rather simple: Draw the lines first, from the position of each vertex to the position of the respective other vertex (the "position" here refers to the center of the rectangle). Afterwards, draw the rectangles for the vertices. They will be painted over the edges, and the result will look exactly like the screenshot.
If you extend the connector lines, you can see they are drawn from the geometric center of the graph node rectangles:
Since you already seem to have a good positioning algorithm for your nodes, all you need to do is draw the connector lines first. Then draw the node rectangles on top of them.
I'm looking for a way to calculate the area of an intersection between a single rectangle and the union of a small set of rectangles.
I'm using Java and all of the rectangles are represented in integers (x,y,w,h). All rectangles are axis aligned with x/y axis.
Any suggestions?
You're going to potentially have a unique intersection between Rect1 and every rectangle in the RectSet union. So you are going to have do the intersection between Rect1 and each rectangle in the union separately. The intersecting area is the union of all intersecting sections between Rect1 and the rectangles in the union.
An optimization is to create a abounding rectangle for the union of rectangles (hopefully done as the union is created). If Rect1 doesn't intersect with this bounding rectangle, you can the skip doing any further intersections and the area in null.
An intersection of two rectangles is a rectangle itself (possibly degenerate, but those have zero area and can be ignored). Further, an intersection of unions is the same as a union of intersections (distributivity law). Therefore, you may intersect R1 with each of Rj and find the union of resulting rectangles.
To find the union, the easiest method is perhaps breaking the scene into vertical stripes, by drawing a vertical line through each vertex. Then within each stripe it's a well-known one-dimensional problem, solved by counting points in and out and removing those with count greater than one.
Go through and express your rectangles not as (x,y,w,h) but as (x1,y1,x2,y2), which is simply (x,y,x+w,y+h).
Then, loop over all Rj`s and "clip" the rectangles to the coordinates of Rect1:
Rj.x1 = max(Rj.x1, Rect1.x1)
Rj.y1 = max(Rj.y1, Rect1.y1)
Rj.x2 = min(Rj.x2, Rect1.x2)
Rj.y2 = min(Rj.y2, Rect1.y2)
Now, go through and remove any Rj's where Rj.x1>=Rj.x2 or Rj.y1>=Rj.y2 as in that case, the rectangles didn't intersect.
After, sum up all the areas of the remaining rectangles (simply (Rj.x2-Rj.x1) * (Rj.y2-Rj.y1)).
At this point, you will have double-counted any area where any of the clipped Rj`s overlap.
So, you then need to go through and loop over all Ri's and all Rj's where j>i and, clip the two with each other, but this time, if there is an intersection (same test as above), you need to subtract the area of the intersection from the value you have so far to remove the double-counting.
Unfortunately, this will double-remove any areas of a triple-overlap. So, you will then need to find those areas and add them back in. And so on and so forth for quadruple-overlaps, quintuple-overlaps, etc.
Sounds like it'll get pretty messy...
Maybe the easiest is to just draw the Rj's to a canvas in red and then count the red pixels inside Rect1 at the end. (Of course, you don't have to use a real Canvas. You can write your own using a bit-array.) There might even be scenarios (like a small coordinate space with lot's of tiny rectangles), where this is faster than the analytical solution. But, of course this will only work if you have integer coordinates.
Both n.m's answer and PQuinn's answer suggest to distribute the intersection across the union, then find the area of the union. That's a good idea.
In java, I suggest creating a new set of non-degenerate intersections between R1 and your Rj's, based on the assumption that most intersections will be degenerate. Then use the algorithm at http://codercareer.blogspot.com/2011/12/no-27-area-of-rectangles.html to find the area of the set of intersections.