How can I achieve the reverse of a k-nearest search, so that I can find geometries thar are farthest away from a given center geometry?
Background: This is about map tile caching. I want to remove irrelevant tiles which are far away from the current view.
The furthest rectangles are always at the limits. So you need to get the minimal enclosing circle, which is defined by three extremal points. The most distant from any given point within the minimal enclosing circle is then the nearest to the most distant point on the circle, which is found by taking a ray from the point in question through the origin until it hits the circumference.
So if you need many most distant neighbours, you set up a structure which tags each arc of the minimal enclosing circle with its nearest neighbour, then you can find them quickly.
However it's unlikely you actually want this. You have a rectangle of interest, and now simply exclude everything outside of it.
Related
Have a binary grid (like black and white pixels with black = empty and white = obstacle).
Starting from a given point on black, I want to emit "rays" in all directions. Those rays should either abort when reaching a given length (for example 100) or when hitting a white pixel (in which case the position of this pixel, aka obstacle contour shall be marked).
Those marked pixels result in a view of all obstacle contours that are "visible" from the given point (not obstructed by other obstacles).
What I have thought of so far, is to simply call a sufficient number of bresenham lines. In the case of a radius of 100, that means 100*2*pi = 628 lines to cover all pixels on the outer most circle.
However that results in many many multiple checks of same pixels closer to the center. Now I could split up the check in multiple rings, each of a different density of bresenham lines, but that appears rather inefficient too.
Does someone happen to have a more efficient algorithm idea for this?
Huge thanks in advance!
Unfortunately the hints towards graphics processing techniques while fascinating, are not well applicable in my case because I have no access to shaders or a camera, etc.
For now I have found a sufficiently efficient solution myself. The basic idea is to launch rays from the contours, not from the origin. Furthermore to use a helper grid named "reachable" where all pixels are marked that are successfully visible from the origin. This way only few pixels are read twice, most are read just once and some are written at most once. The code is rather messy yet, thus only pseudocode here:
Have desired origin O.x/O.y
Have obstacle bool grid Obstacle
Define bool grid Reachable[w][h]
Clear Reachable with false
Reachable[O.x][O.y] = true
For each Point C on all obstacle Contours // if not available, compute contours by finding all pixels adjacent to non-obstacle
For all Pixels A on Bresenham line from C to O
If Obstacle[A.x][A.y]
Continue with outer loop on contours // abort this line due to obstacle hit
If Reachable[A.x][A.y]
For all Pixels B on Bresenham line from C to A
Reachable[B.x][B.y] = true // mark all pixels on this line as Reachable
Mark C as a desired result pixel
Continue with outer loop on contours
Let the "square distance" between two points (x1,y1) and (x2,y2) be max(|x1-x2|,|y1-y2|), so that the points at increasing "square distance" around a center for increasingly large squares.
Now, for each square distance d from your center point, in increasing order, keep track of the angles the center point can see through all the obstacles with distance <= d.
You can use a list of angle intervals starting at [(0,360)] for d=0.
For each new distance, you can inspect the list, examine the new pixels within the given angles, and remove angle from the intervals when obstacles are hit. Each obstacle that causes you to modify an interval is visible from the center point, so you can mark it as such.
This method examines pixels only once, and only examines pixels you can see. The way I wrote it above requires trigonometry, however, which is slow. For a practical implementation, instead of actually using angles, use slopes, which require only simple math, and process each octant separately.
The basics of Weiler-Atherton Polygon Clipping algorithm are:
Start from the first edge which is going inside the clipping area.
When an edge of a candidate/subject polygon enters the clipping area, save the intersection point.
When an edge of a candidate/subject polygon exits the clipping area, save the intersection point and follow the clipping polygon.
How to distinguish between an inbound and an outbound edge of a polygon?
It seems like finding inbound edges invole another huge algorithm and thereby affects the efficiency of the algorithm.
Another question is, how can I find the first inbound intersection?
This answer seems to be shedding some light on the problem. But, sadly it doesn't work.
For example, if I reverse the direction of vectors, the angle is not negated.
https://www.wolframalpha.com/input/?i=angle+between+vector+%7B0%2C180%7D+%7B180%2C0%7D
https://www.wolframalpha.com/input/?i=angle+between+vector+%7B0%2C180%7D+%7B-180%2C0%7D
First, a reminder that the Weiler–Atherton algorithm uses polygons defined by vertices in a specific order, clockwise. In short, you test for edges going in or out by traversing the polygon clockwise. The first edge going in (and therefore the first inbound intersection) is simply the first edge you traverse which started outside the clipping area (see below).
Also, the algorithm is typically run in two phases. First find all intersections, these are added to a list of vertices for your polygons, inserted at the correct position. During this phase you would typically mark whether each vertex is within the other polygon. For the second phase, traverse the vertices to determine clipping polygons.
Lets try some examples. Take a triangle defined by vertices A,B,C, and a rectangle w,x,y,z. The triangle will be the clipping area, rectangle is the subject.
The list of points we have generated for the subject is therefore w,x,R,Q,y,z. The triangle list is now A,B,Q,C,R.
Starting at w, R is the first intersection, it is inbound because the previous point (x) is outside. The traversal of the area will be R,Q,C, and back to R(done).
The intersections are unlabeled here, but they will still be R and Q. The list of points we have generated for the subject is therefore w,x,R,y,Q,z. The triangle list is now A,B,C,Q,R.
The clipping traversal is R,y,Q, and R(done)
Let P and Q be two polygons. One can pick any vertex v of P in order to determine the position of v with respect to Q (i.e inside or outside it) via the ray casting algorithm (or any other algorithm that suits all the requirements of the problem).
You only need to determine the position of one such vertex v of P with respect to Q in this manner because the position of the other vertices of P can be inferred by iterating over the ordered set of vertices and intersection points of P.
Lets say v is outside Q. Then, by iterating over the ordered set of vertices and intersection points of P, the first intersection point one finds is laying on an entering edge. If v is inside Q, the first intersection point one finds is laying on an exiting edge. Keep in mind that one edge can be both entering and exiting, depending on the number of intersection points laying on it.
The idea behind the ray casting algorithm is simple, but one should pick vertex v of P if |V(P)|>=|V(Q)| and v of Q otherwise (in order to lower the impact the ray casting algorithm has on the overall performance, though not significantly).
You do not necessarily need to start at the first inbound intersection, this is fine when you are looking at the polygons drawn on a piece of paper and can drop your pen wherever you want, but as you noted would require more effort to find when coding it.
You just need to make sure you get all the intersections calculated for your two polygons first walking around the source polygons line segments checking for intersections with the clipping polygons line segments. At this point it does not matter whether it is inside or outside.
Once you have all the intersections and your two polygons points in order (I think I had two lists that could link to each other), walk around your source polygon point by point. If your first source polygon point is inside the clip polygon that is the first point of your solution polygon, if not the first point of your solution polygon is the first intersection with the clip polygon.
Once you have your first solution point each point from there is the next solution point. As you hit intersections you switch to the other polygon and carry on until you return back to your first solution point.
It has been a while since I have coded this, but if I remember correctly points that can catch you out are when polygons are entirely inside each other (in which case the contained one is your solution) and make sure you are prepared for more than one solution polygon if you have some odd polygon shapes.
I have a set of point cloud, and I would like to test if there is a corner in a 3D room. So I would like to discuss my approach and if there is a better approach or not in terms of speed, because I want to test it on mobile phones.
I will try to use hough tranform to detect lines, then I will try to see if there are three lines that are intersecting and they make a two plane that are intersecting too.
If the point cloud data comes from a depth sensor, then you have a relatively dense sampling of your walls. One thing I found that works well with depth sensors (e.g. Kinect or DepthSense) is a robust version of the RANSAC procedure that #MartinBeckett suggested.
Instead of picking 3 points at random, pick one point at random, and get the neighboring points in the cloud. There are two ways to do that:
The proper way: use a 3D nearest neighbor query data structure, like a KD-tree, to get all the points within some small distance from your query point.
The sloppy but faster way: use the pixel grid neighborhood of your randomly selected pixel. This may include points that are far from it in 3D, because they are on a different plane/object, but that's OK, since this pixel will not get much support from the data.
The next step is to generate a plane equation from that group of 3D points. You can use PCA on their 3D coordinates to get the two most significant eigenvectors, which define the plane surface (the last eigenvector should be the normal).
From there, the RANSAC algorithm proceeds as usual: check how many other points in the data are close to that plane, and find the plane(s) with maximal support. I found it better to find the largest support plane, remove the supporting 3D points, and run the algorithm again to find other 'smaller' planes. This way you may be able to get all the walls in your room.
EDIT:
To clarify the above: the support of a hypothesized plane is the set of all 3D points whose distance from that plane is at most some threshold (e.g. 10 cm, should depend on the depth sensor's measurement error model).
After each run of the RANSAC algorithm, the plane that had the largest support is chosen. All the points supporting that plane may be used to refine the plane equation (this is more robust than just using the neighboring points) by performing PCA/linear regression on the support set.
In order to proceed and find other planes, the support of the previous iteration should be removed from the 3D point set, so that remaining points lie on other planes. This may be repeated as long as there are enough points and best plane fit error is not too large.
In your case (looking for a corner), you need at least 3 perpendicular planes. If you find two planes with large support which are roughly parallel, then they may be the floor and some counter, or two parallel walls. Either the room has no visible corner, or you need to keep looking for a perpendicular plane with smaller support.
Normal approach would be ransac
Pick 3 points at random.
Make a plane.
Check if each other point lies on the plane.
If enough are on the plane - recalculate a best plane from all these points and remove them from the set
If not try another 3 points
Stop when you have enough planes, or too few points left.
Another approach if you know that the planes are near vertical or near horizontal.
pick a small vertical range
Get all the points in this range
Try and fit 2d lines
Repeat for other Z ranges
If you get a parallel set of lines in each Z slice then they are probably have a plane - recalculate the best fit plane for the points.
I would first like to point out
Even though this is an old post, I would like to present a complementary approach, similar to Hough Voting, to find all corner locations, composed of plane intersections, jointly:
Uniformly sample the space. Ensure that there is at least a distance $d$ between the points (e.g. you can even do this is CloudCompare with a 'space' subsampling)
Compute the point cloud normals at these points.
Randomly pick 3 points from this downsampled cloud.
Each oriented point (point+plane) defines a hypothetical plane. Therefore, each 3 point picked define 3 planes. Those planes, if not parallel and not intersecting at a line, always intersect at a single point.
Create a voting space to describe the corner: The intersection of the 3 planes (the point) might a valid parameterization. So our parameter space has 3 free parameters.
For each 3 points cast a vote in the accumulator space to the corner point.
Go to (2) and repeat until all sampled points are exhausted, or enough iterations are done. This way we'll be casting votes for all possible corner locations.
Take the local maxima of the accumulator space. Depending on the votes, we'll be selecting the corners from intersection of the largest planes (as they'll receive more votes) to the intersection of small planes. The largest 4 are probably the corners of the room. If not, one could also consider the other local maxima.
Note that the voting space is a quantized 3D space and the corner location will be a rough estimate of the actual one. If desired, one could store the planes intersection at that very location and refine them (with iterative optimization similar to ICP or etc) to get a very fine corner location.
This approach will be quite fast and probably very accurate, given that you could refine the location. I believe it's the best algorithm presented so far. Of course this assumes that we could compute the normals of the point clouds (we can always do that at sample locations with the help of the eigenvectors of the covariance matrix).
Please also look here, where I have put out a list of plane-fitting related questions at stackoverflow:
3D Plane fitting algorithms
Im working on a 2D game in which the terrain can vary and is composed of any shape of polygons except for self intersecting ones. The player collision box is in the shape of a square and can move about. My question is this: How do I keep an always-upright box to collide with variable terrain and always stay outside?
My current approach that I made up albeit no code yet works like the following:
The blue square is the player hitbox. First, it moves with a velocity downwards as an example. My goal is to find the heighest point in its travel path where it can be safely outside of the terrain polygon. I test all the terrain vertex points inside its travel path and project them to the velocity of the box. I take the farthest projection.
The farthest projection will be the max distance allowed to move in without going into the terrain.
Move the square by distance in the direction of velocity and done.
However, there are few scenarios that I encountered where this does not work. Take this as an example:
To remedy this situation, I now test for one corner of the square. If the distance from the corner is shorter than the farthest projection, then that distance will give the appropriate shift in distance. This pretty much makes the algorithm full-proof. Unless someone states another exception.
Im going a little crazy and I would appreciate feedback on my algorithm. If anyone has any suggestions or good reads about 2D upright box collisions on terrain or anything similar, that would be great.
This may be useful, and here I'll quickly elaborate on "upright" square collision.
First the collision may occur on the side of the square, and not necessarily a corner. A simple solution to check any collision is describe the region delimited by the square, and then check if any point of your uneven terrain is within this region.
To define the square region, assume your upright square is has the corners (x1,y1), (x2,y1), (x2,y2), (x1,y2), where x2>x1 and y2>y1. Then for a point (x,y) to be within the square it needs to satisfy the conditions
If( x1< x < x2 and y1< y <y2) Then (x,y) is in the square.
Then to conclude, all you need do is check if any point on the terrain satisfies the above condition.
Good luck.
Say we have an object at point A. It wants to find out if it can move to point B. It has limited velocity so it can only move step by step. It casts a ray at direction it is moving to. Ray collides with an object and we detect it. How to get a way to pass our ray safely (avoiding collision)?
btw, is there a way to make such thing work in case of object cast, will it be as/nearly fast as with simple ray cast?
Is there a way to find optimal in some vay path?
What you're asking about is actually a pathfinding question; more specifically, it's the "any-angle pathfinding problem."
If you can limit the edges of obstacles to a grid, then a popular solution is to just use A* on that grid, then apply path-smoothing. However, there is a (rather recent) algorithm that is both simpler to implement/understand and gives better results than path-smoothing. It's called Theta*.
There is a nice article explaining Theta* (from which I stole the above image) here
If you can't restrict your obstacles to a grid, you'll have to generate a navigation mesh for your map:
There are many ways of doing this, of varying complexity; see for example here, here, or here. A quick google search also turns up plenty of libraries available to do this for you, such as this one or this one.
One approach could be to use a rope, or several ropes, where a rope is made of a few points connected linearly. You can initialize the points in random places in space, but the first point is the initial position of A, and the last point is the final position of A.
Initially, the rope will be a very bad route. In order to optimize, move the points along an energy gradient. In your case the energy function is very simple, i.e. the total length of the rope.
This is not a new idea but is used in computer vision to detect boundaries of objects, although the energy functions are much more complicated. Yet, have look at "snakes" to give you an idea how to move each point given its two neighbors: http://en.wikipedia.org/wiki/Snake_(computer_vision)
In your case, however, simply deriving a direction for each point from the force exerted by its neighbors will be just fine.
Your problem is a constrained problem where you consider collision. I would really go with #paddy's idea here to use a convex hull, or even just a sphere for each object. In the latter case, don't move a point into a place where its distance to B is less than the radius of A plus the radius of B plus a fudge factor considering that you don't have an infinite number of points.
A valid solution requires that the longest distance between any neighbors is smaller than a threshold, otherwise, the connecting line between two points will intersect with the obstacle.
How about a simple approach to begin with....
If this is just one object, you could compute the convex hull of all the vertices of the obstacle, plus the start and end points. You would then examine the two directions to get from A to B by traversing the hull clockwise and anti-clockwise. Choose the shortest path.
It's a little more complex because the shape you are moving is not just a point. You can't just blindly move its centre or it will collide. It gets more complicated still as it moves past a vertex, because you have to graze an edge of your object against the vertex of the obstacle.
But hopefully that gives you an idea to ponder over, that's not conceptually difficult to understand.
I have made this image to tell my idea for reaching the object to point B.
Objects in the image :-
The dark blue dot represents the object. The red lines are obstacles. The grey dot and line are the area which can be reached. The purple arrow is the direction of the point B. The grey line of the object is the field of visibility.
Understanding the image :-
The object will have a certain field of visibility. This is a 2d situation so i have assumed the field of visibility to be 180deg. (for human field of visibility refer http://en.wikipedia.org/wiki/Human_eye#Field_of_view ) The object will measure distance by using the idea of SONAR. With the help of SONAR the object can find out the area where it can reach. Using BACKTRACKING, the object can find out the way to the object. If there is no way to go, the object must change its field of visibility
One way to look at this is as a shadow casting problem. Make A the "light source" and then decide whether each point in the scene is in or out of shadow. Those not in shadow are accessible by rays from A. The other areas are not. If you find B is in shadow, then you need only locate the nearest point in the scene that is in light.
If you discretize this problem into "pixels," then the above approach has very well-known solutions in the huge computer graphics literature on shadow rendering. For example, you can use a Shadow Map to paint each pixel with a boolean flag that indicates whether it's in shadow or not. Finding the nearest lit pixel is just a simple search of growing concentric circles around B. Both of these operations can be made extremely fast by exploiting GPU hardware.
One other note: You can treat a general object path finding problem as a point path problem. The secret is to "grow" the obstacles by an appropriate amount using Minkowski Differences. See for example this work on robot path planning.