kyle 742
kyle 742

Reputation: 9

How to know if two lines intersect using r? is there an equation to check easily without looking at graph?

This code gets the data needed to make two different lines. I was wondering if there was a way to see if two lines intersected easily.

# generate data
red <- matrix(runif(n = 4, min = 0, max = 1), nrow = 2)# gets the 4 points for the first line
blue <- matrix(runif(n = 4, min = 0, max = 1), nrow = 2)# gets the 4 points for second line

# make a plot
plot(red, col = "red", pch = 16, cex = 2,
     asp = 1, xlim = c(0,1), ylim = c(0,1),
     xlab = "", ylab = "")##plots both points red

abline(v = c(0,1), col = "grey", lty = 2)
abline(h = c(0,1), col = "grey", lty = 2)

segments(red[1,1], red[1,2], red[2,1], red[2,2], lwd = 2, col = "red")#Makes the line segment
points(blue, col = "blue", pch = 16, cex = 2,
     asp = 1, xlim = c(0,1), ylim = c(0,1))# does same thing for blue line
segments(blue[1,1], blue[1,2], blue[2,1], blue[2,2], lwd = 2, col = "blue") 
##makes all of the plots and can see if the plot intersects.`

what The intersected lines look like

Upvotes: 0

Views: 1005

Answers (1)

Allan Cameron
Allan Cameron

Reputation: 173793

Here's a practical answer using simple algebra wrapped up in a function.

The process is to find the slope and y intercept of both lines, and solve simultaneous equations to find the intersection. If both line segments have the same gradient the answer is undefined so return NA.

Return the x, y co-ordinates of the intersection if it is within the x range of one of the line segments, otherwise return NA

check_intersect <- function(mat1, mat2)
{
  dy1 <- mat1[,2][which.max(mat1[,1])] - mat1[,2][which.min(mat1[,1])]
  dy2 <- mat2[,2][which.max(mat2[,1])] - mat2[,2][which.min(mat2[,1])]
  dx1 <- max(mat1[,1]) - min(mat1[,1])
  dx2 <- max(mat2[,1]) - min(mat2[,1])
  m1  <- dy1/dx1
  m2  <- dy2/dx2
  if(m1 == m2) return(NA)
  c1  <- mat1[1, 2] - m1 * mat1[1, 1]
  c2  <- mat2[1, 2] - m2 * mat2[1, 1]
  x   <- (c2 - c1)/(m1 - m2)
  y   <- m1 * x + c1
  if(x > min(mat1[,1]) & x < max(mat1[,1])) 
    return(c(x, y)) 
  else 
    return(NA)
}

Now test this with a reprex:

set.seed(123)

red <- matrix(runif(n = 4, min = 0, max = 1), nrow = 2)# gets the 4 points for the first line
blue <- matrix(runif(n = 4, min = 0, max = 1), nrow = 2)# gets the 4 points for second line

# make a plot
plot(red, col = "red", pch = 16, cex = 2,
     asp = 1, xlim = c(0,1), ylim = c(0,1),
     xlab = "", ylab = "")##plots both points red

abline(v = c(0,1), col = "grey", lty = 2)
abline(h = c(0,1), col = "grey", lty = 2)

segments(red[1,1], red[1,2], red[2,1], red[2,2], lwd = 2, col = "red")#Makes the line segment
points(blue, col = "blue", pch = 16, cex = 2,
     asp = 1, xlim = c(0,1), ylim = c(0,1))# does same thing for blue line
segments(blue[1,1], blue[1,2], blue[2,1], blue[2,2], lwd = 2, col = "blue") 

p <- check_intersect(red, blue)
points(p[1], p[2], cex = 2)

p
#> [1] 0.5719010 0.6781469

Created on 2020-03-24 by the reprex package (v0.3.0)

Upvotes: 2

Related Questions