teu*_*and 5 geometry r polyline
我正在寻找一种方法来偏移通过 xy 坐标在一个方向(在 R 中)定义的任意曲线。我可以使用 {polyclip} 包在两个方向上偏移曲线。
library(polyclip)
#> polyclip 1.10-0 built from Clipper C++ version 6.4.0
# Make a curve
t <- seq(10, 0, by = -0.05)
curve <- data.frame(
x = t * cos(t), y = t * sin(t)
)
plot(curve, type = 'l')
# Find offset
offset <- polylineoffset(curve, delta = 0.5,
jointype = "round", endtype = "openbutt")[[1]]
offset <- as.data.frame(offset) # xy coordinates
lines(offset, col = "red")
Run Code Online (Sandbox Code Playgroud)

由于曲线上的点比偏移的delta参数间隔更近,因此我可以通过找出一个点与下一个点之间的距离最大的位置来启发式地分割偏移。
distance <- c(0, sqrt(diff(offset$x)^2 + sqrt(diff(offset$y)^2)))
max_dist <- which.max(distance)
plot(curve, type = 'l')
lines(offset[1:(max_dist - 1), ], col = 3)
lines(offset[max_dist:nrow(offset), ], col = 4)
Run Code Online (Sandbox Code Playgroud)

由reprex 包于 2021 年 11 月 11 日创建(v2.0.1)
但是,我希望能够分割偏移,或者仅在一个方向上偏移,即使曲线上的点比偏移距离更远。在 R 中有没有办法做到这一点?我没有与 {polyclip} 包结婚,使用另一个包的解决方案也很好。
不需要额外的软件包 Teunbrand - 这可以通过一个小的三角函数来完成:
offset <- function(x, y, d) {
angle <- atan2(diff(y), diff(x)) + pi/2
angle <- c(angle[1], angle)
data.frame(x = d * cos(angle) + x, y = d * sin(angle) + y)
}
Run Code Online (Sandbox Code Playgroud)
因此,如果我们重新创建您的示例,我们将得到:
t <- seq(10, 0, by = -0.05)
curve <- data.frame(
x = t * cos(t), y = t * sin(t)
)
plot(curve, type = 'l')
Run Code Online (Sandbox Code Playgroud)
我们可以添加一个偏移量:
t <- seq(10, 0, by = -0.05)
curve <- data.frame(
x = t * cos(t), y = t * sin(t)
)
plot(curve, type = 'l')
Run Code Online (Sandbox Code Playgroud)
该函数的工作原理是使用 获取直线每个点的坡度角度,然后加上 90 度即可找到与该点处的曲线垂直atan2([delta y], [delta x])的直线的角度。最后,它找到沿这条线距原始x,y坐标的距离的点,即d(x + d * cos(angle), y + d * sin(angle))
这也许最好以图形方式显示。这里的蓝线是函数计算的偏移量offset:
curve2 <- offset(curve$x, curve$y, 0.5)
lines(curve2, col = "red")
Run Code Online (Sandbox Code Playgroud)
我们可以通过简单地传递负值来向相反方向偏移d:
lines(offset(curve$x, curve$y, -0.5), col = "forestgreen")
Run Code Online (Sandbox Code Playgroud)
我们需要意识到定义偏移量的局限性,特别是当偏移量与绘图的任何凹部分相比较大时。例如,如果我们查看 -2 的偏移量,我们似乎在螺旋中心有一个伪影:
segments(curve$x, curve$y, curve2$x, curve2$y, col = "blue")
Run Code Online (Sandbox Code Playgroud)
如果我们再次绘制偏移线段,我们就会明白为什么会发生这种情况:
lines(offset(curve$x, curve$y, -0.5), col = "forestgreen")
Run Code Online (Sandbox Code Playgroud)
本质上,如果您有一条紧密的凹曲线和相当大的偏移,那么偏移线将会交叉。这会产生一些与我们期望看到的“偏移路径”不太匹配的东西,但是如果不仔细定义偏移路径的含义以及我们想要的方式,很难看出如何解决这个问题它出现在类似上述情况的情况下。我的猜测是,最令人满意的解决方案是d在超出该点的曲线半径的点处进行收缩,但我不会在这里实现它,因为这只是一种选择,而且我确信存在那里有更好的。
无论如何,这样做的好处之一是结果中的点数与输入的点数相同。这使得可以轻松地将偏移量放入初始数据帧中。方便构建新的几何图形!
由reprex 包于 2021 年 11 月 12 日创建(v2.0.0)