Determining if two line segments intersect? [duplicate] - algorithm

This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
How do you detect where two line segments intersect?
Can someone provide an algorithm or C code for determining if two line segments intersect?

That really depends on how the lines are represented. I'm going to assume that you have them represented in the parametric form
x0(t) = u0 + t v0
x1(t) = u1 + t v1
Here, the x's, u's, and v's are vectors (further denoted in bold) in ℜ2 and t ∈ [0, 1].
These two points intersect if there's some point that's on both of these line segments. Thus if there is some point p so that there's a t where
p = x0(t) = u0 + t v0
and an s such that
p = x1(s) = u1 + s v1
And moreover, both s, t ∈ [0, 1], then the two lines intersect. Otherwise, they do not.
If we combine the two equalities, we get
u0 + t v0 = u1 + s v1
Or, equivalently,
u0 - u1 = s v1 - t v0
u0 = (x00, y00)
u1 = (x10, y10)
v0 = (x01, y01)
v1 = (x11, y11)
If we rewrite the above expression in matrix form, we now have that
| x00 - x10 | | x11 | | x01 |
| y00 - y10 | = | y11 | s - | y01 | t
This is in turn equivalent to the matrix expression
| x00 - x10 | | x11 x01 | | s|
| y00 - y10 | = | y11 y01 | |-t|
Now, we have two cases to consider. First, if this left-hand side is the zero vector, then there's a trivial solution - just set s = t = 0 and the points intersect. Otherwise, there's a unique solution only if the right-hand matrix is invertible. If we let
| x11 x01 |
d = det(| y11 y01 |) = x11 y01 - x01 y11
Then the inverse of the matrix
| x11 x01 |
| y11 y01 |
is given by
| y01 -x01 |
(1/d) | -y11 x11 |
Note that this matrix isn't defined if the determinant is zero, but if that's true it means that the lines are parallel and thus don't intersect.
If the matrix is invertible, then we can solve the above linear system by left-multiplying by this matrix:
| s| | y01 -x01 | | x00 - x10 |
|-t| = (1/d) | -y11 x11 | | y00 - y10 |
| (x00 - x10) y01 - (y00 - y10) x01 |
= (1/d) | -(x00 - x10) y11 + (y00 - y10) x11 |
So this means that
s = (1/d) ((x00 - x10) y01 - (y00 - y10) x01)
t = (1/d) -(-(x00 - x10) y11 + (y00 - y10) x11)
If both of these values are in the range [0, 1], then the two line segments intersect and you can compute the intersection point. Otherwise, they do not intersect. Additionally, if d is zero then the two lines are parallel, which may or may not be of interest to you. Coding this up in C shouldn't be too bad; you just need to make sure to be careful not to divide by zero.
If anyone can double-check the math, that would be great.

You could build an equation for two lines, find the point of intersection and then check if it belongs to those segments.

Related

Algorithm for navigating a matrix

So I have a robot and it has five infrared sensors(leftmost,left-middle,middle,right-middle,rightmost), and I have a 5*5 square matrix that I want my robot to navigate.
The actions my robot can take are:
-Forward(following the line using 3 inner sensors i.e. left-middle, middle, right-middle)
-turnleft
-turnright
-turnaround
I know the initial position of the robot in the grid and it's orientation(the direction it's facing i.e. North, south, east,west).
Now I want to come up with an algorithm such that when the initial position of my robot is (0,0) and orientation is North and then when I give my Robot co-ordinates like (2,1), It should first turnRight, then move two columns to the left and then turnleft and move one column up to reach the co-ordinate (2,1).
Is there an algorithm out there that does this? I came up with an algorithm myself but it is quite lengthy(200+ loc), So I am looking for an efficient algorithm.
P.s.- The robot have no idea where the co-ordinates are in the grid, it only has it's sensors to detect the row and columns and there cross-sections and make decisons based on that. Any help would be appreciated
Let me sumarize:
Your robot can go only in four directions (UP, DOWN, LEFT, RIGHT).
M =
+---------+
| E|
| |
| |
| |
| S |
+---------+
Robot start position is S(0,2)
End position is E(4,4)
There are few paths with the same length from S to E.
+---------+ +---------+ +---------+ +---------+
| E| | E| | E| | E|
| +| | +| | +| | + +|
| +| | +| | + +| | + |
| +| | + +| | + | | + |
| S + +| | S + | | S + | | S + |
+---------+ +---------+ +---------+ +---------+ . . .
The point is that all paths are 5(+1) steps long. So you can easily calculate those:
S = M[0][2] (M[i][j], Si = 0, Sj = 2)
E = M[4][4] (M[i][j], Ei = 4, Ej = 4)
up_or_down = Ei-Si = 4-0 = 4 // sign is positive (so UP)
if (up_or_down > 0) then UP
else DOWN
left_or_right = Ej-Sj = 4-2 = 2 // sign is positive (so RIGHT)
if (left_or_right > 0 then RIGHT
else LEFT
Final path, that your robot should go is:
4xUP
2XRIGHT
Any combination of UP and RIGHT will work.
Optimisation if robot can go diagonally
In our case it would be:
+---------+
| E|
| x|
| x|
| x |
| S |
+---------+
In total it is 3(+1) steps.
With the previous formula we got 4 UPs, and 2 RIGHTs. So we have:
path = 4*U + 2*R
path = U+U+U+U+R+R
// let's combine U and R as much as possible
path = U + R + U + R + U + U
\ / \ / // combine U+R into DUR (diagonal-up-right)
path = DUR + DUR + U + U // it gives us 3(+1) step

Max sum in the vector, according to the condition, which is defined by another vector

I have 2 variables in the data.frame: a, b.
I need to find the max sum of a, where sum of b = x.
Ok, for example:
| a | b |
|401| 2 |
|380| 3 |
|380| 2 |
|370| 1 |
So, for sum(b)=1, max(sum(a)) = 370, for sum(b)=2, max(sum(a))=401 etc.
How can I find a solution to this problem?
Not sure that this problem can be solved using linear programming

Calculating final market distribution - competitive programming

I came across following question while practicing competitive programming. I solved it manually, kinda designing an approach, but my answer is wrong and I cannot imagine how to scale my approach.
Question:
N coffee chains are competing for market share by a fierce advertising battle. each day a percentage of customers will be convinced to switch from one chain to another.
Current market share and daily probability of customer switching is given. If the advertising runs forever, what will be the final distribution of market share?
Assumptions: Total market share is 1.0, probability that a customer switches is independent of other customers and days.
Example: 2 coffee chains: A and B market share of A: 0.4 market share of B: 0.6.
Each day, there is a 0.2 probability that a customer switches from A to B Each day, there is a 0.1 probability that a customer switches from B to A
input: market_share=[0.4,0.6],
switch_prob = [[.8,.2][.1,.9]]
output: [0.3333 0.6667]
Everything till here is part of a question, I did not form the example or assumptions, they were given with the question.
My_attempt: In my understanding, switch probabilities indicate the probability of switching the from A to B.
Hence,
market_share_of_A = current_market_share - lost_customers + gained_customers and
marker_share_of_B = (1 - marker_share_of_A)
iter_1:
lost_customers = 0.4 * 0.8 * 0.2 = 0.064
gained_customers = 0.6 * 0.2 * 0.1 = 0.012
market_share_of_A = 0.4 - 0.064 + 0.012 = 0.348
marker_share_of_B = 1 - 0.348 = 0.652
iter_2:
lost_customers = 0.348 * 0.1 * 0.2 = 0.00696
gained_customers = 0.652 * 0.9 * 0.1 = 0.05868
market_share_of_A = 0.348 - 0.00696 + 0.05868 = 0.39972
marker_share_of_B = 1 - 0.32928 = 0.60028
my answer: [0.39972, 0.60028]
As stated earlier, expected answers are [0.3333 0.6667].
I do not understand where am I wrong? If something is wrong, it has to be my understanding of the question. Please provide your thoughts.
In the example, they demonstrated an easy case that there were only two competitors. What if there are more? Let us say three - A, B, C. I think input has to provide switch probabilities in the form [[0.1, 0.3, 0.6]..] because A can lose its customers to B as well as C and there would be many instances of that. Now, I will have to compute at least two companies market share, third one will be (1-sum_of_all). And while computing B's market share, I will have to compute it's lost customers as well as gained and formula would be (current - lost + gained). Gained will be sum of gain_from_A and gain_from_C. Is this correct?
Following on from my comment, this problem can be expressed as a matrix equation.
The elements of the "transition" matrix, T(i, j) (dimensions N x N) are defined as follows:
i = j (diagonal): the probability of a customer staying with chain i
i != j (off-diagonal): the probability of a customer of chain j transferring to chain i
What is the physical meaning of this matrix? Let the market share state be represented by a vector P(i) of size N, whose i-th value is the market share of chain i. The vector P' = T * P is the next share state after each day.
With that in mind, the equilibrium equation is given by T * P = P, i.e. the final state is invariant under transition T:
| T(1, 1) T(1, 2) T(1, 3) ... T(1, N) | | P(1) | | P(1) |
| T(2, 1) T(2, 2) ... | | P(2) | | P(2) |
| T(3, 1) ... | | P(3) | | P(3) |
| . . | * | . | = | . |
| . . | | . | | . |
| . . | | . | | . |
| T(N, 1) T(N, N) | | P(N) | | P(N) |
However, this is unsolvable by itself - P can only be determined up to a number of ratios between its elements (the technical name for this situation escapes me - as MBo suggests it is due to degeneracy). There is an additional constraint that the shares add up to 1:
P(1) + P(2) + ... P(N) = 1
We can choose an arbitrary share value (say, the Nth one) and replace it with this expression. Multiplying out, the first row of the equation is:
T(1, 1) P(1) + T(1, 2) P(2) + ... T(1, N) (1 - [P(1) + P(2) + ... P(N - 1)]) = P(1)
--> [T(1, 1) - T(1, N) - 1] P(1) + [T(1, 2) - T(1, N)] P(2) + ... "P(N - 1)" = -T(1, N)
The equivalent equation for the second row is:
[T(2, 1) - T(2, N)] P(1) + [T(2, 2) - T(2, N) - 1] P(2) + ... = -T(2, N)
To summarize the general pattern, we define:
A matrix S(i, j) (dimensions [N - 1] x [N - 1]):
- S(i, i) = T(i, i) - T(i, N) - 1
- S(i, j) = T(i, j) - T(i, N) (i != j)
A vector Q(i) of size N - 1 containing the first N - 1 elements of P(i)
A vector R(i) of size N - 1, such that R(i) = -T(i, N)
The equation then becomes S * Q = R:
| S(1, 1) S(1, 2) S(1, 3) ... S(1, N-1) | | Q(1) | | R(1) |
| S(2, 1) S(2, 2) ... | | Q(2) | | R(2) |
| S(3, 1) ... | | Q(3) | | R(3) |
| . . | * | . | = | . |
| . . | | . | | . |
| . . | | . | | . |
| S(N-1, 1) S(N-1, N-1) | | Q(N-1) | | R(N-1) |
Solving the above equation gives Q, which gives the first N - 1 share values (and of course the last one too from the constraint). Methods for doing so include Gaussian elimination and LU decomposition, both of which are more efficient than the naive route of directly computing Q = inv(S) * R.
Note that you can flip the signs in S and R for slightly more convenient evaluation.
The toy example given above turns out to be quite trivial:
| 0.8 0.1 | | P1 | | P1 |
| | * | | = | |
| 0.2 0.9 | | P2 | | P2 |
--> S = | -0.3 |, R = | -0.1 |
--> Q1 = P1 = -1.0 / -0.3 = 0.3333
P2 = 1 - P1 = 0.6667
An example for N = 3:
| 0.1 0.2 0.3 | | -1.2 -0.1 | | -0.3 |
T = | 0.4 0.7 0.3 | --> S = | | , R = | |
| 0.5 0.1 0.4 | | 0.1 -0.6 | | -0.3 |
| 0.205479 |
--> Q = | | , P3 = 0.260274
| 0.534247 |
Please forgive the Robinson Crusoe style formatting - I'll try to write these in LaTeX later for readability.

Solving a constrained system of linear equations

I have a system of equations of the form y=Ax+b where y, x and b are n×1 vectors and A is a n×n (symmetric) matrix.
So here is the wrinkle. Not all of x is unknown. Certain rows of x are specified and the corresponding rows of y are unknown. Below is an example
| 10 | | 5 -2 1 | | * | | -1 |
| * | = | -2 2 0 | | 1 | + | 1 |
| 1 | | 1 0 1 | | * | | 2 |
where * designates unknown quantities.
I have built a solver for problems such as the above in Fortran, but I wanted to know if there is a decent robust solver out-there as part of Lapack or MLK for these types of problems?
My solver is based on a sorting matrix called pivot = [1,3,2] which rearranges the x and y vectors according to known and unknown
| 10 | | 5 1 -2 | | * | | -1 |
| 1 | | 1 1 0 | | * | + | 2 |
| * | | -2 0 2 | | 1 | | 1 |
and the solving using a block matrix solution & LU decomposition
! solves a n×n system of equations where k values are known from the 'x' vector
function solve_linear_system(A,b,x_known,y_known,pivot,n,k) result(x)
use lu
integer(c_int),intent(in) :: n, k, pivot(n)
real(c_double),intent(in) :: A(n,n), b(n), x_known(k), y_known(n-k)
real(c_double) :: x(n), y(n), r(n-k), A1(n-k,n-k), A3(n-k,k), b1(n-k)
integer(c_int) :: i, j, u, code, d, indx(n-k)
u = n-k
!store known `x` and `y` values
x(pivot(u+1:n)) = x_known
y(pivot(1:u)) = y_known
!define block matrices
! |y_known| = | A1 A3 | | * | + |b1|
| | * | = | A3` A2 | | x_known | |b2|
A1 = A(pivot(1:u), pivot(1:u))
A3 = A(pivot(1:u), pivot(u+1:n))
b1 = b(pivot(1:u))
!define new rhs vector
r = y_known -matmul(A3, x_known)-b1
% solve `A1*x=r` with LU decomposition from NR book for 'x'
call ludcmp(A1,u,indx,d,code)
call lubksb(A1,u,indx,r)
% store unknown 'x' values (stored into 'r' by 'lubksb')
x(pivot(1:u)) = r
end function
For the example above the solution is
| 10.0 | | 3.5 |
y = | -4.0 | x = | 1.0 |
| 1.0 | | -4.5 |
PS. The linear systems have typically n<=20 equations.
The problem with only unknowns is a linear least squares problem.
Your a-priori knowledge can be introduced with equality-constraints (fixing some variables), transforming it to an linear equality-constrained least squares problem.
There is indeed an algorithm within lapack solving the latter, called xGGLSE.
Here is some overview.
(It also seems, you need to multiply b with -1 in your case to be compatible with the definition)
Edit: On further inspection, i missed the unknowns within y. Ouch. This is bad.
First, i would rewrite your system into a AX=b form where A and b are known. In your example, and provided that i didn't make any mistakes, it would give :
5 0 1 x1 13
A = 2 1 0 X = x2 and b = 3
1 0 1 x3 -1
Then you can use plenty of methods coming from various libraries, like LAPACK or BLAS depending on the properties of your matrix A (positive-definite ,...). As a starting point, i would suggest a simple method with a direct inversion of the matrix A, especially if your matrix is small. There are also many iterative approach ( Jacobi, Gradients, Gauss seidel ...) that you can use for bigger cases.
Edit : An idea to solve it in 2 steps
First step : You can rewrite your system in 2 subsystem that have X and Y as unknows but dimension are equals to the numbers of unknowns in each vector.
The first subsystem in X will be AX = b which can be solved by direct or iterative methods.
Second step : The second system in Y can be directly resolved once you know X cause Y will be expressed in the form Y = A'X + b'
I think this approach is more general.

Testing for Adjacent Cells In a Multi-level Grid

I'm designing an algorithm to test whether cells on a grid are adjacent or not.
The catch is that the cells are not on a flat grid. They are on a multi-level grid such as the one drawn below.
Level 1 (Top Level)
| - - - - - |
| A | B | C |
| - - - - - |
| D | E | F |
| - - - - - |
| G | H | I |
| - - - - - |
Level 2
| -Block A- | -Block B- |
| 1 | 2 | 3 | 1 | 2 | 3 |
| - - - - - | - - - - - |
| 4 | 5 | 6 | 4 | 5 | 6 | ...
| - - - - - | - - - - - |
| 7 | 8 | 9 | 7 | 8 | 9 |
| - - - - - | - - - - - |
| -Block D- | -Block E- |
| 1 | 2 | 3 | 1 | 2 | 3 |
| - - - - - | - - - - - |
| 4 | 5 | 6 | 4 | 5 | 6 | ...
| - - - - - | - - - - - |
| 7 | 8 | 9 | 7 | 8 | 9 |
| - - - - - | - - - - - |
. .
. .
. .
This diagram is simplified from my actual need but the concept is the same. There is a top level block with many cells within it (level 1). Each block is further subdivided into many more cells (level 2). Those cells are further subdivided into level 3, 4 and 5 for my project but let's just stick to two levels for this question.
I'm receiving inputs for my function in the form of "A8, A9, B7, D3". That's a list of cell Ids where each cell Id has the format (level 1 id)(level 2 id).
Let's start by comparing just 2 cells, A8 and A9. That's easy because they are in the same block.
private static RelativePosition getRelativePositionInTheSameBlock(String v1, String v2) {
RelativePosition relativePosition;
if( v1-v2 == -1 ) {
relativePosition = RelativePosition.LEFT_OF;
}
else if (v1-v2 == 1) {
relativePosition = RelativePosition.RIGHT_OF;
}
else if (v1-v2 == -BLOCK_WIDTH) {
relativePosition = RelativePosition.TOP_OF;
}
else if (v1-v2 == BLOCK_WIDTH) {
relativePosition = RelativePosition.BOTTOM_OF;
}
else {
relativePosition = RelativePosition.NOT_ADJACENT;
}
return relativePosition;
}
An A9 - B7 comparison could be done by checking if A is a multiple of BLOCK_WIDTH and whether B is (A-BLOCK_WIDTH+1).
Either that or just check naively if the A/B pair is 3-1, 6-4 or 9-7 for better readability.
For B7 - D3, they are not adjacent but D3 is adjacent to A9 so I can do a similar adjacency test as above.
So getting away from the little details and focusing on the big picture. Is this really the best way to do it? Keeping in mind the following points:
I actually have 5 levels not 2, so I could potentially get a list like "A8A1A, A8A1B, B1A2A, B1A2B".
Adding a new cell to compare still requires me to compare all the other cells before it (seems like the best I could do for this step
is O(n))
The cells aren't all 3x3 blocks, they're just that way for my example. They could be MxN blocks with different M and N for
different levels.
In my current implementation above, I have separate functions to check adjacency if the cells are in the same blocks, if they are in
separate horizontally adjacent blocks or if they are in separate
vertically adjacent blocks. That means I have to know the position of
the two blocks at the current level before I call one of those
functions for the layer below.
Judging by the complexity of having to deal with mulitple functions for different edge cases at different levels and having 5 levels of nested if statements. I'm wondering if another design is more suitable. Perhaps a more recursive solution, use of other data structures, or perhaps map the entire multi-level grid to a single-level grid (my quick calculations gives me about 700,000+ atomic cell ids). Even if I go that route, mapping from multi-level to single level is a non-trivial task in itself.
I actually have 5 levels not 2, so I could potentially get a list like "A8A1A, A8A1B, B1A2A, B1A2B".
Adding a new cell to compare still requires me to compare all the other cells before it (seems like the best I could do for this step is
O(n))
The cells aren't all 3x3 blocks, they're just that way for my example. They could be MxN blocks with different M and N for different
levels.
I don't see a problem with these points: if a cell is not adjacent at the highest level one then we can stop the computation right there and we don't have to compute adjacency at the lower levels. If there are only five levels then you'll do at most five adjacency computations which should be fine.
In my current implementation above, I have separate functions to check adjacency if the cells are in the same blocks, if they are in separate horizontally adjacent blocks or if they are in separate vertically adjacent blocks. That means I have to know the position of the two blocks at the current level before I call one of those functions for the layer below.
You should try to rewrite this. There should only be two methods: one that computes whether two cells are adjacent and one that computes whether two cells are adjacent at a given level:
RelativePosition isAdjacent(String cell1, String cell2);
RelativePosition isAdjacentAtLevel(String cell1, String cell2, int level);
The method isAdjacent calls the method isAdjacentAtLevel for each of the levels. I'm not sure whether cell1 or cell2 always contain information of all the levels but isAdjacent could analyze the given cell strings and call the appropriate level adjacency checks accordingly. When two cells are not adjacent at a particular level then all deeper levels don't need to be checked.
The method isAdjacentAtLevel should do: lookup M and N for the given level, extract the information from cell1 and cell2 of the given level and perform the adjacency computation. The computation should be the same for each level as each level, on its own, has the same block structure.
Calculate and compare the absolute x and y coordinate for the lowest level.
For the example (assuming int index0 = 0 for A, 1 for B, ... and index1 = 0...8):
int x = (index0 % 3) * 3 + index1 % 3;
int y = (index0 / 3) * 3 + index1 / 3;
In general, given
int[] WIDTHS; // cell width at level i
int[] HEIGHTS; // cell height at level i
// indices: cell index at each level, normalized to 0..WIDTH[i]*HEIGHT[i]-1
int getX (int[] indices) {
int x = 0;
for (int i = 0; i < indices.length; i++) {
x = x * WIDTHS[i] + indices[i] % WIDTHS[i];
}
return x;
}
int getY (int[] indices) {
int y = 0;
for (int i = 0; i < indices.length; i++) {
y = y * HEIGHTS[i] + indices[i] / WIDTHS[i];
}
return x;
}
You can use a space filling curve, for example a peano curve or z morton curve.

Resources