How can I find the first point along a heading that is a specified distance away from a line segment? - line

Given a starting point, a heading, a distance, and a line segment, find the first point along this heading that is the specified distance away from this line segment.
I covered two cases, but I haven't been able to cover the last one.
First case: heading away from the line. Ignore it even if the starting point is within the specified distance.
Second case: It intersects the line. I solved it using trig and triangles. Initially didn't consider the next case.
Third case: It is heading towards the line, but it does not intersect it. I think this will solve the second case as well if it's done correctly.
Three subcases:
The minimum line distance is greater than the specified distance. Ignore it.
The minimum line distance is equal to the specified distance. Found the points already.
The minimum line distance is less than the specified distance. This means there is a perpendicular line from the along the heading to an endpoint of the line segment that is less than the distance needed. This also means that on either side of this perpendicular line will be two lines of the distance needed. One is perpendicular to the heading, while the other is closest to the same endpoint and not perpendicular to the heading. Just a matter of finding those points and seeing which one is closer to the start point.
This is where I am stuck today. Drawing it up was easy, but doing the vector calc or whatever turned out tricky.
It's possible to rephrase this as:
At what time(s) is P(t) = P0 + t*v at a distance D from the line segment L((x1,y1), (x2,y2))?
v=(sin(heading), -cos(heading)) in my case.

Shoot mang your solution doesn't always work. I found a counter example:
Line Segment = (0,0) -> (0,14)
Start Point = (19, 6) # heading -159.5 or 200.5 in west/counter-clockwise
It will intersect the line at (2.952, 0.0) so I ask, where does it it come within a distance of 0.0.
The result I get is incorrect.
http://img5.imageshack.us/i/failuref.png/
How I can tell which ones will work using your solution and which ones do not work depends whether the minimum starting distance between the point and the line segment creates a perpendicular line.
If I can post another picture in the next post, I will put the successful example.
I would have liked to post some code for Sage which produced those images, but the code tags are accepting python unfortunately.

A successful result where the minimum starting distance between the point and the line segment is perpendicular to the line segment:
http://img46.imageshack.us/i/success.png/

Hi the solution I eventually came up with.
Does the ray intersect line segments that are parallel and the specified distance D away from the line segment. Just drawing a rectangle and checking the sides parallel to the line segment.
Does the ray intersect circles of radius D at each end point of the line segment.
Minimize for total unit time to find the first point along the ray that is D away from the line segment.
Possible Border case: Is the start point within D and heads away from the line? Up to the user how to handle this case.

Thanks, that works.
I found the alpha this way:
heading = 45.0*pi/180. #heading 45 degrees.
if x1 > x2: #line segment (x1,y1)<->(x2,y2)
dx = x2 - x1
dy = y2 - y1
else:
dx = x1 - x2
dy = y1 - y2
segmentHeading = atan2(dx, dy)
if heading > 0:
alpha = segmentHeading + heading
else:
alpha = -segmentHeading + heading
t = abs( (dStart - D) / -cos(alpha) ) #-cos in python, sin in C.

Related

Finding the number of times a line will intersect with other lines on the plot

Using
plt.plot(x[i:i+2], y[i:i+2], 'ro-')
to create some line segments:
If one plots x = 0.6, is there a matplotlib built in method of finding the number of times it will intersect with lines that have already been plotted on the graph?
For a given segment where you know x[2i] and x[2i+1], you have an intersection if your given x falls in between. The best way to check is to compute (x-x[2*i])*(x-x[2*i+1]). If less than zero, you have an intersection. If equal to zero, one of the end points is on your x=0.6 line. If greater than zero it means that the ends of the segment are on the same side of the line, so no intersection.
To program this, assuming that x is a numpy array
prod=(0.6-x[::2])*(0.6-x[1::2])
And the number of intersections is len(numpy.where(prod>=0)[0])

Calculate radius and remove GPS coordinates

I have a question about how to remove some "unnecessary" coordinates from a "maps.txt" file using segment line, projection vector or other method.
Path Created on Google Maps:
Map1
Total of 275 coordinates, extracted from the ".KML" file of Google Maps.
Map1_2
Map2
When I do it manually it stays that way (Map2), with 9 coordinates.
I have a file called "maps.txt" where its lines, with coordinates, are in this format:
Obs: A coordinate on each line: latitude, longitude.
-37.2012600, -59.8404600
-37.2000200, -59.8419600
-37.1985300, -59.8439200
-37.1970600, -59.8458500
-37.1959100, -59.8473500
-37.1957800, -59.8475200
-37.1948600, -59.8486900
-37.1939500, -59.8498600
-37.1931400, -59.8509400
-37.1928400, -59.8513100
-37.1926700, -59.8515000
-37.1924600, -59.8517200
-37.1922600, -59.8519200
Is there any way for a code to read my file "maps.txt" and do the line segment, vector projection, point distance calculation using a radius of 100 meters?
In case the code would "remove the line / unnecessary coordinate" from the file "maps.txt", leaving it this way (just an example):
-37.2012600, -59.8404600
-37.1948600, -59.8486900
-37.1922600, -59.8519200
In Python, C, C ++ or another language.
I hope I have been clear and thank you in advance for any help.
Thank you (:
I'll try to explain better.
In the following figure I have 3 coordinates (1, 2 and 3).
The coordinate "1" has a radius within 100m with respect to the "2" coordinate, but from "1" to "3" I have a value greater than 100m, ie in this case the coordinate "1", "2" "and" 3 "in my text file" maps.txt ".
Example1
In the following figure from example 2, I would need only the coordinates "1" and "3" in the file "maps.txt".
Example2
Update:
Here's a script that converts KML to GPX: https://gist.github.com/timabell/8791116
And here's a Python script that seems like it'll do what you want (for GPX files): https://wiki.openstreetmap.org/wiki/User:Travelling_salesman/gpx_reduce
Previous answer:
I don't know how far you're asking us to take our answers; this problem is slightly complex, so here's some pseudocode for starters:
Overall algorithm:
Vector from point 1 to 3. Check distance of point 2 from this vector. (Assuming threshold is okay)
Vector from point 1 to 4. Check distance of points 2 and 3 from this vector. (Assuming threshold is okay)
Vector from point 1 to 5. Check distance of points 2, 3, and 4 from this vector. (Assuming threshold is bad)
First vector is determined: it's from point 1 to 4. Second vector starts at point 4.
Vector from point 4 to 6. Check distance of point 5 from this vector.
Vector from point 4 to 7. Check distance of points 5 and 6 from this vector.
...
Distance of point from vector:
At this point, we need to make a decision:
If we want this to be (quite) exact, we have to find a line that is perpendicular to our line and goes through this point, and find the intersection of these two lines. Then, we calculate the distance using the haversine formula between the intersection and the point. (Unless we sometimes have longer distances between coordinates, I don't think we need this.)
If we don't care too much about exactness, we use the following formula to calculate the "distance", and then "experimentally" find a good threshold value that works for us. (This threshold value is just some float number that we use when checking the distance. If it's above the threshold value, we start a new line.)
https://en.wikipedia.org/wiki/Distance_from_a_point_to_a_line#Line_defined_by_two_points
(Where (x0, y0) is the point we're investigating, and the line goes through (x1, y1) and (x2, y2).)

How to find the point of collision between an irregular shape (built out of 3 circles) and a line

I'm making a program in which many weird shapes are drawn onto a canvas. Right now i'm trying to implement the last, and possebly hardest, one.
In this particular shape i need a way to find the location (on a 2d canvas) where the line hits the shape. The following image is an example of what i have right now.
The black dots are the points that a known to me (i also have the location of the center of the three open circles and the radius of these circles). Each of the three outer lines needs a line towards the center dot, ending at the point that it hits the circle. This shape can be turned 90, 180 or 270 degrees.
The shape should look something like the following:
If you need any other information, please ask me in the comments. I'm not very good at math so please be gentle, thanks!
If A and B are points forming a line, then you can describe any point on that line using coordinates:
x = t·Ax + (1−t)·Bx
y = t·Ay + (1−t)·By
0 ≤ t ≤ 1
You can also describe the circle with center M and radius r as
(x − Mx)2 + (y − My)2 = r2
So take the x and y from the equations of the line, and plug them into the equation of the circle. You obtain a quadratic equation in t. Its two solutions describe the two points of intersection between the line and circle. In your example, only one of them lies on the line segment, i.e. satisfies 0 ≤ t ≤ 1. The other describes a point on the extension of the segment past its endpoint. Take the correct value for t back to the equations of the line, and you obtain the x and y coordinates of the point of intersection.
If you don't know up front which circle you want to intersect with a given line, then intersect all three and choose the most appropriate point afterwards. Probably that is the point closest to the outside starting point of the line segment. The same goes in cases where both points of intersection lie on the segment.

Objective C Game Geometry question

I'm creating simple game and reached the point where I feel helpless. I was good in geometry but it was long time back in school, now trying to refresh my mind.
Let's say i have iPad screen. Object's xy position at one given point of time and xy position at another point of time stored in 2 variables .
Question:
how to find the third position of the object at the end of the screen being given previous 2 position, considering the object moves in the same direction (line) from point 1 to point 2.
Thanks in advance.
Let us have that v1 and v2 are the vectors representing the two points. Let t0 be the time between the two points. Let t be the current time.
Then our location vector v3 is given by v3 = v1 + (v2 - v1)t/t0
If the object is moving in the same direction and you have an horizontal line, the next position given x and y would be
x+1, y
If the object is moving in the same direction in a vertical line it would be
x, y+1
If the object is moving in a diagonal up-right
x+1,y+1
diagonal down-right
x+1, y+1
diagonal down-left
x-1, y-1
diagonal up-left
x-1, y+1
So something general would be :
newPosition = (x+1,y) //if you wish to move forward to the right, try to handle all
cases
All the cases above work if the object is moving forward, if it is moving backwards just change the + by - . Basically think of the object as moving in a cartesian coordinate system, where x is horizontal and y is vertical.
I think you can get the idea out of this three cases ;)

Placement of "good" control points in Bezier curves

I've been working on this problem for awhile now, and haven't been able to come up with a good solution thusfar.
The problem: I have an ordered list of three (or more) 2D points, and I want to stroke through these with a cubic Bezier curve, in such a way that it "looks good." The "looks good" part is pretty simple: I just want the wedge at the second point smoothed out (so, for example, the curve doesn't double-back on itself). So given three points, where should one place the two control points that would surround the second point in the triplet when drawing the curve.
My solution so far is as follows, but is incomplete. The idea might also help communicate the look that I'm after.
Given three points, (x1,y1), (x2,y2), (x3,y3). Take the circle inscribed by each triplet of points (if they are collinear, we just draw a straight line between them and move on). Take the line tangent to this circle at point (x2,y2) -- we will place the control points that surround (x2,y2) on this tangent line.
It's the last part that I'm stuck on. The problem I'm having is finding a way to place the two control points on this tangent line -- I have a good enough heuristic on how far from (x2,y2) on this line they should be, but of course, there are two points on this line that are that distance away. If we compute the one in the "wrong" direction, the curve loops around on itself.
To find the center of the circle described by the three points (if any of the points have the same x value, simply reorder the points in the calculation below):
double ma = (point2.y - point1.y) / (point2.x - point1.x);
double mb = (point3.y - point2.y) / (point3.x - point2.x);
CGPoint c; // Center of a circle passing through all three points.
c.x = (((ma * mb * (point1.y - point3.y)) + (mb * (point1.x + point2.x)) - (ma * (point2.x + point3.x))) / (2 * (mb - ma)));
c.y = (((-1 / ma) * (c.x - ((point1.x + point2.x) / 2))) + ((point1.y + point2.y) / 2));
Then, to find the points on the tangent line, in this case, finding the control point for the curve going from point2 to point3:
double d = ...; // distance we want the point. Based on the distance between
// point2 and point3.
// mc: Slope of the line perpendicular to the line between
// point2 and c.
double mc = - (c.x - point2.x) / (c.y - point2.y);
CGPoint tp; // point on the tangent line
double c = point2.y - mc * point2.x; // c == y intercept
tp.x = ???; // can't figure this out, the question is whether it should be
// less than point2.x, or greater than?
tp.y = mc * tp.x + c;
// then, compute a point cp that is distance d from point2 going in the direction
// of tp.
It sounds like you might need to figure out the direction the curve is going, in order to set the tangent points so that it won't double back on itself. From what I understand, it would be simply finding out the direction from (x1, y1) to (x2, y2), and then travelling on the tangent line your heuristic distance in the direction closest to the (x1, y1) -> (x2, y2) direction, and plopping the tangent point there.
If you're really confident that you have a good way of choosing how far along the tangent line your points should be, and you only need to decide which side to put each one on, then I would suggest that you look once again at that circle to which the line is tangent. You've got z1,z2,z3 in that order on the circle; imagine going around the circle from z2 towards z1, but go along the tangent line instead; that's which side the control point "before z2" should be; the control point "after z2" should be on the other side.
Note that this guarantees always to put the two control points on opposite sides of z2, which is important. (Also: you probably want them to be the same distance from z2, because otherwise you'll get a discontinuity at z2 in, er, the second derivative of your curve, which is likely to look a bit suboptimal.) I bet there will still be pathological cases.
If you don't mind a fair bit of code complexity, there's a sophisticated and very effective algorithm for exactly your problem (and more) in Don Knuth's METAFONT program (whose main purpose is drawing fonts). The algorithm is due to John Hobby. You can find a detailed explanation, and working code, in METAFONT or, perhaps better, the closely related METAPOST (which generates PostScript output instead of huge bitmaps).
Pointing you at it is a bit tricky, though, because METAFONT and METAPOST are "literate programs", which means that their source code and documentation consist of a kind of hybrid of Pascal code (for METAFONT) or C code (for METAPOST) and TeX markup. There are programs that will turn this into a beautifully typeset document, but so far as I know no one has put the result on the web anywhere. So here's a link to the source code, which you may or may not find entirely incomprehensible: http://foundry.supelec.fr/gf/project/metapost/scmsvn/?action=browse&path=%2Ftrunk%2Fsource%2Ftexk%2Fweb2c%2Fmplibdir%2Fmp.w&view=markup -- in which you should search for "Choosing control points".
(The beautifully-typeset document for METAFONT is available as a properly bound book under the title "METAFONT: the program". But it costs actual money, and the code is in Pascal.)