Given the coordinates of a polygon,
I found many algorithms to detect if a point is in a polygon - for example: [1] and [2]. But none of these algorithms are able to detect if the point lies on the vertices of this polygon. For example I have a polygon:
|---------------------|
| |
| |
|---------------------|
My point is in the right upper corner. I want an algorithm that tells me whether the point is inside the polygon. How can I do this?
Except for problem of dealing with issues related to floating point not exact match but close enough, the same algorithm should work for both.
Just pick a point inside the polygon, create the test line segment from the test point to the inside point, and then, for each segment in the polygon, determine if a test line segment intersects that polygon segment, To count as intersect, count intersects open on one end of polygon segment, and closed on the other end, i.e., if the intersection is exactly the same as the start of the polygon, count it, but if it's exactly the same as the end point, do Not count it. You need to do this so that when the test segment intersects with a polygon vertex, you must only count it as intersecting one of the two segments on either side of the vertex.
Then If test point is inside polygon, the number of intersections will be an even number, if it is outside, it will be an odd number.
Just found a solution right here. It is very easy and the code from [1] has a and b already implemented. Additional information to the source code can be found here.
const float EPSILON = 0.001f;
bool IsPointOnLine(Point linePointA, Point linePointB, Point point)
{
float a = (linePointB.y - linePointA.y) / (linePointB.x - linePointB.x);
float b = linePointA.y - a * linePointA.x;
if ( fabs(point.y - (a*point.x+b)) < EPSILON)
{
return true;
}
return false;
}
Related
Given a collection of points, I'd like to find the center of a bounding box (fixed-length and width) that maximizes the number of points within said box. I'm at a loss for an efficient way to do this.
Algorithm with complexity O(N^2*logN) (I hope that better one exists):
Edit: article exploiting interval trees claims O(NlogN) complexity
Sort data array A by X coordinate.
Scan A with sweep line left to right.
For every point in A get LeftX = A[k].X - left coordinate of vertical band, find the rightmost coordinate of vertical band RightX = LeftX + Width.
Copy points inside the band to another array B.
Sort B by Y-coordinate.
Scan B width sweep line top to down.
For every point B[i] get TopY = B[i].Y - top coordinate of rectangle, calculate BottomY = TopY + Height.
Use binary search in B:
B[j] is the last bottom point in B with B[j].Y <= BottomY.
Find number of points in the current rectangle:
Number of points is N(k, i) = j - i + 1
Check whether N(k, i) is maximum among others
This seems like a difficult problem, here is my idea:
Hold a graph, each node holds a rectangle and a subset of points. the rectangle defines the area where placing the bounding box in would overlap all the points in the subset.
To build the graph:
Start with a root node holding the empty set and the rect [top:-inf, bottom:inf, left:-inf, right:inf]
For each point in the tree call this recursive function with the root node (pseudo code):
function addPoint(node, point)
// check that you didn't already try to add this point to this node
// node.tested can be a hash set
if(node.tested contains point)
return
node.tested.add(point)
newRect = node.rect.intersectWith(boundingBoxAround(point))
// if the bounding box around the point does not intersect the rectangle, return
if(newRect is invalid) // rect is invalid if right<left or bottom<top
return
node.addChild(new node(newRect, node.pointSet U {point})
for each child of node
addPoint(child, point)
Now you just pick the node with the largest subset, you can keep track of that when building the graph so you don't need to run through the graph again.
I hope my idea is clear, let me know if I can explain it better.
I have a list of points in cartesian plane, and a test point. I want to find list indices of three points nearest to test point. What's the better way to find these indices? Thanks in advance for tour replies.
=== EDIT ===
I've found a solution in C++. At first I create a vector:
typedef struct
{
int iIndex;
double dSqrDistance;
} IndexedDistance;
std::vector<IndexedDistance> xDistanceVector;
and then a function to sort its elements
bool compareIndexedDistance(IndexedDistance xD1, IndexedDistance xD2)
{
return (xD1.dSqrDistance < xD2.dSqrDistance);
}
Then in a loop I calculate all distances, then I sort them and at the end I take first three elements:
IndexedDistance xDistanceElement;
for (int i = 0; i < xPointList.size(); i++)
{
dSqrDistance = xPointList.at(i).sqrDistance(xTestPoint);
xDistanceElement.iIndex = i;
xDistanceElement.dSqrDistance = dSqrDistance;
xDistanceVector.push_back(xDistanceElement);
}
std::sort(xDistanceVector.begin(), xDistanceVector.end(), compareIndexedDistance);
xDistanceVector.resize(3);
In this way, I found what I need. I don't know if it's the best way, but it seems to work.
Binary space partitioning may provide algorithms complexity of O(log n * log n).
Determine bounds of your point set. Infinum and supremum points will give you an axis-aligned square containing all the points in set.
Split the bounding square in two by any of axis. Make a separate list of contained points for each square. Link each of bounding squares to the parent square.
Repeat splitting bounding squares (step 2) until corresponding lists of containing points will be reasonably small to utilize exhaustive search.
Now you will be able to use tree search to localize space around your point of interest and therefore greatly reduce number of distance tests.
The tricky part is that you must scan all the neighbour bounding squares around the point of interest because the closest point may lie in any of them.
I was wondering if the following algorithm to check if a point is inside a rectangle is valid.
I've developed it using my own intuition (no strong trig/math basis to support it), so I'd love to hear from someone with more experience in the matter.
Context:
The rectangle is defined with 4 points. It could be rotated.
Coordinates are always positive.
By definition, the point is considered inside the rectangle if intersects it.
Hypothesis:
Use the distance between the point and the rectangle vertices (first diagram below).
The maximum possible total distance is when the point is in one vertex (second diagram).
If the point is just outside the rectangle, the distance will be greater (third diagram).
Diagram link: http://i45.tinypic.com/id6o35.png
Algorithm (Java):
static boolean pointInsideRectangle(Point[] rect, Point point) {
double maxDistance = distance(rect[0], rect[1]);
maxDistance += distance(rect[0], rect[2]);
maxDistance += distance(rect[0], rect[3]);
double distance = 0;
for (Point rectPoint : rect) {
distance += distance(rectPoint, point);
if (distance > maxDistance) return false;
}
return true;
}
Questions: is this correct?
Short answer: NO :P (don´t fell bad about it)
Long Answer: Intersecction the areas from the four circles that you mention (max distance between opposite vertex) does not produce a rectangle.
Since I´m a bit rusty in geometry I can´t give full mathematical explanation (time constrain for my part), but give you some pseudocode of the procedure with the constrains that you ask (no fancy formulae), valid for any rectangle the wikipeida or a geometry book can fill the gaps.
Find the N,E,S,W vertex (the uppermost, rightmost, lowest and leftmost vertex) this is trivially easy for any rectangle but the axis aligned who can produce oddly assignation of the vertex (see images with examples)
Find the NE, SE, SW and NW border, this is the line equation in wikipedia or another link, again should be easy, but the axis aligned border should be analized carefully because those generate another type of ecuation/restriction.
Check if your point is on the "right side" of the border see inequality as mathematical term, only a point inside your rectangle satisfy the four restrictions as you can see in the image attached.
my apologies if I have overlook some command of java.geom that can accomplish this task
I hope this help with your endevour
You can try this.Lets name the point we have as A.Draw a line between A and every point of the rectangle.After that you get 4 different triangles.Calculate the area the triangles are taking(using Heron's formula) and compare it to the area of the rectangle.If the areas are the same then your point is inside the rectangle.
Cheers
I'm using a Segment to Segment closest approach method which will output the closest distance between two segments of length. Each segment corresponds to a sphere object's origin and destination. The speed is simply from one point, to the other.
Closest Approach can succeed even when there won't be a real collision. So, I'm currently using a 10-step method and calculating the distance between 2 spheres as they move along the two segments. So, basically the length of each segment is the object's traverse in the physics step, and the radius is the objects radius. By stepping, I can tell where they collide, and if they collide (Sort of; for the MOST part.)..
I get the feeling that there could be something better. While I sort of believe that the first closest approach call is required, I think that the method immediately following it is a TAD weak. Can anyone help me out? I can illustrate this if needed.
Thanks alot!
(source: yfrog.com)
(I don't know how to post graphics; bear with me.)
All right, we have two spheres with radii r1 and r2, starting at locations X1 and X2, moving with velocities V1 and V2 (X's and V's are vectors).
The velocity of sphere 1 as seen from sphere 2 is
V = V1-V2
and its direction is
v = V/|V|
The distance sphere 1 must travel (in the frame of sphere 2) to closest approach is
s = Xv
And if X is the initial separation, then the distance of closest approach is
h = |X - Xv|
This is where graphics would help. If h > r1+r2, there will be no collision. Suppose h < r1+r2. At the time of collision, the two sphere centers and the point of closest approach will form a right triangle. The distance from Sphere 1's center to the point of closest approach is
u = sqrt((r1 + r2)^2 - h^2)
So the distance sphere 1 has traveled is
s - u
Now just see if sphere 1 travels that far in the given interval. If so, then you know exactly when and where the spheres were (you must shift back from sphere 2's frame, but that's pretty easy). If not, there's no collision.
Closest approach can be done without simulating time if the position function is invertible and explicit.
Pick a path and object.
Find the point on the path where the two paths are closest. If time has bounds (e.g. paths are line segments), ignore the bounds in this step.
Find the time at which the object is at the point from the previous step.
If time has bounds, limit the picked time by the bounds.
Calculate the position of the other object at the time from the previous step.
Check if the objects overlap.
This won't work for all paths (e.g. some cubic), but should work for linear paths.
If I have 5 Vertices in 3D coordinate space how can I determined the ordering of those Vertices. i.e clockwise or anticlockwise.
If I elaborate more on this,
I have a 3D model which consists of set of polygons. Each polygon is collection of vertices and I want to calculate the norm of the polygon surface. To calculate the norm I have to consider the vertices in counter clockwise order . My question is given set of vertices how can I determine whether it is ordered in clockwise or counter clockwise?
This is for navigation mesh generation where I want to remove the polygons which cannot be walked by the agent. To do so my approach is to calculate the surface norm(perpendicular vector of the polygon) and remove the polygon based on the angle with 2D plane. To calculate the norm I should know in which order points are arranged. So for given set of points in polygon how can I determine the order of the arrangement of points.
Ex.
polygon1 consist of Vertex1 = [-21.847065 -2.492895 19.569759], Vertex2 [-22.279873 1.588395 16.017160], Vertex3 [-17.234818 7.132950 7.453146] these 3 points and how can I determine the order of them
As others have noted, your question isn't entirely clear. Is the for something like a 3D backface culling test? If so, you need a point to determine the winding direction relative to. Viewed from one side of the polygon the vertices will appear to wind clockwise. From the other side they'll appear to wind counter clockwise.
But suppose your polygon is convex and properly planar. Take any three consecutive vertices A, B, and C. Then you can find the surface normal vector using the cross product:
N = (B - A) x (C - A)
Taking the dot product of the normal with a vector from the given view point, V, to one of the vertices will give you a value whose sign indicates which way the vertices appear to wind when viewed from V:
w = N . (A - V)
Whether this is positive for clockwise and negative for anticlockwise or the opposite will depend on the handedness of your coordinate system.
Your question is too poorly defined to give a complete answer, but here's the skeleton of one.
The missing part (the meat if you will), is a function that takes any two coordinates and tells you which one is 'greater' than the other. Without a solid definition for this, you won't be able to make anything work.
The rest, the skeleton, is pretty simple. Sort your list of vectors using your comparison function. For five vectors, a simple bubble sort will be all you need, although if the number of vertices increases considerably you may want to look into a faster sorting algorithm (ie. Quicksort).
If your chosen language / libraries provide sorting for you, you've already got your skeleton.
EDIT
After re-reading your question, it also occurred to me that since these n vertices define a polygon, you can probably make the assumption that all of them lie on the same plane (if they don't, then good luck rendering that).
So, if you can map the vector coordinates to 2d positions on that plane, you can reduce your problem to ordering them clockwise or counterclockwise in a two dimensional space.
I think your confusion comes from the fact that methods for computing cross products are sometimes taught in terms of clockwiseness, with a check of the clockwiseness of 3 points A,B,C determining the sign of:
(B-A) X (C - A)
However a better definition actually determines this for you.
In general 5 arbitrary points in 3 dimensions can't be said to have a clockwise ordering but 3 can since 3 points always lie in a plane.