How to calculate the trajectory of a parabola on GoogleEarthPro given 3 geocoordinates? - curve-fitting

I am not a coder, I apologize, but I have attempted to solve this on my own but am confused as geocoordinates are given in (Latitude, Longitude) which seems to imply I need to input the coordinates as [y,x] into online 3 point conversion calculator to identify the parabolic equation (ex., y = ax^2 + bx = c). I have 2 confirmed points (41.8794 N, 87.6238 W), (46.7988 N, 71.2247 W) and educated guess for third point (39.8259 N, 86.1858 W). I need to see at what point the parabola would cross New Zealand or Australia with these given points or plotting for corrected 3rd point at a later time. Thanks Everybody!
Even better if someone knows an application to Google Earth Pro that lay person can use.

Related

Fast Integer Coordinates Inside/along a Circle Centered at origin with radius r

Consider that you have a circle centered at 0,0 with radius r.
I'd like to get all the integer points available that are inside this circle. This problem is easy to solve.
One may just iterate over a square from x = -r to +r and y =-r to +r and see if x * x + y * y <= r * r, if so, add the point to your result.
However, what's the quickest way to do this? I feel there should be some type of hack that we can take the calculations from (2r)^2 to 4/3 r^2
More particularly, I have a feeling that we can calculate the length of the inscribed square, then add the outer remaining components. I'm unsure of how to do this though. The math is a little dense. I'm refraining from posting code because I'd like a general algorithm response, but if one has preference, he may state the final benchmark that this will be used in should use a JVM language.
Any help?
Note: this is similar to the gauss's circle problem, but instead of counting the number of points, I want to know what the points are.
You can get the values directly by computing the maximum y (the second coordinate of the point on the circle at the vertical of (x,0)) for each value of x like that:
for x in [-floor(r), floor(r)]
y_max = floor(sqrt(r^2 - x^2)) # Pythagora's theorem
for y in [-y_max, y_max]
# (x, y) is good !
I don't think you can do much better (maybe you can compute y_max faster but that won't be a big win) because anyway you have these points in the result.
EDIT:
This is in Pi*r^2 time, which is the least you can do since it's the number of points.
You can maybe save a few computations by doing only a quarter circle and getting the other ones by symmetry, but I'm not even sure it's faster, and it's certainly longer to write.

Distance from a point to a polygon

I am trying to determine the distance from a point to a polygon in 2D space. The point can be inside or outside the polygon; The polygon can be convex or concave.
If the point is within the polygon or outside the polygon with a distance smaller than a user-defined constant d, the procedure should return True; False otherwise.
I have found a similar question: Distance from a point to a polyhedron or to a polygon. However, the space is 2D in my case and the polygon can be concave, so it's somehow different from that one.
I suppose there should be a method simpler than offsetting the polygon by d and determining it's inside or outside the polygon.
Any algorithm, code, or hints for me to google around would be appreciated.
Your best bet is to iterate over all the lines and find the minimum distance from a point to a line segment.
To find the distance from a point to a line segment, you first find the distance from a point to a line by picking arbitrary points P1 and P2 on the line (it might be wise to use your endpoints). Then take the vector from P1 to your point P0 and find (P2-P1) . (P0 - P1) where . is the dot product. Divide this value by ||P2-P1||^2 and get a value r.
Now if you picked P1 and P2 as your points, you can simply check if r is between 0 and 1. If r is greater than 1, then P2 is the closest point, so your distance is ||P0-P2||. If r is less than 0, then P1 is the closest point, so your distance is ||P0-P1||.
If 0<r<1, then your distance is sqrt(||P0-P1||^2 - (r * ||P2-P1||)^2)
The pseudocode is as follows:
for p1, p2 in vertices:
var r = dotProduct(vector(p2 - p1), vector(x - p1))
//x is the point you're looking for
r /= (magnitude(vector(p2 - p1)) ** 2)
if r < 0:
var dist = magnitude(vector(x - p1))
else if r > 1:
dist = magnitude(vector(p2 - x))
else:
dist = sqrt(magnitude(vector(x - p1)) ^ 2 - (r * magnitude(vector(p2-p1))) ^ 2)
minDist = min(dist,minDist)
In the event that this helps someone else, I reverse engineered doverbin's answer to understand why it worked showing graphically what the three cases are computing. (doverbin, feel free to incorporate this into your answer if you wish.)
If you have a working point to line segment distance function, you can use it to calculate the distance from the point to each of the edges of the polygon. Of course, you have to check if the point is inside the polygon first.
Do you need fast or simple?
Does it have to be always absolutely correct in edge cases or will good enough most of the time be OK?
Typical solution are to find the distance to each vertex and find the pair with the smallest values ( note that for a point outside a convex polygon these might not be adjacent) and then check point to line intersections for each segment.
For large complex shapes you can also store approx polygon bounding boxes (either rectangular or hexagons) and find the closest side before checking more detail.
You may also need code to handle the special case of exactly on a line.
I can help you with this pointers:
The distance can be calculated using Wikipedia entry, even with an untested snipped of code.
The inside/outside border can be solved with this Stack Post and links
and some remarks:
you should check only the nearest points, as Martin Beckett´s answer point outs, since another segment can "proyected" very near, but in reality don´t be close as need.
I do not know about the difference in performance with respect to the rest of answers, but in boost C++ libraries there is an generic implementation called distance. It has information about complexity in every case and in your problem case it is linear.
I was also looking for solutions to this problem some days ago and I want to share this finding. Hope it helps to someone.

Gradient Of Bezier Curve At Given Point

I cant seem to figure out how to calculate the incline of a curve for the following situation...
Essentially what I am trying to do is increase the speed of an object based on the incline of the curve at a particular point. The speed will be reduced if the incline is upwards and increase if downward.
I was using the derivative of a point t on the bezier curve to establish the tangent but this doesnt seem to be right as I would expect that value to be negative if the slope is downward.
I have been using the below equation for the tangent to evaluate X, Y and Z but then I only use Y to establish the incline...I think that step may be wrong
Any ideas?
EDIT:
Ultimately this is an object moving along an inclined plane but I cant establish the angle of the plane in order to do this, I believe if I could correctly find the angle it may solve the problem. I tried to take the point in question and then another point in front (so for example t = 0.5 and then a point in front would be t=0.51) and then calculate the angle using tan. I completely ignore the Z axis but is that wrong? If not how should I calculate the angle?
Thanks a lot
This should help: http://www.physicsclassroom.com/Class/vectors/U3L3e.cfm .
Essentially, you need to calculate the angle of inclination. If the angle is \theta , then the acceleration depends on sin(\theta).
I am assuming z as the vertical dimension.
if dx,dy and dz is are the gradients in each directions, dw = sqrt( dx^2+dy^2). \theta = tan_inverse( dz/dw). Acceleration = g*sin(\theta).
NOTE: You can directly calculate sin(\theta) without explicitly calculating \theta. sin(\theta) = dz/sqrt(dx^2+dy^2+dz^2).
=== More formal description ===
Let x be the east-west dimension, y be the north-south dimension and z be the up-down dimension.
Let z = F(x,y) give the elevation of the terrain at any given location x,y.
Calculate dz/dx = fx(x,y) and dz/dy = fy(x,y), the partial derivatives of z w.r.t to x and y.
Now, sin(\theta) = dz/sqrt(dx^2+dy^2+dz^2) = 1/(sqrt( (dx/dz)^2+ (dy/dz)^2 )= 1/(sqrt( (1/fx(x,y))^2, (1/fy(x,y))^2 ).
This is how you calculate sin(\theta).
The value of derivation is negative when the slope is "downward". And yes, the derivation is the tangent of the slope angle. Only you should pay attention to the directions. They can change the sign, of course. Only you should take dy/dx, not dy/something else. That is all on 2d curves.
You mention Z in the last paragraph. You curve is 3D? Then, of course, the term "derivation" should be put more precisely. Derivation of what to what do you need? The second idea is - please, explain better, what do you want. BTW, maybe after you write down the task correctly, you'll see the solution as obvious.
If it is 3D, let us say, you have your curve as 3 functions of x(t), y(t), z(t). then you need dz/dq, where dq= dt*sqrt((dx/dt)^2+(dy/dt)^2). Obviously, isn't it?
As I said, no maths here. Merely Pythagor's theorem and proportions. (I take z as height)
Addition: it can be rerecounted as tan(a)=dz/(dt*sqrt((dx/dt)^2+(dy/dt)^2)) => tan(a)=(dz/dt)/sqrt((dx/dt)^2+(dy/dt)^2)) ==> a=ATAN((dz/dt)/sqrt((dx/dt)^2+(dy/dt)^2)). But look out for directions you are moving! They can reverse the sign. For under sqrt(^2+^2) we have lost the direction of the dt proection.

Computing an angle from x,y coordinates [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Circle line collision detection
I'm trying to do collision testing between a finite line segment, and an arc segment. I have a collision test which does line segment vs. line segment, so I was going to approximate these arc segments with line segments and run my existing test.
The data I have defining the arc segment(s) are three points. Two of which are endpoints that lie on the circumference of a circle, and the third point is the center of that circle.
So far this is what I've got:
Let (a,b) be the center point of the circle, let 'r' be the radius of the circle, and (x1, y1), (x2, y2) be the endpoints of the arc segment which lies on the circumference of the circle.
The following parametric equations give the x, and y locations of an arc. 't' is the parametric variable.
x = a + r * cos(t)
y = b + r * sin(t)
To create the line segments from the arc, I wanted to walk the arc for some fixed ratio of 't' creating line segments along the way, until I've reached the end of the arc. To do this I figured I'd have to find the start and end angle. I'd start walking the arc from the start angle, and end at the end angle. Since I know the start and end points I figured I could use these equations to solve for these angles. The following are my equations for this:
t = arccos((x-a)/r)
or
t = acrcsin((y-b)/r)
The problem I'm having is that the range of values returned by these functions (http://en.wikipedia.org/wiki/Inverse_trigonometric_function) is limited, so there is a high probability that the angle I'm looking for will not be returned because these functions are multivalued: arcsin(0) = 0, but also arcsin(0) = π, arcsin(0) = 2π, etc
How do I get the exact angle(s) I'm looking for? Or, can you think of a better/different way of achieving my goal?
Take a look at the atan2 function, which should exist in whatever programming language or math library you're using. It takes two arguments, the x and y coordinates of a point (for you: (x-a)/r and (y-b)/r) and returns the angle in the range -π to +π.
At least IMO, you're going at this the wrong way. A line has an equation y=mx+b. A circle has an equation x2 + y2 = r2. You're looking for a point at which the x and y of the circle equals the x and y of the line. You can do that by substituting the mx+b equation for the line for the y equation in the circle, and then solve using the quadratic equation.
The equations involved do get a bit long, but quite a few web pages (e.g., http://www.sonoma.edu/users/w/wilsonst/papers/geometry/circles/default.html) have them, at which point it's simple matter of implementing the equations as a couple of functions and plugging in the values for your particular circle/line. A solution based on these equations complete avoids the ambiguity from using an arg tangent.
Your pseudo-code looks a lot like Python. If you don't mind using Python I would recommend the Shapely Library. If you just want the algorithm, check the source.
Shapely objects have the 'simplify' and 'intersection' methods.

Given two lines on a plane, how to find integer points closest to their intersection?

I can't solve it:
You are given 8 integers:
A, B, C representing a line on a plane with equation Ax + By = C
a, b, c representing another line
x, y representing a point on a plane
The two lines are not parallel therefore divide plane into 4 pieces.
Point (x, y) lies inside of one these pieces.
Problem:
Write a fast algorithm that will find a point with integer coordinates in the same piece as (x,y) that is closest to the cross point of the two given lines.
Note:
This is not a homework, this is old Euler-type task that I have absolutely no idea how to approach.
Update:
You can assume that the 8 numbers on input are 32-bit signed integers.
But you cannot assume that the solution will be 32 bit.
Update 2:
Difficult case - when lines are almost parallel - is the heart of the problem
Update 3:
Author of the problem states that the solution is linear O(n) algorithm. Where n is the size of the input (in bits). Ie: n = log(A) + log(B) + ... + log(y)
But I still can't solve it.
Please state complexities of published algorithms (even if they are exponential).
alt text http://imagebin.ca/img/yhFOHb.png
Diagram
After you find intersection of lines L1:Ax+By=C and L2:ax+by=c i.e. point A(x1,y1).
Define two more lines y = ceil(y1) and y = floor(y1) parallel to X-axis and find their intersection with L1 and L2 i.e. Points B(x2,y2) and C(x3,y3).
Then point you require is D or E whichever is closer to point A. Similar procedure applies to other parts of the plane.
D ( ceil(x2), ceil(y1) )
E ( ceil(x3), floor(y1) )
This problem falls into the category of Integer Convex Optimization.
Presented here is a mathematical way to approach the problem. I don't expect you to actually use it - a lot of complicated techniques are required, and other algorithmic approaches (such as "searching" for the appropriate point) will likely do just fine. However, interest has been expressed in the "true" solution, so here it is.
It can be solved in three stages:
First, determine which side of each line the answer will be on, as illustrated by TheMachineCharmer's answer.
Once that is known, the problem can be rewritten as a convex optimization problem (see Wikipedia for details). The function to be optimized is minimizing (x - x0)^2 + (y - y0)^2, with x0 and y0 the coordinates of the intersection of the two lines. The two lines each become a linear inequality, e.g. "x+y >= 0", together forming the convex region the answer can be found in. I will note that the solution will be (x=x0, y=y0) - what you need from this stage a way of expressing the problem, analagous to a feasible tableau for the simplex method.
Third, an integer solution can be found by repeatedly adding cuts to further constrain the feasible region until the solution to the convex optimization problem is integral. This stage may take a lot of iterations in the general case, but looking at the problem presented, and in particular the 2D nature of it, I believe it will be solved with at most two cuts.
I show here how a "difficult" instance of this problem can be solved. I think this method can be generalized. I have put another simpler instance in the comments of the original post.
Consider the two lines:
10000019 * X - 10000015 * Y + 909093 >= 0 (L1)
-10000022 * X + 10000018 * Y + 1428574 >= 0 (L2)
A = 10000019, B = -10000015, C = -909093
The intersection point is H:
Hx = -5844176948071/3, Hy = -5844179285738/3
For a point M(X,Y), the squared distance HM^2 is:
HM^2 = (9*X^2+35065061688426*X
+68308835724213587680825685
+9*Y^2+35065075714428*Y)/9
g = gcd(A,B) = 1: the equation of L1 A*X+B*Y+909093
can take any integer value.
Bezout coefficients, U=2500004 and V=2500005 verify:
A * U + B * V = 1
We now rewrite the problem in the "dual" basis (K,T) defined by:
X = T*U - K*B
Y = T*V + K*A
After substitution, we get:
T+909093 >= 0
2*T+12*K+1428574 >= 0
minimize 112500405000369*T^2
+900003150002790*T*K
+1800006120005274*K^2
+175325659092760325844*T
+701302566240903900522*K
+Constant
After further translating (first on T, then on K to minimize the
constant in the second equation), T=T1-909093, K=K1+32468:
T1 >= 0
2*T1+4+12*K1 >= 0
minimize 112500405000369*T1^2
+300001050000930*T1
+900003150002790*T1*K1
+1200004080003516*K1
+1800006120005274*K1^2
+Constant
The algorithm I proposed is to loop on T1. Actually, we don't need to
loop here, since the best result is given by T1=K1=0, corresponding to:
X = -1948055649352, Y = -1948056428573
My initial post below.
Here is another idea of algorithm. It may work, but I did not implement it...
With appropriate change of signs to match the position of (x,y), the problem can be written:
A*X+B*Y>=C (line D)
a*X+b*Y>=c (line d)
minimize the distance between M(X,Y) and H, the intersection point
A*b != a*B (intersection is defined)
A,B,C,a,b,c,X,Y all integers
The set of all values reached by (AX+BY) is the set of all multiples of g=gcd(A,B), and there exist integers (u,v) such that Au+Bv=g (Bezout theorem). From a point with integer coordinates (X0,Y0), all points with integer coordinates and the same value of AX+BY are (X0-KB/g,Y0+KA/g), for all integers K.
To solve the problem, we can loop on lines parallel to D at increasing distance from H, and containing points with integer coordinates.
Compute g,u,v, and H (the coordinates of H are probably not needed, we only need the coefficients of the quadratic form corresponding to the distance).
T0 = ceil(C/g)
Loop from T = T0
a. Find K the smallest (or largest, depending on the sign of aB-bA) integer verifying a*(Tu-KB/g)+b*(Tv+KA/g)>=c
b. Keep point (Tu-KB/g,Tv+KA/g) if closer to H
c. Exit the loop when (T-T0) corresponds to a distance from D larger than the best result so far, otherwise continue with T+=1
I have researched the problem in the past (both because it's fun and because I ran into something related at a place where I worked).
To my knowledge, there is no efficient (FPTIME) algorithm for this problem.
The only known (to me) solution is to basically enumerate integer coordinates (starting from around the intersection) until you find the one you want. This is of course not at all efficient when the angle between the two lines is very small. You can do some pruning to improve efficiency and, when the slope is small, efficiency is decent.
A generalization of this (ILP - integer linear programming) is known to be NP-complete.
The more I think about this, the more it seems like it turns into Integer Linear Programming, which is NP-complete in the general case. http://en.wikipedia.org/wiki/Linear_programming#Integer_unknowns
My line of reasoning started out like TheMachineCharmer's answer until I reached that point. The problem there is that the approach of examining the lines along the ceil/floor of the point of intersection only works if the section is aligned with the vertical or horizontal axis though the intersection point. More likely, the thin section will be inclined at some angle away from the axis and the ceil/floor neighbors will not intersect the section on integer coordinates.
At that point we're looking for some integer combination of the natural unit vectors that satisfies the inequalities that define our selected section and also minimizes the distance to the point of intersection. To me, that seems like an integer linear programming problem.
There are special cases of integer linear programming that are easier than NP-hard and this problem could easily be one of them since it seems like its more constrained than the general linear programming case. The Wikipedia article links to a few methods, but that's beyond my math level to apply.
As a few others have pointed out, this is a problem in integer linear programming (aka linear Diophantine inequalities).
Check out this reference: ABS Algorithm For Solving a Class Of Linear Diophantine Inequalities and Integer LP Problems. The authors claim to be able to solve systems like
max(cTx) for Ax≤b, x∈Zn, where c∈Zn, b∈Zm, A∈Zm,n, m≤n.
In particular, setting m=2, n=2, we get the problem of finding
max(cTx) for Ax ≤ b, x∈Z2, where c∈Z2, b∈Z2, A∈Z2,2.
Here, A is a 2x2 matrix, and b, c and x are 2x1 column vectors.
The problem stated by the OP can be restated in this fashion (if asked, I'll try to spell this out in more detail).
The matrix algorithm presented in the paper may look hairy to the uninitiated, but matrix algorithms are like that. Not that I've gone through it line by line, or understand it, but it looks pretty tame compared to some stuff I've seen.
This seems to be something in the general class of ABS methods, which appear to be gaining traction in several problem domains.
The last sentence of section 2 of the paper also refers to another solution method.
As #Alan points out, whereas the general ILP problem is NP-Hard, the problem stated here may not be. I'm not sure why that is, but it may be because the matrix A is 2x2 (rather than nx2), and because the constraints can be expressed as integers.
Edit1: the complexity of the algorithm appears to be O(1) (It appears to be O(d), where d is the dimension of the lattice. In this case, d=2). My surprise at this is O(!!) and understanding and implementing this is still O(??), although I've gone through it a few times now and it is looking more straightforward than I thought.
Here's a partial idea which may be useful in getting a full solution. Imagine the two lines are very, very close to each other. Then any integral solution between them would also be an integral point which is very close to each line. Let's try to find close integral points to the line ax+by=c. Since y = (c - ax)/b, we need to have y very close to an integer, so b approximately divides c-ax. In other words, c-ax+D == 0 mod b for a small integer D.
We can solve c-ax+D == 0 mod b for x: x = a^-1(c+D) mod b (a^-1 will exist if a and b are relatively prime, not sure if that is the case here).
So the algorithm is to evaluate x = a^-1(c+D) mod b for D=0,+1,-1,+2,-2,... and try the resulting x's to see if they work. If there are close integral points to the intersection of the two lines, they should show up early in this iteration. Of course, you may have to reach D=b-1 in the worst case...
Actually it may be possible to solve this with a modified Bresenham's line drawing algorithm.
It is usually used to do scan conversion of lines, and only requires increments of some step inside a loop if you know the end points of the line.
Once you have worked out which sector the point is in, move the origin to the intersection keeping note of the non integer error. Work out the slope of the line from the intersection to the bottom line, then do a normal to the horizontal at an integer x value (if the slope is small) or a normal from the y (is the slope is high) and find where it intersects the other axis an an integer point.
You should be able to check each integer step in one axis to determine if the point you are testing is above or between your two lines (make a new vector to that spot from the intersection and determine the slope). If the point is above increment your integer step. Becuse you are testing from the smallest gradient differnece from one of the lines it should be O(n). In Bresenhams algorithm their are 8 sectors not just 4.
You guys are missing the point! haha, sorry, couldn't resist.
Hey, let's imagine a slightly simpler situation.
You've got one line emanating from the origin forming an angle of less than 90 degrees with the x axis. Find the nearest integer point.
The problem with just searching lattice points until you hit one that's in the quadrant we want is that one doesn't know how far out to search. In the case of a very, very acute angle, we could consider a bazillion points before we hit one that's in our region.
Solution:
Solve: (Slope of Line) * Delta(x) = 1.
i.e. Delta(x) = 1/(Slope of Line), is where we start searching. Subject to the constraint Delta(x) > 1.
In other words, we go just far out enough that there must have been at least an integer difference between x and y coordinates.
In our problem we'd have to transform appropriately and tweedle the numbers to give an appropriate error range. Delta(x) >= 2, Delta(x) = 2/(Slope of Line) I think will do it off of the top of my head, but I don't have a pencil.
No?
Well, it depends on what is considered as fast enough.
Let's name the point [x,y] P. Also I'll call points with integer coordinates 'integer points'.
Algorithm I propose:
Find the point Q where these two lines intersect. (Q=[x_q, y_q])
Get the function of the line between Q and P, y=f(x) or inverse x=g(y);
Determine if QP more vertical or horizontal according to its angle. Let's say it's vertical to simplify following solution (if it's horizontal, the axes would simply invert and where I write x it'd be y and vice versa).
Take the first integer coordinate y_1 we get going along the line from Q to P.
Calculate second coordinate of that point: x_1=f(y_1). That point is in our segment.
Find if the surrounding integer points with coordinates [floor(x_1);y_1] and [floor(x_1+1);y1] are in the segment we're interested in.
6.1 If yes, then we iterate through horizontal line x_3=f(y_1) to find the integer point which is still in our segment and has (x_3-x_q) -> min. That point is our answer.
6.2 If not, then increment y_1 by one and repeat from step 5.
I think there are 3 pieces to this.
calculate the intersection of the 2 lines, and hold on to the X and Y coordinates of that point
find the section that the given point is in. This should be easy enough, because you have the slope of the 2 lines, and the slope of the line created by the given point and the point of intersection. Call them m_line1, m_line2 and m_intersect. If m_intersect There's a formula to figure out the section using these values and the location of the given point.
find the closest integer. There is also a straightforward calculation of this once you know the values from #1 above, and the slopes from #2. You can brute-force it, but there is an elegant mathematical solution.
These are the steps I took, at least.
Updated to add more substance
OK, I'll start us off with a discussion on #2.
If you calculate the slope of the given point and the intersection point, then you arrive at m_intersection. This is the slope of a line that passes through the intersection point. Let's assume that m_line1 is the greater of the 2 slopes, so that line1 is "above" line2 as x increases after the intersection. It makes it easier to think about for section names. We'll call section A the section given by the sliver between line1 and line2 for x larger than the intersection coordinate x, and then we'll name the other 3 sections clockwise, so that A and C are opposite each other.
If m_intersection is between m_line1 and m_lin2, then it must be in one of the 2 sections A or C. Which section is a simple test of the x coordinate value against the intersection's x coordinate. We defined A to be the section with greater value. A similar calculation can be made if the slope is outside m_line1 or m_line2.
This gives you the section that your point lies in. All you did was calculate 1 intersection (5 multiplications, 2 divisions and a handful of subtractions if you do it the traditional way), 3 slopes, and then a couple integer comparisons.
Edit #3 - back by (un)popular demand!
So here is how I calculated #3, the closest integer point to the intersection. It may not be the best, but it uses binary search, so it's O(log n) where n is related to the inverse of the difference of the line slopes. The closer they are together, the larger n is.
First, take the difference between the slopes of the two lines. Say it's 1/8. This means that from the point of intersection, you have to go out 8 units along the x axis before you are guaranteed that there is a whole integer on the y axis in between the two lines (it may be on one of the lines). Now, if the intersection itself is not on an integer x coordinate, then you'll need to step out further to guarantee that your starting point is on an integer x coordinate, but it is bounded. If the intersection is at x = 1.2, then in the above example, at worst you'd start at x = 41, then move down ~5 units along the y axis. Choose either the ceil or floor of the y value that you get. It's not terribly critical.
Now that you have a starting point, the closest point can be approximated by binary search. Your new line segment is between the intersection and the starting point, and your units of movement are multiples of that line segment's slope. Calculate the midpoint of the line segment and see if it lies in between the two lines. Add or subtract 1 to it if it is not a direct hit, and if either of those hits, cut the remaining distance in half and do it again. Otherwise search the further half of the segment.
If you don't have a slope difference < 1, I think the problem may be simpler (brute force the space around the intersection). But it's just a special case of the search above, where you don't need to step out that far to find a starting point.
I was doing something similar when I had to find a point for labeling of a polygon.
The final result was 70000 polygons in 5 seconds on pentium 3 in Autocad. So that's about 3 seconds if you exclude Autocad.
First you need to find an intersection point.
Next thing you have to find where your point (x, y) lies and draw a horizontal or vertical line through it, so that your 2 lines (A, B, C) and (a, b, c) and a new horizontal/verical line form a triangle.
How to find if it's vertical or horizontal line:
Draw both horizontal and vertical lines through your (x, y) point and then check:
-for horizontal:
- if intersections for line A,B,C and your horizontal line and line a,b,c make this equation work (intersection with A,B,C).x < x < (intersection with a,b,c).x, then you know your inside. (you can switch A,B,C and a,b,c, just as long x is inside.
- similar for y, just check for y and not x.
So now you have a triangle and you know where it is (left, right, up, down).
for example if it's a right triangle (like the graph above). You take the x of intersection point and you ceil it (if it's on the left you floor it)..similar for y coordinate if you have up/down triangle.
Then you draw a scanline through it, that's paralel to your scanline through your (x,y) point and check if you have a point inside of the intersections (similar to x < x < x above, but with a new line).
If you don't have an integer inside, then you have to move your ceil point further away from intersection point. You should calculate apropriate 'step' based on the angle between your two lines (if the lines are paralel and very close to each other then the angle will be small, so you have to increse the step, if the angle is wide, small step is required.
When you find a point, it may not be the closest one. So you'll have to do a bisection between the last not good point (when you're increasing step) and the last point (where you found an integer).
The problem of checking whether a point is part of a mathematical cone is fairly simple. Given 2 vectors, v, w, any point in the cone defined by (v, w) will be on the form: z = a***v** + b***w**, where a,b >= 0. Note, for this to work, you will have to move Origo to the intersection of the 2 lines. Since we cannot assume finite precision of the intersection, you will have to do floating point math and decide whether something is close enough to what you want.
Find vectors defining the 4 cones (there's infinitely many of them, we just need 2 for each cone), that are defined by the 2 lines.
Find out which cone contains our point, call that cone for C.
Take the 2 vectors defining C, and find the median vector (the vector that would split C in 2 identical cones), call it m.
Now is time to initiate the loop. For simplicity sake I'm going to assume that we limit ourself to n-bits on the x and y axis. Note you'll need an integer larger than n-bits for the length of m. Now do a binary search along the length of m, and check the 2 rings around every time (I suspect 1 ring around will be enough). When you've found the smallest length that do contain points C, check which of those points are the closest.
The worst case growth would be O(log(sqrt(2*n^2)), where n is the length we use to represent the x and y axis.
It is possible to do a "reverse binary search" so to speak, if you don't know the length of *m. Just keep doubling the the length you go out until you find points in C. Then you know 2 points on m and you can do a binary search between them.
The main problem with all this is precision, so keep this in mind. Alternative ways to pursue could include the 2 halfplanes that make up a cone. Each cone above are defined by the intersection of 2 halfplanes, and it is possible that checking whether a point is member of a halfplane is simple enough, I'm not sure.
Edit: it is indeed a whole lot easier with the half planes, the 2 lines divide R^2 into 2 half planes each, this gives the 4 combinations that would be the 4 cones. So every time you want to check if a point is member of a cone, you have to check if it's a member of the 2 half planes that make up that particular cone. How to do so are explained here:
http://www.mathsteacher.com.au/year9/ch04_linear_graphs/07_half/planes.htm
and would be easier than moving Origo and fiddling around with precision. Replacing the method of checking membership and keeping everything else the same, you arrive at the same growth.
Here is a linear time (i.e., O(# bits of A, B, C, etc.), assuming the bits fit into O(1) words of memory) solution using line-side tests and binary search:
Suppose w.l.o.g. that B != 0 (else we swap A with a, B with b, and C with c). Perform a line-side test to see which side of line (A, B, C) the point is on. Assume w.l.o.g. that the point is below (or on) the line.
Note that for an arbitrary x-coordinate x', we can compute the smallest y' such that (x', y') is above the line (A, B, C) in O(1) time via y' = (C - A * x') / B.
Now, assume w.l.o.g. that the input point (x, y) is to the right of (a, b, c), or below in the case of a horizontal line. We can then perform a line-side test of (x', y') relative to line (a, b, c) and determine whether we need to increase x' or decrease x' to find the minimum x' such that (x', y') falls on the correct side of (a, b, c).
Binary searching for this point takes at most O(w) time where w is the number of bits in A, B, etc. Note that because the input coordinates x and y each fit in an integer, so will the return value. Even if x and y were not necessarily within these bounds and the lines were nearly parallel, a suitable x will be found within O(w) time because the difference in slopes is A / B - a / b = (Ab - aB) / Bb <= 1 / 2^(2w), so the x-coordinate of the answer will fit within O(1) words of memory. We still need to find the y-coordinate of the answer, which can also be found via binary search.
I suspect this is a mathematical optimization problem that can be solved with a Lagrange multiplier...
Of those four pieces of the plane, one is to the left of both lines, one is to the right of both lines, one is to the right of one and to the left of the other line, and the last one is to the left of one and to the right of the other line. It's easier to see if you draw it.
The relative position of a point from a line depends on the result of this determinant:
[1 p1x p1y; 1 p2x p2y; 1 p3x p3y], where p1 and p2 are two arbitrary points in the line and p3 is the given point.
If it equals zero, the point is in the line, if it's greater of lower than zero, it's to a side, the side depends on the relative position of p1 and p2 in the line and what you consider left and right on the plane.
The problem is choosing two points that follow the same criteria in both lines, so that results are consistent, maybe p1 always has lower value of x coordinate than p2 (y coordinate if the line is vertical).
When you have both points for each line, calculate both determinants and you are done.
EDIT
Ups, this solves the problem partially. Anyway you can calculate the side the XY point is in with this, calculate the intersection, and then calucate the relative position of all valid points (floor(x), floor(y)), (floor(x), ciel(y)), ...
line 1 is defined as y1 = m1 * x1 + b1.
line 2 is defined as y2 = m2 * x2 + b2.
m1, m2, b1, b2 are all known values [constants].
make sure m1 <> m2.
find point of intersection, ie where y1 == y2 and x1 == x2 , defined as (X,Y).
Y = ((m1*b2)/m2)/(m1/m2-1)
X = (Y-b1)/m1
the nearest point can be found by rounding X and Y to the nearest integers. you decide what to do with .5
My proposal is this. Assume that the section of the plane which contains our target point spans entirely in lower left quadrant, looking from the cross point of two lines (other quadrants are analogous, and case when section of plane spans more than one quadrant will be considered later).
Let the two given lines be l1 and l2 (l1 is 'less steep' than l2)
find X = (a, b), the cross point of l1 and l2.
let k = 0
let vk be vertical line with the x coordinate xk = floor(a-k)
find cross points of vk with l1 and l2 (points V1 = (x1, y1), V2 = (x2, y2)).
if floor(y1) != floor(y2), target point is (x1, floor(y1)) END.
if floor(y1) == floor(y2), increment k and go to step 3.
Since l1 and l2 are not parallel, abs(y1 - y2) must grow with k. When abs(y1 - y2) gets larger than 1, algorithm will surely stop (it might stop earlier though).
Now let us consider the (easy) case when our section of plane spans more than one quadrant, looking from the cross point of two lines (it may span two or three quadrants).
find X = (a, b), the cross point of l1 and l2.
find A, the set of four closest points to X that have integer coordinates
find B, the set of points from A which are in the target section of the plane.
point from B that is closest to the cross point of l1 and l2 is the target point
(This case runs in constant time.)

Resources