Here is a graphic representation of the problem:
http://i.imgur.com/aBG3p.jpg
Given a starting point (x1,y1) and a destination point (x2,y2), I must determine if the path between the two points is open or, if it is not open, which coordinate the collision happens on.
It would be a trivial problem except for the special rules involved:
The line can intercept a point, call it (i,j) to a small and varying degree without causing a collision. If (i,j) is directly adjacent to (x1,y1), we can safely cut about 0.4 over its corners without triggering a collision. However we cannot cut 0.4 over if going directly through it, only over the corners. This number tapers off to about 0.2 as we get further away from (x,y). Unfortunately I'm just trying to reconstruct something I saw once, so I don't know the exact values, I'm just approximating them.
The caveat to 1: If the space directly beside (i,j), in the plane that we are intersecting, on the side that we are intersecting, is also occupied, there will be a collision no matter what. The collision will happen (i,j) if we intercept it by too much, otherwise in the relevant adjacent tile.
I've made several tries to crack this problem, always ending up with false negatives and/or the collision resulting on the wrong tile. I tried to do it without considering the angle, just by looking at the decimal points of x and y as we travel down the line. I'm not sure if it is possible to do this, or if I must use the angle in some way, or if using the angle in some way could make my life easier.
Please help if you can!
It seems like you could get results similar to what you describe by treating the occupied grids as containing unit circles. That would let you pass corners, but block on any 2 adjacent ones, since they contact.
So I'd try using your current collision method to check rectangles quickly, then refining it once you found a collision, by testing the line entering the box against a circle centered in it.
Related
I have a grid. If something goes off one edge, it reappears on the other side, in the same way as on a gluing diagram of a torus. There are two arbitrary points on the grid I want to find a straight line between using an algorithm. The line must completely avoid going through any obstacle squares. It must also be inside a specified range of angles from the x-axis. It should return the slope of the linear path that it finds. The starting position is already known, so only the slope is necessary. If no such path exists, the algorithm must return some exceptional data value indicating a lack of possible path. It should also be something better than searching all the angles the program is capable of processing. How do I make this algorithm? I have tried just searching all the angles the program is capable of processing and extending the line until it hits something or reaches some maximum length, but this is rather inefficient and I don't really want there to be a maximum length. It is not necessary for the path that is found to be the shortest path. It just needs to be a path that is linear, has a certain range of angle from the x-axis and does not hit any obstacle squares.
This image may help
Green is the starting point, red is the target, the brown square is the obstacle, and the grey areas are the areas blocked by the obstacle.
Note that there is only one target and one obstacle. The target and obstacle are repeated to show what happens when you go off the right edge of the grid, and wrap back to the left edge.
You can see that each time the line wraps around the grid, the angle to the target, and the angles to the obstacle are reduced. Eventually, the obstacle starts shadowing itself. Beyond that point, there's no hope of ever reaching the target. So in this example, there are exactly two angles that reach the target.
Add another obstacle (purple), and all angles are blocked even sooner.
If the obstacle is at the same level as the target, it takes longer before all possible angles are blocked. But eventually the obstacle will shadow itself, and all target angles beyond that point are blocked.
And just for completeness, obstacles above the target can be ignored. The angle to the target will always be smaller than the angle to the obstacle.
Given a list of points that represent the polygon in 2D, how can I determine if the point is inside the polygon.
Please note that the polygon can be either concave or convex. You can also make any assumptions about the order of the points.
The best approach to doing this is to draw a line in any direction from your point, and count the number of times that you cross the boundary of the object. If you hit the boundary an even number of times, you are outside the object, if an odd, you are inside. It is usually easiest to go along one of the axis to make this determination.
Essentially, you just have to find a way to determine if you cross a point. Use the slope of a line equation(m=(y1-y2)/(x1-x2), y=m*x(x-x1)+y1, and see if you cross within the boundaries that the point is valid. Given this equation for the line between the points, determine where your line crosses this line, and figure out if it is within the range of the line.
Incidentally, the same method works for any arbitrary dimension, just determining if you hit the face becomes more difficult.
To show a couple of examples, I've drawn a simple illustration, showing both what happens inside and outside, even with a weird shape.
Incidentally, if you hit a corner, it counts for the number of times you make a transition from inside to outside.
Select a point outside of the polygon. Draw a line between your´s and the point outside. If the line intersects the polygon an odd number of times, its inside, otherwise its outside. Zero intersections are also outside. However, this only workes for non overlapping polygons
It's a known problem with many solutions, just google it.
And read this :
http://en.wikipedia.org/wiki/Point_in_polygon
Take an arbitrary line from your point, to any point definitely outside your polygon (i.e. outside of the bounds). Check how many times that line intersects with one of the edges of your polygon. If the value is odd, the point is inside.
When checking, be careful of lines that go through a vertex, where your test may indicate two edge crossings.
I'd like to place an arbitrary number of rectangles into a fixed size parent such that they are:
Randomly placed
Randomly rotated to within a give degree range
Nicely dispersed around the center point (not all clumped into one corner)
Not overlapping unless necessary due to lack of space
With minimum overlap when it's necessary
To help you visualize the problem, I would like to scatter images inside a window for the user to choose one.
Googling had led me do various algorithms for packing etc, but nothing really addresses my requirements.
Does anyone have any good ideas?
It shouldn't be much more complicated than:
Place new rectangle in random location with random rotation. Simply using three random values (x, y, r) should do it, unless you want random size as well (in which case you'd need w and h too). This shouldn't give any corner-clumping (through random is random).
For every rectangle already placed, check for collisions. Here's one way. Also check for collisions with the side of the window (if you don't want things to extend past the screen); putting four dummy rectangles around the border may be a cheap way to do this.
If there are any collisions, then there are two choices: either move the new rectangle to a new random location or move both the new rectangle and the blocking rectangle away from each other until they no longer touch. Both have yays and nays - moving the new one only is faster and easier though it might not ever find a place where it fits if the page is really full; moving both is almost sure to be successful but takes longer and may result in chain-reaction collisions that would all have to be sorted out recursively.
In any case you'll want to try and keep the number of rectangles small, because the number of comparisions can quickly get really big. Using a short-circuit (such as "if they're halfway across the screen then don't bother looking closely") may help but isn't guarenteed.
EDIT: Okay, so requirement #5. Chances are that the push-both-rectangles-until-they-no-longer-collide-recursively method of adding new rectangles will end up being the simplest way to do this - just cut off the loop after a few thousand iterations and everything will have attempted to move as far away from everything else as possible, leaving minimum overlap. Or, leave the method running in a seperate thread so that the user can see them spreading out as more are added (also stopping it from looking like it's locking up while it's thinking), stopping once no rectangle has moved more than X units in one iteration.
How about this? Consider the rectangles you have to place as shaped, charged particles which repel one another and are also repelled by the walls of the container. You could start by (randomly) distributing them (and giving them random angles) in the container, then running a simulation where each "particle" moves in response to the forces acting on it (angles will change according to the turning moments of these forces). Stop when you hit a configuration within your tolerances.
You could simplify the calculations by treating each rectangle as an ellipse, which can be further simplified by treating each ellipse as a circle which has undergone scaling and rotation.
I don't understand requirement 2. Are you saying that the rectangles themselves are rotated around the rectangle center point, or that the rectangles only cover part of the 360 degree circle around the center point of all the rectangles.
I'm not sure that random is the way to go.
Simply divide the number of rectangles desired by 360 degrees. That's the number of degrees to offset each rectangle as it's being drawn. This should cover requirements 3, 4, and 5.
does anybody know of a good algorithm for this task:
a multi polygon contains the reserved areas
find an empty position for the given polygon which is closest to its original position but does not intersect the reserved areas
I have implemented some very basic algorithm which does the job but far from optimally.
Thank You!
Edit:
my solution basically does the following:
move given polygon in all possible directions dx and dy
check wether the new intersection is less than the previous intersection
if so, use new position and make sure that you don't move your polygon back and forth at the same position
repeat these steps a maximum of N times
Example: it is intended for placing text which should not overlap with each other.
One method that immediately pops into my mind is to shoot a ray (i.e. measure a line segment) from the original position to every vertex of the polygon. Do a comparison on those distances, and then based on those comparisons, narrow it down to the minimally far away line segment of the polygon. Compute the perpendicular intersection of that line with the origin, and you'll get the minimally far away point. If the vertex comparisons don't lead you down the right path, just shoot off lines in random directions, and just stop when you're happy with the result. It doesn't sound like you require optimality.
Let's look at the original problem: making sure that one piece of text doesn't overlap another. Presumably this is for labelling a map. The way I do it is this: draw the text invisibly, checking for overlap (by using a specialised graphics context that instead of drawing a pixel, checks whether a pixel is already there) then try another position along the line on which the text is to be placed - usually a street. I try the middle of the line first, then successive positions further and further left and right of the middle. If that fails I try again with a condensed (narrower) font.
Just wondering if there was a nice (already implemented/documented) algorithm to do the following
boo! http://img697.imageshack.us/img697/7444/sdfhbsf.jpg
Given any shape (without crossing edges) and two points inside that shape, compute all the paths between the two points such that all reflections are perfect reflections. The path lengths should be limited to a certain length otherwise there are infinite solutions. I'm not interested in just shooting out rays to try to guess how close I can get, I'm interested in algorithms that can do it perfectly. Search based, not guess/improvement based.
I think you can do better than computing fans. Call your points A and B. You want to find paths of reflections from A to B.
Start off by reflecting A in an edge, and call the reflection A1. Can you draw a line from A1 to B that only hits that edge? If yes, that means you have a path from A to B that reflects on the edge. Do this for all the edges and you'll get all the single reflection paths that exist. It should be easy to construct these paths using the properties of reflections. Along the way, you need to check that the paths are legal, i.e. they do not cross other edges.
You can continue to find paths consisting of two reflections by reflecting all the first generation reflections of A in all the edges, and checking to see whether a line can be drawn from those points through the reflecting edge to B. Keep on doing this search until the distance of the reflected points from B exceeds a threshold.
I hope this makes sense. It should be easier than chasing fans and dealing with their breakups, even though you're still going to have to do some work.
By the way, this is a corner of a well studied field of billiards on tables of various geometries. Of course, a billiard ball bounces off the side of a table the same way light bounces off a mirror, so this is just another way of thinking of reflections. You can delve into this with search terms like polygonal billiards unfolding illumination, although the mathematicians tend to dwell on finding cases where there are no pool shots between two points on a polygonal table, as opposed to directly solving the problem you've posed.
Think not in terms of rays but fans. A fan would be all the rays emanating from one point and hitting a wall. You can then check if the fan contains the second point and if it does you can determine which ray hits it. Once a fan hits a wall, you can compute the reflected fan by transposing it's origin onto the outside of the wall - by doing this all fans are basically triangle shaped. There are some complications when a fan partially hits a wall and has to be broken into pieces to continue. Anyway, this tree of reflected fans can be traversed breadth first or depth first since you're limiting the total distance.
You may also want to look into radiosity methods, which is probably similar to what I've just described, but is usually done in 3d.
I do not know of any existing solutions for such a problem. Good luck to you if you find one, but incase you don't the first step to a complete but exponential (with regard to the line count) would be to break it into two parts:
Given an ordered subset of walls A,B,C and points P1, P2, calculate if a route is possible (either no solutions or a single unique solution).
Then generate permutations of your walls until you exceed whatever limit you had in mind.
The first part can be solved by a simple set of equations to find the necessary angles for each ray bounce. Then checking each line against existing lines for collisions would tell you if the path is possible.
The parameters to the system of equations would be
angle_1 = normal of line A with P1
angle_2 = normal of line B with intersection of line A
angle_3 = normal of line C with ...
angle_n = normal of line N-1 with P2
Each parameter is bounded by the constraints to hit the next line, which may not be linear (I have not checked). If they are not then you would probably have to pick suitable numerical non-linear solvers.
In response to brainjam
You still need wedges....
alt text http://img72.imageshack.us/img72/6959/ssdgk.jpg
In this situation, how would you know not to do the second reflection? How do you know what walls make sense to reflect over?