This is more of a mathematical question.
I have a list of 2D coordinates of length N. (Nx2 list)
The coordinates are rounded numbers and form a region. The following is an example:
enter image description here
What I would like is to have a border around these points. Like the following:
enter image description here
One option to do this is to
go through the list, and for each coordinate i
check for the 8 possible neighbours j to see
if this point doesn't overlap with given coordinates k .
if this point doesn't overlap with already found border coordinates
This works well, nut needs N*N*8 calculations. For my N=1000 points: 8 million!
Does anyone know how this could be done more efficient?
Best regards,
Martin
If the size of the grid is constrained and is on the order of N as well, you could do better and get to O(N) by making a 2-D array of ints the size of the grid.
Initialize the grid to zeros.
For each point in the list of points, set the point itself to negative in the grid array and set each neighbor that isn't negative to positive.
When you're done, each point in the 2-D grid array that's positive is the border.
Make a sorted container that enforces uniqueness (in c++ STL, that's a std::set) of coordinates. Go through the points, adding each point's eight neighbors to the set if they aren't already in there. Then go though the points a second time, subtracting them from the set if they are in the set. The points that remain are the border. That's O(N*log(N)). In general that's the best you can do. But see my other answer for a better algorithm if additional criteria exist.
Related
i have two concentric circles and three points are given for each circle that are on circumference.
I need a optimized method to check if a given random point exist inbetween these circles or not.
You can compute (x²+y²), x, y, 1 for each point. The last entry is simply the constant one. Put these terms for four given points into a matrix and compute its determinant. The determinant will be zero if the points are cocircular. Otherwise the sign will tell you which point is on which side with respect to the circle defined by the other three. Use a simple example to check which sign corresponds to which direction. Be prepared for the fact that the three circle-defining points being oriented in a clockwise or counter-clockwise orientation will affect this sign, too.
Computing a 4×4 determinant can be done horribly inefficiently, too. I'd suggest you compute all the 2×2 minors from the first two rows, and all the 2×2 minors from the last two, then you can combine them to form the full determinant. See this Math SE post for details. If you need further mathematical help (as opposed to programming help), you might find more suitable answers there.
Nothe that the above works for each circle independently. Check whether the point is inside the one, then check whether it is outside the other. It does not make use of the fact that the circles are assumed to be cocircular.
Given some points in plane (upto 500 points), no 3 collinear. We have to determine the number of triangles whose vertices are from the given points and that contain exactly N points inside them. How to efficiently solve this problem? The naive O(n^4) algorithm is too slow. Any better approach?
You could try thinking of the triangle as the intersection of three half-spaces. To find the number of points inside a triangle A, B, C first consider the set of points on one side of the infinite line in direction AB. Let these sets L(AB) and R(AB) for points of the left and right. Similarly you the same with other two edges and build sets L(AC) and R(AC) and sets L(BC) and R(BC).
So the number of points in ABC will be the number of points in the intersection of L(AB), L(AC) and L(BC). (You might want to consider R(AB) instead depending on the orientation of the triangle).
Now if we want to consider the full set of 500 points. First take all pairs of points AB and construct the sets L(AB) and R(AB). This will take O(n^3) operations.
Next we test all triangles and find the intersections of the three sets. If we use some hash table structure for the sets then to find the intersection points is like a hashtable lookups. If L(AB) has l elements, L(AC) has m elements and L(BC) n elements. Say l > m > n. For each point in L(BC) we need to do a lookup in L(AC) and L(BC) so thats a maximum of 2n hashtable lookups.
It might be faster to consider a geometric lookup table.
Divide your whole domain into a coarse grid say a 10 by 10 grid. We can then put each point into a set G(i,j). We can then split the sets L(AB) into each grid cell. Say call these sets L(AB,i,j) and R(AB,i,j). In testing for intersections first workout which grid cells lie in the intersection. This dramatically reduces the search space and as each set L(AB,i,j) contain fewer members there will be fewer hashtable lookups.
Actually I happened to encounter similar problem recently but the only difference was that there were around 300 pts and I solved it using bitset (C++ STL). For every pair of points, say (x[i],y[i]) and (x[j],y[j]), I formed a bitset<302>B[i][j] and B[i][j][k] stores 1 if k-th point is above line segment from point i to point j else I would store 0.
Now in a brute force manner I get three points so as to form a triangle, lets say (x[i],y[i]), (x[j],y[j]) and (x[k],y[k]), then a point,say z-th point ,would be inside triangle if B[i][j][z]==B[i][j][k] && B[j][k][z]==B[j][k][i] && B[k][i][z]==B[k][i][j] because a point inside triangle would show similar sign w.r.t. a side of triangle as the third point of triangle(one which is not on this side).
So i get three bitset variables P=B[i][j], Q=B[j][k] and R=B[k][i] and there taking there bitwise AND then applying count() function to give me the active number of bits and hence the number of points within the triangle. But make sure you change variable P such that it gives B[i][j][k]=1 if not then take bitwise not (~) of this variable.
Though the above solution is problem specific, i hope it helps. This is the problem link: http://usaco.org/current/index.php?page=viewproblem&cpid=660
I am working on a project where I have a set of known measurements (x,y,z,a) and an input (z,a). I need to be able to interpolate the (x,y,z) so that I can get a list of possible (x,y) coordinates from a given z.
I was looking at bicubic interpolation, but I can only find examples pertaining to regular grids, and my (x,y) pairs are most certainly not regular.
Basically I am looking for some guidance on algorithms/models to achieve this goal. I am considering a triangulated irregular network, which is attractive because it breaks down into planes which are easy to determine the (x,y) from a given Z. But I would like a little more finesse.
I know it sounds like homework, its not.
Efficiency is not a concern.
Thanks!
I actually ended up using Delauney Triangulation to break down the fields into 3 dimensional X,Y,Z surfaces with an Identifier. Then given a set of (Identity,Z) pairs I form a field line from each surface, and from these lines compute the polygon formed from the shortest edges between lines. This gives me an area of potential x,y coordinates.
Take a look at Kd-tree.
These first take a set of scattered points in 2d or 3d or 10d,
then answers queries like "find the 3 points nearest P".
Are your queries z a pairs ?
For example, given a bunch of colored pins on a map, a table of x y size color,
one could put all the [x y] in a kd tree, then ask for pins near a given x0 y0.
Or, one could put all the [size color[ in a tree, then ask for pins with a similar size and color.
(Note that most kd-tree implementations use the Euclidean metric,
so sqrt( (size - size2)^2 + (color - color2)^2 ) should make sense.)
In Python, I highly recommend scipy.spatial.cKDTree.
See also SO questions/tagged/kdtree .
I have an array of points. I want to know if this array of point represents a circle, a square or a triangle.
Where should i begin? (i use C#)
Thanks
Jon
Depending on your problem, a good approach for this problem may be to use the Hough transform and all its derived algorithm
It consists in a transformation of the image space to an other space where the coordinate represents the objects parameters (angle and initial point for a line, coordinates of the center and radius for a circle)
The algorithm transforms each point of your array of points in points in the other space. Then you have to search in the new space if some points are prevailing. From these points, you will get the parameters of your object.
Of course, you need to do it once to recognize the lines (so you will know how many lines are in your bitmap and where they are) and to it to recognize the circles (it is not exactly the same algorithm)
You may have a look to this lecture (for Hough Circle Transform), but you could easily find the algorithm for line
EDIT: you can also have a look to these answers
Shape recognition algorithm(s)
Detecting an object on the image based on geometrical form
imagine it is each of these one-by-one and try to fit each of these shapes on the data.. for a square, you could find the four extreme points, and try charting out a square that goes through all of them..
Once you have got a shape in place.. you could measure the distance between each of the points and the part of the shape that is nearest to it.. then square these distances and add them up.. the shape which has the smallest sum-of-squares is probably your best bet
Use the Hough Transform.
I'm going to take a wild stab and say if you have 3 points the shape represents a triangle, 4 points is some kind of quadrilateral, any more than that is a circle.
Perhaps there's more information to your problem you could provide.
Given a list of points that form a simple 2d polygon oriented in 3d space and a normal for that polygon, what is a good way to determine which points are specific 'corner' points?
For example, which point is at the lower left, or the lower right, or the top most point? The polygon may be oriented in any 3d orientation, so I'm pretty sure I need to do something with the normal, but I'm having trouble getting the math right.
Thanks!
You would need more information in order to make that decision. A set of (co-planar) points and a normal is not enough to give you a concept of "lower left" or "top right" or any such relative identification.
Viewing the polygon from the direction of the normal (so that it appears as a simple 2D shape) is a good start, but that shape could be rotated to any arbitrary angle.
Is there some other information in the 3D world that you can use to obtain a coordinate-system reference?
What are you trying to accomplish by knowing the extreme corners of the shape?
Are you looking for a bounding box?
I'm not sure the normal has anything to do with what you are asking.
To get a Bounding box, keep 4 variables: MinX, MaxX, MinY, MaxY
Then loop through all of your points, checking the X values against MaxX and MinX, and your Y values against MaxY and MinY, updating them as needed.
When looping is complete, your box is defined as MinX,MinY as the upper left, MinX, MaxY as upper right, and so on...
Response to your comment:
If you want your box after a projection, what you need is to get the "transformed" points. Then apply bounding box loop as stated above.
Transformed usually implies 2D screen coordinates after a projection(scene render) but it could also mean the 2D points on any plane that you projected on to.
A possible algorithm would be
Find the normal, which you can do by using the cross product of vectors connecting two pairs of different corners
Create a transformation matrix to rotate the polygon so that it is planer in XY space (i.e. normal alligned along the Z axis)
Calculate the coordinates of the bounding box or whatever other definition of corners you are using (as the polygon is now aligned in 2D space this is a considerably simpler problem)
Apply the inverse of the transformation matrix used in step 2 to transform these coordinates back to 3D space.
I believe that your question requires some additional information - namely the coordinate system with respect to which any point could be considered "topmost", or "leftmost".
Don't forget that whilst the normal tells you which way the polygon is facing, it doesn't on its own tell you which way is "up". It's possible to rotate (or "roll") around the normal vector and still be facing in the same direction.
This is why most 3D rendering systems have a camera which contains not only a "view" vector, but also "up" and "right" vectors. Changes to the latter two achieve the effect of the camera "rolling" around the view vector.
Project it onto a plane and get the bounding box.
I have a silly idea, but at the risk of gaining a negative a point, I'll give it a try:
Get the minimum/maximum value from
each three-dimensional axis of each
point on your 2d polygon. A single pass with a loop/iterator over the list of values for every point will suffice, simply replacing the minimum and maximum values as you go. The end result is a list that has the "lowest" X, Y, Z coordinates and "highest" X, Y, Z coordinates.
Iterate through this list of min/max
values to create each point
("corner") of a "bounding box"
around the object. The result
should be a box that always contains
the object regardless of axis
examined or orientation (no point on
the polygon will ever exceed the
maximum or minimums you collect).
Then get the distance of each "2d
polygon" point to each corner
location on the "bounding box"; the
shorter the distance between points,
the "closer" it is to that "corner".
Far from optimal, certainly crummy, but certainly quick. You could probably post-capture this during the object's rotation, by simply looking for the min/max of each rotated x/y/z value, and retaining a list of those values ahead of time.
If you can assume that there is some constraints regarding the shapes, then you might be able to get away with knowing less information. For example, if your shape was the composition of a small square with a long thin triangle on one side (i.e. a simple symmetrical geometry), then you could compare the distance from each list point to the "center of mass." The largest distance would identify the tip of the cone, the second largest would be the two points farthest from the tip of the cone, etc... If there was some order to the list, like points are entered in counter clockwise order (about the normal), you could identify all the points. This sounds like a bit of computation, so it might be reasonable to try to include some extra info with your shapes, like the "center of mass" and a reference point that is located "up" above the COM (but not along the normal). This will give you an "up" vector that you can cross with the normal to define some body coordinates, for example. Also, the normal can be defined by an ordering of the point list. If you can't assume anything about the shapes (or even if the shapes were symmetrical, for example), then you will need more data. It depends on your constraints.
If you know that the polygon in 3D is "flat" you can use the normal to transform all 3D-points of the vertices to a 2D-representation (of the points with respect to the plan in which the polygon is located) - but this still leaves you with defining the origin of this coordinate-system (but this don't really matter for your problem) and with the orientation of at least one of the axes (if you want orthogonal axes you can still rotate them around your choosen origin) - and this is where the trouble starts.
I would recommend using the Y-axis of your 3D-coordinate system, project this on your plane and use the resulting direction as "up" - but then you are in trouble in case your plan is orthogonal to the Y-axis (now you might want to use the projected Z-Axis as "up").
The math is rather simple (you can use the inner product (a.k.a. scalar product) for projection to your plane and some matrix stuff to convert to the 2D-coordinate system - you can get all of it by googling for raytracer algorithms for polygons.