We are working on one map solution.
Here user has drawn one polygon on the map and for a given point we need to find if point is residing in or out of the polygon.
We are using one SQL technique as per http://www.sql-statements.com/point-in-polygon.html to do this task till now but during the time we found out that its not worked for some areas.
Does anyone has the proper solution on this? We can also try the solution in C# if its working fine
Thank you.
If you are using SQL Server 2008 then you can use STIntersection (geography Data Type) - SQL Server will do everything for you.
I'd recommend SQL Server 2008 in this case because it provides native support for geographical data. Before you use it "STIntersect giving incorrect result for geography Datatype" might be worth of reading. Example from that site:
declare #point geometry
declare #polygon geometry
set #point = geometry::STGeomFromText('POINT (-88.22 41.50000001)', 4326)
set #polygon = geometry::STGeomFromText('POLYGON ((-88.2 41.5, -88.2 41.6, -88.3 41.6, -88.3 41.5, -88.2 41.5))', 4326)--124
Select #point.STIntersection(#polygon).ToString()
Paraphrased from http://en.wikipedia.org/wiki/Point_in_polygon
The easiest way to do this is draw an imaginary line from your point in one direction and count the number of lines it crosses. If it's odd, the point is inside, even the point is outside.
Basically iterate through each point pair, find where it crosses the horizontal line at your point, if it crosses to the right, increment the counter, if it crosses to the left or doesn't cross at all, ignore it. Horizonal lines right at your point should not be counted either (boundary condition).
IMHO the basic explanation of the PIP solutions are missing half of the important stuff, i.e. how to determine what lines of the polygon to actually test for having been crossed. Just in case of Michał Powaga's solution not working for you.
Point P(x, y) is your point. Points P0(x0, y0) and P1(x1, y1) form a line. The imaginary line we draw to see how many poly-lines we cross is horizontal.
1) First determine what lines are actually crossable (lines that are parallel to the imaginary line you draw or lines that are above or below the line would obviously not be crossed):
For each line of the polygon, compute weather P would be able to cross it.
If ((x0 < x < x1) OR (x0 > x > x1)) add line to some list.
2) Determine which of the remaining lines (those in the list) are actually crossed:
For each line in list, compute
result = (y - y0) * (x1- x0) - (x - x0) * (y1 - y0)
If (result < 0) the line was crossed, increment a counter.
If (result == 0) the point is ON the line, increment a counter if thats supposed
to count as the point having crossed the line, else don't ...
If (result > 0) the line was not crossed, so just continue with the loop.
[Note: double check weather I got the sides right ...]
3) Now, if the counter is an odd number your point is inside, if it is even or zero it is outside of the polygon.
Related
I was wondering if it is possible to find the dimensions (in pixel) of a cube/cuboid in an image like the one shown below?
I know its nearly impossible because of no information about the depth,the viewing angle, etc. But at least can one find the appropriate corners of the cube so that the length, width and height can be approximated?
Any type help or information would be appreciated.
Thanks in advance.
I guess I could suggest a solution to the "at least" part of the question. You can find the corners of the cube by finding the lines in the image.
Firstly, find the edges in the image. If the target images are as plain and clear as the provided one, finding edges must be straighforward. Use cv::Canny().
cv::Mat img = cv::imread("cube.png");
cv::Mat edges;
cv::Canny(img, edges, 20, 60);
Secondly, in the edges image, detect the straight lines. Use either cv::HoughLines() or cv::HoughLinesP(). Here, I proceed with the former one:
std::vector<cv::Vec2f> lines;
cv::HoughLines(edges, lines, 0.6, CV_PI / 120, 50);
Plaese refer to the on the OpenCV documentation on Hough lines. I also took the code for the visualization from there.
The cv::HoughLines() function detects straight lines and, for each line, returns 2 values (ρ - distance, and θ - rotation angle) which define this line's equation in polar coordinates. This function would often return several lines for one source edge (as it did for a couple of lines here). In our case, we can remove such duplicates by filtering lines with the very close ρ values.
The benefit of our case is that the sides of the cube resposible for each dimension (length, width, and height) will have the same rotation angle θ in found line equations. For instance, we can expect vertical sides of the cube (responsible for the height dimension) to remain vertical and have their θ close to 0 or π (see the OpenCV documentation). We could find such lines in the vector of the detected Hough lines:
std::vector<cv::Vec2f> vertical_lines;
std::copy_if(lines.begin(), lines.end(), std::back_inserter(vertical_lines), [](cv::Vec2f line) {
//copy if θ is near 0 or CV_PI
return ((0 < line[1]) && (line[1] < 0 + CV_PI / 10)) ||
((line[1] < CV_PI) && (line[1] > CV_PI - CV_PI / 10));
});
The same reasoning applies to finding the lines for the rest of the cube sides. Just filter the found Hough lines by appropriate θ.
Now that we have the equations of the lines of our interest, we can find their corresponding edge pixels (not optimal code below, just demo):
std::vector<cv::Point> non_zero_points;
cv::findNonZero(edges, non_zero_points);
std::vector<std::vector<cv::Point>> corresponding_points(vertical_lines.size());
for (int i = 0; i < vertical_lines.size(); ++i)
for (auto point : non_zero_points)
if (abs(cos(vertical_lines[i][1])*point.x + sin(vertical_lines[i][1])*point.y - vertical_lines[i][0]) < 2)
corresponding_points[i].push_back(point);
Now, for each found cluster find the top-most, the bottom-most points (or left-most/right-most for the other sides) and get your cube corners.
Please note the pixel I denoted by exclamation marks. It got accidently sorted to one of the vertical Hough lines, but it actually belongs to a non-vertical top side. It needs to be removed, by some outlier detection or by some other approach to the corresponding pixel search.
About retreiving actual lengths of the sides: to my knowledge, it is really a non-trivial problem. Maybe this SO question would be a good place to start.
I've read a lot of questions that were "similar" to mine but no one has been good for me. The thing is that I want to know the longest distance from a curve and a straight line. The curve line is the touch input of the user, every point, and the straight line is from the start touch point to the end touch point.
What's the best and efficient way to achieve that?
Thank you.
Assuming your curve is given by IEnumerable<Point> curve and your line is given by two points start and end.
Func<Point, double> distance = p =>
Math.Abs(
(end.Y - start.Y)*p.X
- (end.X - start.X)*p.Y
+ end.X*start.Y
- end.Y*start.X
)
/ Math.Sqrt(
(end.Y - start.Y)*(end.Y - start.Y)
+ (end.X - start.X)*(end.X - start.X));
Point nearest = curve.OrderBy(distance).First();
Point farthest = curve.OrderByDescending(distance).First();
This is not the most efficient way to do it, because one iteration over the data would suffice and the sorting is overkill. However, there is no builtin ArgMinAndMaxBy in Linq, and speed might not be an issue.
You can, trivially, replace the type Point (from System.Drawing) by your Vector2 type, by the way.
if you are asking which is the longest distance between the straight line and through the curve... the curve has the longest distance.. use the power of calculus where you can estimate the exactly distance of the curve by making use of straight line segments on the curve. the more line segments you can put in higher chance of improved approximation of the distance..
I'm trying to find the fastest and easiest way in a C# program to calculate the intersections of two circles. From what I can tell there are two possible methods, and you'll have to forgive me for not knowing the official names for them.
We're assuming you know the center points for both circles and their exact radii, from which you can calculate the distance between them, so all that is missing are the point(s) of intersection. This is taking place on a standard x-y plot.
The first is a kind of substitution method like the one described here where you combine the two circle formulas and isolate either x or y, then sub it back in to an original formula to end up with a quadratic equation that can be solved for two (or possibly one or none) coordinates for an axis, which then lets you find the corresponding coordinates on the other axis.
The second I have seen a reference to is using a Law of Cosines method to determine the angles, which would then let you plot a line for each side on the grid, and put in your radius to find the actual intersection point.
I have written out the steps for the first method, and it seems rather lengthy. The second one is going to take some research/learning to write out but sounds simpler. What I've never done is translate processes like this into code, so I don't know ultimately which one will be the easiest for that application. Does anyone have advice on that? Or am I perhaps going about the the complete wrong way? Is there a library already out there that I can use for it instead of reinventing the wheel?
Some context: I'm worried mainly about the cost to the CPU to do these calculations. I plan on the application doing a heck of a lot of them at once, repeatedly, hence why I want the simplest way to accomplish it.
Computational geometry is almost always a pain to implement. It's also almost always quite CPU-intensive. That said, this problem is just algebra if you set it up right.
Compute d = hypot(x2-x1, y2-y1), the distance between the two centres. If r1 + r2 < d, there is no intersection. If r1+r2 == d, the intersection is at (x1, y1) + r1/(r1+r2) * (x2-x1,y2-y1). If d < abs(r1-r2), one circle is contained in the other and there is no intersection. You can work out the case where the two circles are tangent and one is contained in the other. I will only deal with the remaining case.
You want to find distances h orthogonal to (x2-x1,y2-y1) and p parallel to (x2-x1,y2-y1) so that p^2 + h^2 = r1^2 and (d-p)^2 + h^2 = r2^2. Subtract the two equations to get a linear equation in p: d^2-2dp = r2^2-r1^2. Solve this linear equation for p. Then h = sqrt(r1^2 - p^2).
The coordinates of the two points are (x1,y1) + p (x2-x1,y2-y1) / d +/- h (y2-y1, x1-x2) / d. If you work through the derivation above and solve for p/d and h/d instead, you may get something that does fewer operations.
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
How can I tell if a point is nearby a certain line?
//Returns the point on the line traced from start to end which
//comes nearest to 500,000, 500,000. The points are scaled between
//1,000,000 and 0 from their original fp types.
Point closestToCentre(Point start, Point end);
Anyone know of quicker way than single stepping through the pixels?
Could some one more alert than me demonstrate their maths & geometry prowess please?
_______EDIT___________
Thanks Kris, this was confusing me :
[x; -a/bx-c/b]=[0; -c/b]-1/b[-b; a]x.
Now I see it is just splitting (mainly the y component) the vector into two which combine to yield the same result. Got the old partial fractions brain cell excited for a minute then :)
_______EDIT_________
Jason Moore, thanks for the inspiration, here is what I am doing, graphically,
I hope that is clearer.
____EDIT________
So I could reasonably expect to take a line at right angles to my sampled line and run it from the centre but how to tell when they touch?
I think Kris's page of equations is the way to go. If you're all telling me it is a two step process. It is just two simultaneous equations now, so I may not need Kris's derivations.
____EDIT_________
Whether good or bad thing, I don't know, but the beauty of stackoverflow as a search engine has revealed to me several routes of investigation. Chiefly I like the first solution here:
Shortest distance between a point and a line segment.
But to prove this to my self I needed the link from matti's solution at the bottom (but one):
http://www.topcoder.com/tc?d1=tutorials&d2=geometry1&module=Static
The derivation is so simple and elegant even I could follow it!
Given http://mathworld.wolfram.com/Point-LineDistance2-Dimensional.html
This is a matter of linear projection of a point onto a line, which can be done with some fine vector gymnastics, as elaborated at MathWorld.
The article details how to find the shortest distance from a point to a line, and one of the intermediate steps is finding the perpendicular line from the point x,y to the original line. Intersecting these two lines will give you the point, on the line, closest to x,y.
Edit in response to comment: What equation (2) in the link is doing is transforming the vector into a form reminiscent of y = mx + c, which allows you to quickly and easily read off the gradient, from which the perpendicular gradient can be easily calculated.
I think the quickest way will be a two step process:
Assume your line is infinite in length, and find the intersection of your line and its perpendicular bisector through (500,000, 500,000).
Make sure that point is actually on your line, else find the closest endpoint.
Kris's post covers step 1 pretty well, all you have to do is add the check for step 2 because you have a line segment and you're golden.
Let point 1 = (x1, y1) and endpoint 2 = (x2, y2). Then the line containing these two points is
y = (y2 - y1)/(x2 - x1) * (x - x1) + y1
and the perp. bisector through (5e5, 5e5) is
y = (x1 - x2)/(y1 - y2) * (x - 5e5) + 5e5
Your point (x,y) is the solution (x,y) to the above two equations (or one of the two endpoints). This might be more straightforward than the mathworld link. Note that this solution fails, however, when your line is either almost vertical or almost horizontal whereas I don't think the mathworld solution style does, though I haven't looked very closely.
I have an application (cad like editor) in which the user may place a lot of positional nodes (defined by their latitude and longitude). The application needs to tell the user if these nodes are very close together - a common design error is to overlap them. What the app is doing is something rather like ReSharper or CodeRush does in the IDE - parses the project and reports problems. A project may have several thousand of these nodes so testing for overlap becomes exponetially more time consuming as the numbers go. At the moment I am using two for loops to get through the list.
for (int i = 0; i < count - 1; i++) {
for (int j = i + 1; j < count; j++) {
// check the distance between the i and j elements and if less than
// a predetermined value report it
}
}
I would like to get the process of identifying these into 'real time' so that the user is told at once in the event that an overlap occurs. The looping is expensive as is the testing of the distance between nodes. Most of the comparisons are wasted of course.
I just wonder if there is another way. I have thought about sorting the list by lat and lon and comparing adjacent elements but I suspect that will not work nor necessarily be faster.
My other thought is to move the activity to another thread (I really have no experience of using multiple threads) so that the values are being updated - for example storing a reference to nearby nodes in each object. However I can imagine needing to clone the object tree for the background thread so that there is no conflict with the foreground.
You could look into Tessealtion.
Executing this on another Thread is a completely separate issue, you could do that with your nested loops as well as with a more efficient algorithm.
Since the user is placing these locations, the ideal solution would be to assume all previously placed points are not nearby, and with each new point or moved point, check against the rest -- this becomes a single for loop, which should be reasonable.
Another, more ideal solution however:
Let position of A be lat, lng.
Convert both lat and lng to a fixed-length representation
(truncating the degree of precision to a value below which
you are sure they will overlap)
Let xa = lat . lng (concatenate both)
Let ya = lng . lat
Given some position B, find xb, yb.
B is 'close' to A iff | xa - xb | < delta, | ya - yb | < delta.
So what you can do is sort the values of xi, yi for all your input points. When you want to check for points that are too close, you need to traverse through the list of xi's to find points that are too close together (linear time, since they will be adjacent) and then check if the same points in the list of yi's are too close.
Thanks to the insights given here I think I have found a reasonable way to deal with this.
*First to sort all the points in latitude order.
*Then loop through the sorted list.
*For each entry in the list compare the latitude offset (distance in meters) to the entries below it.
*If the latitude offset is less than the test distance then check the actual distance from point to point and if it is inside the test radius report the issue.
*When the latitude offset exceeds the test distance move on to the next point in the list and repeat the tests.
I have not written the code yet but it seems to me that if there are no overlaps then I will make a single pass. Since overlaps are rare in practice then the total number of tests is likely to be quite small. For 1000 points the current method makes 500,000 tests. The new method is unlikely to make more than a few thousand.