How to move within Cartesian space along cardinal directions while limiting turns? - algorithm

Given is a Cartesian coordiante system, a from-position A (X/Y), and a to-position B (X/Y). I want to move from A to B. However, I can only move on the eight directions N, NE, E, SE, S, SW, W, NW.
I know that I can calculate the "best" of these directions to take from the current position A via the dot product with the unit vectors of the axis (the eight directions), where the biggest dot product is the direction to take. But this approach leads to some kind of "oscillation" between two directions, if A is exactly in between these two.
So I am searching for an algorithm now that sovles this problem of getting from A to B with only one or max. two directions to use. Of course I am ignoring any obstalces now, so that theoretically I can always get from A to B with a maximum of two different directions. I could probably solve this problem with a bunch of if-statements, but I would prefer a more elegant solution...
I hope that was somewhat understandable :)
Thanks in advance for any ideas!
Kind regards, Matthias

the simplest solution is to head in a "diagonal" direction until you are on the same row/column as the target, and then to use the horizontal/vertical direction.
in other words:
check if you are horizontally / vertically aligned. if so, move in that direction and finish.
otherwise, find the closest diagonal direction using the method you have.
move along the diagonal until you are horizontally or vertically aligned. then move in that direction and finish.

For the case of two segments maximum, this seems relatively easy:
Project a line from A -> B and then from B -> A. Pick the cardinal closest to this line rounding in either a clockwise or counterclockwise direction. Be consistent. (Once the angle is determined from A -> B, it's likely best to just add Pi to minimize very odd edge-cases with math... not sure if it can actually occur.)
Re-project lines from A -> B and B -> A along the selected cardinal direction.
If the lines are parallel (requires movement in exactly one cardinal direction and can thus also be considered a termination in step #1) there is one segment A -> B.
If the lines are not parallel find the intersection of the lines, point C.
Then there are two segments A -> C and C -> B.
I think a smarter solution would give weights to each turn (relative to distance) -- then by configuring the weights the number of turns allowed could be increased or decreased.
Not sure if this made/makes sense, but happy coding!

You can start by computing the actual number of steps between any given point and your destination; this will probably be something like "taxicab geometry" but more complicated. If all 8 steps are the same "real"(i.e., Euclidean) distance, your step count should be something like:
dist(dx,dy) = |dx|+|dy| + sqrt(0.5)(|dx+dy|+|dx-dy|)
Then, in general, there will be two possible steps that have the same, smallest, distance-to-destination. You can then choose the direction which is the same as the last one (where possible).
Actually, if you do the math as shown above, you will probably encounter problems with floating point precision. You should still be able to make a robust decision, though, by giving a small "discount" (say 1% of a step) to the preferred direction.

It sounds like your problem stems from re-evaluating optimal route along the way. This will lead to ongoing switches between, for example, N and NE, then N, then NE, etc. This is the optimal route based on distance, but you want optimal route based on direction changes.
The resolution to this is to either
pre-plan the route, rather than re-evaluate along the way, and stick to the plan
compute a number of direction changes allowed / minimum number to take, and re-evaluate only when the target can be reached within that minimum number.
To explain my second suggestion, you should know that (without obstacles) any point can be reached in two 'moves'. Initial movement is a first move, and while travelling along that path only one more direction change is allowed. You algorithm would need to allow for this 'one more' - any possible route towards the goal should not be taken unless it can be reached within the remaining number of moves.
It appears that you algorithm is focused on minimum distance rather than minimum moves - or is it some combination of the two?

Related

Algorithm to connect multiple points without inclusion

I am searching for an algorithm to connect multiple points without including one of the points. The requirement is that all points are connected but no points are in the interior of the resulting polygon. I was not sure what the technical term for this could be and did not find anything to solve my problem. The setting might look similar to this:
Setting
I am not looking for a convex hull algorithm since it might include some points (In the image 2,6,8). The result should be close to the convex hull (as far as possible) but satisfy the requirement of not including any points. Any suggestions?
Start with a point then go to another one in a clockwise (or counter-clockwise fashion). According to Green's Formula you should be integrating the area (in the discrete case it amounts to counting your vertices).
clockwise procedure: Say you start with the top-most point xi
from all points right side of xi, pick the nearest below xi
if not existing: from all points left side of xi, pick the nearest below xi
if your reached the bottom-most point, you go now up but with the opposite recipe (i.e. check the left side first, then the right side)
you can start with 0->1, 1->2, .. n-1 -> n, n->0
Now look at these lines and see if any of them cross over.
If line a-b crosses line c-d, delete these two lines and create two new lines, line a-c and line a-d.
Since we are removing crossings, the total length of all the lines is always decreasing, so it should converge to something with zero crossings and everything connected..

How can I pick a set of vertices to subtract from a polygon such that the distortion is minimum?

I'm working with a really slow renderer, and I need to approximate polygons so that they look almost the same when confined to a screen area containing very few pixels. That is, I'd need an algorithm to go through a polygon and subtract/move a bunch of vertices until the end polygon has a good combination of shape preservation and economy of vertice usage.
I don't know if there's a formal name for these kind of problems, but if anyone knows what it is it would help me get started with my research.
My untested plan is to remove the vertices that change the polygon area the least, and protect the vertices that touch the bounding box from removal, until the difference in area from the original polygon to the proposed approximate one exceeds a tolerance I specify.
This would all be done only once, not in real time.
Any other ideas?
Thanks!
You're thinking about the problem in a slightly off way. If your goal is to reduce the number of vertices with a minimum of distortion, you should be defining your distortion in terms of those same vertices, which define the shape. There's a very simple solution here, which I believe would solve your problem:
Calculate distance between adjacent vertices
Choose a tolerance between vertices, below which the vertices are resolved into a single vertex
Replace all pairs of vertices with distances lower than your cutoff with a single vertex halfway between the two.
Repeat until no vertices are removed.
Since your area is ultimately decided by the vertex placement, this method preserves shape and minimizes shape distortion. The one drawback is that distance between vertices might be slightly less intuitive than polygon area, but the two are proportional. If you really wish, you could run through the change in area that would result from vertex removal, but that's a lot more work for questionable benefit imo.
As mentioned by Angus, if you want a direct solution for the change in area, it's not actually super difficult. Was originally going to leave this as an exercise to the reader, but it's totally possible to solve this exactly, though you need to include vertices on either side.
Assume you're looking at a window of vertices [A, B, C, D] that are connected in that order. In this example we're determining the "cost" of combining B and C.
Calculate the angle offset from collinearity from A toward C. Basically you just want to see how far from collinear the two points are. This is |sin(|arctan(B - A)| - |arctan(C - A)|)| Where pipes are absolute value, and differences are the sensical notion of difference.
Calculate the total distance over which the angle change will effectively be applied, this is just the euclidean distance from A to B times the euclidean distance from B to C.
Multiply the terms from 2 and 3 to get your first term
To get your second term, repeat steps 2 - 4 replacing A with D, B with C, and C with B (just going in the opposite direction)
Calculate the geometric mean of the two terms obtained.
The number that results in step 6 presents the full-picture minus a couple constants.
I tried my own plan first: Protect the vertices touching the bounding box, then remove the rest in the order that changes the resultant area the least, until you can't find a vertice to remove that keeps the new polygon area within X% of the original one. This is the result with X = 5%:
When the user zooms out really far these shapes fit the bill well enough for me. I haven't tried any of the other suggestions. The savings are quite astonishing, sometimes from 80-100 vertices down to 4 or 5.

Connect points from set in the line segments

I have been given a task where I have to connects all the points in the 2D plane.
There are four conditions to to be met:
Length of the all segments joined together has to be minimal.
One point can be a part of only one line segment.
Line segments cannot intersect
All points have to be used(one can't be left alone but only if it cannot be avoided)
Image to visualize the problem:
The wrong image connected points correctly, although the total length is bigger that the the one in on the left.
At first I thought about sorting the points and doing it with a sweeping line and building a tree of all possibilities, although it does seem like a way to complicated solution with huge complexity. Therefore I search better approaches. I would appreciate some hints what to do, or how could I approach the problem.
I would start with a Delaunay triangulation of the point set. This should already give you the nearest neighbor connections of each point without any intersections. In the next step I'd look at the triangles that result from the triangulation - the convenient property here is that based on your ruleset you can pick exactly one side from each triangle and remove the remaining two from the selection.
The problem that remains now is to pick those edges that give you the smallest total sum which of course will not always be the smallest side since that one might already have been blocked by a neighboring triangle. I'd start with a greedy approach, always picking the smallest remaining edge that has not been blocked by neighboring triangles yet.
Edit: In the next step you retrieve a list of all the edges in that triangulation and sort them by length. You also make another list in which you count the amount of connections each point has. Now you iterate through the edge list going from the longest edge to the shortest one and check the two points it connects in the connection count list: if each of the points has still more than 1 connection left, you can discard the edge and decrement the connection count for the two points involved. If at least one of the points has only one connection left, you have got yourself one of the edges you are looking for. You repeat the process until there are no edges left and this should hopefully give you the smallest possible edge sum.
If I am not mistaken this problem is loosely related to the knapsack problem which is NP-Hard so I am not sure if this solution really gives you the best possible one.
I'd say this is an extension to the well-known travelling salesman problem.
A good technique (if a little old-fashioned) is to use a simulated annealing optimisation technique.
You'll need to make adjustments to the cost (a.k.a. objective) function to miss out sections of the path. But given a candidate continuous path, it's reasonably trivial to decide which sections to miss out to minimise its length. (You'd first remove the longer of any intersecting lines).
Wow, that's a tricky one. That's a lot of conditions to meet.
I think from a programming standpoint, the "simplest" solution might actually be to just loop through, find all the possibilities that satisfy the last 3 conditions, and record the total length as you loop through, and just choose the one with the shortest length in the end - brute force, guess-and-check. I think this is what you were referring to in your OP when you mentioned a "sweeping line and building a tree of all possibilities". This approach is very computationally expensive, but if the code is written right, it should always work in the end.
If you want the "best" solution, where you want to just solve for the single final answer right away, I'm afraid my math skills aren't strong enough for that - I'm not even sure if there is any single analytical solution to that problem for any arbitrary collection of points. Maybe try checking with the people over at MathOverflow. If someone over there can explain you with the math behind that calculation, and you then you still need help to convert that math into code in a certain programming language, update your question here (maybe with a link to the answer they provide you) and I'm sure someone will be able to help you out from that point.
One of the possible solutions is to use graph theory.
Construct a bipartite graph G, such that each point has its copy in both parts. Now put the edges between the points i and j with the weight = i == j ? infinity : distance[i][j]. The minimal weight maximum matching in the graph will be your desired configuration.
Notice that since this is on a euclidean 2D plane, the resulting "edges" of the matching will not intersect. Let's say that edges AB and XY intersect for points A, B, X, Y. Then the matching is not of the minimum weight, because either AX, BY or AY, BX will produce a smaller total weight without an intersection (this comes from triangle inequality a+b > c)

Elegant "Left-of" test for Polyline

Given:
(X,Y) coordinate, which is the position of a vehicle.
Array of (X,Y)'s, which are vertices in a polyline. Note that the polyline consists of straight segments only, no arcs.
What I want:
To calculate whether the vehicle is to the left or to the right of the polyline (or on top, ofcourse).
My approach:
Iterate over all line-segments, and compute the distance to each segment. Then for the closest segment you do a simple left-of test (as explained here for instance).
Possible issues:
When three points form an angle smaller than 90 degrees (such as shown in the image blow), a more complicated scenario arises. When the vehicle is in the red segment as shown below, the closest segment can be either one of the two. However, the left-of test will yield right if the first segment is chosen as the closest segment, and left otherwise. We can easily see (at least, I hope), that the correct result should be that the vehicle is left of the polyline.
My question:
How can I elegantly, but mostly efficiently take care of this specific situation?
My fix so far:
Compute for both segments a point on that segment, starting from the vertex point.
Compute the distance from the vehicle to both of the points, using Euclidian distance
Keep the segment for which the computed point is the closest.
I am not very happy with this fix, because I feel like I am missing a far more elegant solution, my fix feels rather "hacky". Efficiency is key though, because it is used on a realtime embedded system.
Existing codebase is in C++, so if you want to write in a specific language, C++ has my preference.
Thanks!
[edit]
I changed my fix, from a perpendicular point to a parallel point, as I think it is easier to follow the line segment than compute the outward normal.
This topic has been inactive for so long that I believe it's dead. I have a solution though.
However, the left-of test will yield right if the first segment is
chosen as the closest segment, and left otherwise.
You've used slightly ambiguous language. I'm gonna use segments to speak of the line segments in the polyline and quadrants to speak of the areas delimited by them. So in your case, you'd have a red quadrant which seems to be on the right of one segment and on the left of the other.
If the left-of test yields different answers for different segments, you should redo the test on the segments themselves. In your case, you'd have:
The quadrant is on the RIGHT of the first segment
The quadrant is on the LEFT of the second segment
Both segments disagree on where the quadrant lies, so you do two further disambiguation tests:
The second segment is on the RIGHT of the first segment
The first segment is on the RIGHT of the second segment
This allows us to conclude that the second segment is in between the first segment and the quadrant—since each of those two lies on a different side of the second segment. Therefore, the second segment is "closer" to the quadrant than the first and it's answer to the left-right test should be used as the correct one.
(I'm almost sure you can do with only one of the two disambiguation tests, I've put both in for clarity)
For the sake of completeness: I believe this solution also accounts for your demands of efficiency and elegance, since it uses the same method you've been using from the start (the left-of test), so it meets all the conditions specified: it's elegant, it's efficient and it takes care of the problem.
Let infinity = M where M is big enough. You can consider that everything is in the square [-M,M]x[-M,M], split the square with your polyline and you have now two polygons. Then checking if the car is in a given polygon can be done very simply with angles.
I consider that your first point and your last point have M in there coordinates. You may need to add some of these points to have a polygon: (-M,-M), (M,-M), (M,M) and (-M,M).
Once you have a polygon for the left of the polyline, sum the angles OĈP where O is a fixed point, C is the car and P is a point of the polygon. If the sum is 0 then the car is outside of the polygon, else it is inside.
Just a quick idea: would it be possible to connect the last and first vertex of your polyline, so that it would become a polygon? You could then do a simple inside/outside check do determine whether the vehicle is left/right of the line (this ofcourse depends on the direction of the polygon).
However, this method does assume that the polygon is still not self-intersecting after connecting the last and first vertex.
This is a standard sort of problem from computational geometry. Since you're looking to test whether a point (x0, y0) is left-of a given surface (your polyline), you need to identify which segment to test against by its height. One easy way to do this would be to build a tree of the lower point of each segment, and search in that for the test point's predecessor. Once you have that segment, you can do your left-of test directly: if it's left of both endpoints, or between them on the appropriate side, then you return true.
I am assuming here that you guarantee that the vertical extent of your polyline is greater than where you might find your query point, and that the line doesn't overlap itself vertically. The latter assumption might be quite poor.
Expansion in response to OP's comment:
Note that the angle example in the question contradicts the first assumption - the polyline does not reach the height of the search point.
One way to conceptualize my method is by sorting your segments vertically, and then iterating through them comparing your point's y-coordinate against the segments until your point is above the lower endpoint and below the higher endpoint. Then, use the endpoints of the segment to figure out the x-intercept at the given y. If the point has a lower x-cooordinate, it's to the left, and if it has a greater x-coordinate, it's to the right.
There are two ways to improve on this explanation in a real implementation, one of which I mentioned about:
Use a balanced search tree to find the right segment instead of iterating through a sorted list, to bring the time from O(n) to O(log n)
Reconceptualize the search as finding the intersection of the polyline and the horizontal line y = y0 through the search point. Then just compare the x value of the intersection against the search point.

reflection paths between points in2d

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?

Resources