我正在尋找一種方法來偏移通過 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")

因為曲線上的點比偏移量的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)

由
我們可以添加一個偏移量:
curve2 <- offset(curve$x, curve$y, 0.5)
lines(curve2, col = "red")

此函式的作業方式是使用 獲得直線上每個點的斜率角度atan2([delta y], [delta x]),然后加上 90 度以找到在該點與曲線垂直的直線的角度。最后,它找到d沿這條線與原始 x,y 坐標的距離的點,即(x d * cos(angle), y d * sin(angle))
This is maybe best shown graphically. The blue lines here are the offsets calculated by the function offset:
segments(curve$x, curve$y, curve2$x, curve2$y, col = "blue")

We can offset in the opposite direction by simply passing a negative value of d:
lines(offset(curve$x, curve$y, -0.5), col = "forestgreen")

We need to be aware of the limitations of defining what we mean by an offset, particularly when the offset is large compared to any concave sections of the plot. For example, if we look at an offset of -2, we seem to have an artifact at the center of our spiral:
plot(curve, type = 'l')
curve3 <- offset(curve$x, curve$y, -2)
lines(curve3, col = "gray50")

We can see why this happens if we draw the offset segments again:
segments(curve$x, curve$y, curve3$x, curve3$y, col = "blue")

Essentially, if you have a tight concave curve and a fairly large offset, then the offset lines will cross. This produces something that doesn't quite match with what we would expect to see with an "offset path", but it is difficult to see how this could be fixed without carefully defining what we mean by an offset path, and how we would want it to appear in situations like the one above. My guess is that the most satisfactory solution would be to shrink d at the points where it would otherwise exceed the radius of the curve at that point, but I won't implement that here as this is only one option, and I'm sure there are better ones out there.
Anyway, one of the benefits of doing it this way is that the number of points in the result is the same as the number that went in. This makes it easy to have the offsets put into your initial data frame. Handy for building new geoms!
Created on 2021-11-12 by the reprex package (v2.0.0)
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/356520.html
上一篇:在閃亮的意外行為中取消組合和選擇
