I needed the intersection for another application and found that the answer of nograpes did not work correctly:
# another example
x=seq(-4,6,length.out=10)
x1=dnorm(x, 0, 1)
x2=dnorm(x,2,2)
# Find points where x1 is above x2.
above <- x1 > x2
# Points always intersect when above=TRUE, then FALSE or reverse
intersect.points <- which(diff(above) != 0)
# Find the slopes for each line segment.
x1.slopes <- x1[intersect.points+1] - x1[intersect.points]
x2.slopes <- x2[intersect.points+1] - x2[intersect.points]
# Find the intersection for each segment.
x.points <- x[intersect.points] + ((x2[intersect.points] - x1[intersect.points]) / (x1.slopes-x2.slopes))
y.points <- x1[intersect.points] + (x1.slopes*(x.points-x[intersect.points]))
# Joint points
joint.points <- which(x1 == x2)
x.points <- c(x.points, joint.points)
y.points <- c(y.points, x1[joint.points])
# Plot points
# length(x); length(x1)
plot(x, x1,type='l')
lines(x, x2,type='l',col='red')
points(x.points,y.points,col='blue')
For these bi-normal distributions the points are off, in this case especially the right hand point of intersection. This happens when the values on x-axis are not consecutive integers and have therefore not a difference of 1 for consecutive points. I replaced intersect.points
by x[intersect.points]
, which is not sufficient. This is a pity, as the method is relatively simple in comparison to the other methods. The method supplied by baptiste works much better:
m = cbind(x1, x2)
matplot(x, m, t="l", lty=1)
points(ssi_matrix(x, m))
Following the same idea, a more general implementation that allows for differences of consecutive x-values != 1 is:
intersect.2lines <- function (x, y1, y2){
above = y1 > y2
intersect.points <- which(diff(above) != 0)
y1.diff <- y1[intersect.points+1] - y1[intersect.points]
y2.diff <- y2[intersect.points+1] - y2[intersect.points]
x.diff <- x[intersect.points+1]-x[intersect.points]
slope1 = y1.diff/x.diff
slope2 = y2.diff/x.diff
intercept1 = y1[intersect.points]-slope1*x[intersect.points]
intercept2 = y2[intersect.points]-slope2*x[intersect.points]
x.points = ifelse(slope1==slope2, NA,
(intercept2-intercept1)/(slope1-slope2))
y.points = ifelse(slope1==slope2, NA,
slope1*x.points+intercept1)
# Joint points
joint.points <- which(y1 == y2)
x.points <- c(x.points, x[joint.points])
y.points <- c(y.points, y1[joint.points])
return(data.frame(x.points=x.points, y.points=y.points))
}
It is an implementation of the formula given in Wikipedia, "Given two line equations" Line-line intersection
The results are now identical with those produced by the method of baptiste.
plot(x1,x2, type='l')
? – Canstplot(seq_along(x1), x1, type='l')
andlines(seq_along(x2), x2, type='l', col="red")
– Canst