私は2つのベクトルを持っています:
set.seed(1)
x1 = rnorm(100,0,1)
x2 = rnorm(100,1,1)
これらを線としてプロットし、線の交点を見つけたいと思います。また、交点が複数ある場合は、それぞれを見つけたいと思います。
同様の質問に遭遇し、 を使用してこの問題を解決しようとしましたspatstat
が、両方のベクトル値を含む結合されたデータ フレームを に変換できませんでしたpsp object
。
私は2つのベクトルを持っています:
set.seed(1)
x1 = rnorm(100,0,1)
x2 = rnorm(100,1,1)
これらを線としてプロットし、線の交点を見つけたいと思います。また、交点が複数ある場合は、それぞれを見つけたいと思います。
同様の質問に遭遇し、 を使用してこの問題を解決しようとしましたspatstat
が、両方のベクトル値を含む結合されたデータ フレームを に変換できませんでしたpsp object
。
文字通り 2 つのランダムな数値ベクトルがある場合、非常に単純な手法を使用して両方の交点を取得できます。x1
が上にあるすべてのポイントを見つけx2
てから、次のポイントでその下に、またはその逆を見つけます。これらが交点です。次に、それぞれの勾配を使用して、そのセグメントの切片を見つけます。
set.seed(2)
x1 <- sample(1:10, 100, replace = TRUE)
x2 <- sample(1:10, 100, replace = TRUE)
# 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 <- intersect.points + ((x2[intersect.points] - x1[intersect.points]) / (x1.slopes-x2.slopes))
y.points <- x1[intersect.points] + (x1.slopes*(x.points-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
plot(x1,type='l')
lines(x2,type='l',col='red')
points(x.points,y.points,col='blue')
# Segment overlap
start.segment <- joint.points[-1][diff(joint.points) == 1] - 1
for (i in start.segment) lines(x = c(i, i+1), y = x1[c(i, i+1)], col = 'blue')
別のセグメント間交差コードを次に示します。
# segment-segment intersection code
# http://paulbourke.net/geometry/pointlineplane/
ssi <- function(x1, x2, x3, x4, y1, y2, y3, y4){
denom <- ((y4 - y3)*(x2 - x1) - (x4 - x3)*(y2 - y1))
denom[abs(denom) < 1e-10] <- NA # parallel lines
ua <- ((x4 - x3)*(y1 - y3) - (y4 - y3)*(x1 - x3)) / denom
ub <- ((x2 - x1)*(y1 - y3) - (y2 - y1)*(x1 - x3)) / denom
x <- x1 + ua * (x2 - x1)
y <- y1 + ua * (y2 - y1)
inside <- (ua >= 0) & (ua <= 1) & (ub >= 0) & (ub <= 1)
data.frame(x = ifelse(inside, x, NA),
y = ifelse(inside, y, NA))
}
# do it with two polylines (xy dataframes)
ssi_polyline <- function(l1, l2){
n1 <- nrow(l1)
n2 <- nrow(l2)
stopifnot(n1==n2)
x1 <- l1[-n1,1] ; y1 <- l1[-n1,2]
x2 <- l1[-1L,1] ; y2 <- l1[-1L,2]
x3 <- l2[-n2,1] ; y3 <- l2[-n2,2]
x4 <- l2[-1L,1] ; y4 <- l2[-1L,2]
ssi(x1, x2, x3, x4, y1, y2, y3, y4)
}
# do it with all columns of a matrix
ssi_matrix <- function(x, m){
# pairwise combinations
cn <- combn(ncol(m), 2)
test_pair <- function(i){
l1 <- cbind(x, m[,cn[1,i]])
l2 <- cbind(x, m[,cn[2,i]])
pts <- ssi_polyline(l1, l2)
pts[complete.cases(pts),]
}
ints <- lapply(seq_len(ncol(cn)), test_pair)
do.call(rbind, ints)
}
# testing the above
y1 = rnorm(100,0,1)
y2 = rnorm(100,1,1)
m = cbind(y1, y2)
x = 1:100
matplot(x, m, t="l", lty=1)
points(ssi_matrix(x, m))