Eğri çizgi parçalarından oluştuğunda, o zaman bu parçaların tüm iç noktaları ilgi çekici olmayan eğilme noktalarıdır. Bunun yerine, eğri bu bölümlerin köşeleriyle yaklaştığı düşünülmelidir . Bu bölümler boyunca parçalara ayrılabilir iki kat eğri oluşturarak, eğriliği hesaplayabiliriz. Kesin olarak konuşursak bir bükülme noktası, eğriliğin sıfır olduğu bir yerdir.
Örnekte eğriliğin neredeyse sıfır olduğu uzunca uzamalar vardır. Bu, belirtilen noktaların bu tür düşük eğrilikli bölgelerin uçlarına yaklaşması gerektiğini göstermektedir.
Bu nedenle etkili bir algoritma, köşeleri sınırlar, yoğun bir ara nokta kümesi boyunca eğriliği hesaplar, sıfıra yakın eğrilik aralıklarını belirler ("yakın" olmanın ne demek olduğuna dair bazı makul bir tahmin kullanarak) ve bu aralıkların bitiş noktalarını işaretler .
İşte R
bu fikirleri göstermek için çalışma kodu. Koordinat dizisi olarak ifade edilen bir satır dizesiyle başlayalım:
xy <- matrix(c(5,20, 3,18, 2,19, 1.5,16, 5.5,9, 4.5,8, 3.5,12, 2.5,11, 3.5,3,
2,3, 2,6, 0,6, 2.5,-4, 4,-5, 6.5,-2, 7.5,-2.5, 7.7,-3.5, 6.5,-8), ncol=2, byrow=TRUE)
Eğrinin bir parametresini elde etmek için x ve y koordinatlarını ayrı ayrı çizin. (Parametre çağrılacak time
.)
n <- dim(xy)[1]
fx <- splinefun(1:n, xy[,1], method="natural")
fy <- splinefun(1:n, xy[,2], method="natural")
Çizim ve hesaplama için spline'ları enterpolasyon yapın :
time <- seq(1,n,length.out=511)
uv <- sapply(time, function(t) c(fx(t), fy(t)))
Parametreli bir eğrinin eğriliğini hesaplamak için bir işleve ihtiyacımız var . Spline'ın birinci ve ikinci türevlerini tahmin etmesi gerekir. Birçok spline'da (kübik splinelar gibi) bu kolay bir cebirsel hesaplamadır. R
otomatik olarak ilk üç türevi sağlar. (Diğer ortamlarda türevlerin sayısal olarak hesaplanması istenebilir.)
curvature <- function(t, fx, fy) {
# t is an argument to spline functions fx and fy.
xp <- fx(t,1); yp <- fy(t,1) # First derivatives
xpp <- fx(t,2); ypp <- fy(t,2) # Second derivatives
v <- sqrt(xp^2 + yp^2) # Speed
(xp*ypp - yp*xpp) / v^3 # (Signed) curvature
# (Left turns have positive curvature; right turns, negative.)
}
kappa <- abs(curvature(time, fx, fy)) # Absolute curvature of the data
Sıfır eğriliği için eşiğin derecesine göre bir eşik tahmin etmeyi öneriyorum . Bu en azından iyi bir başlangıç noktasıdır; eğrinin eğriliğine (yani daha uzun eğriler için arttırılmış) göre ayarlanmalıdır. Bu daha sonra eğriliğe göre grafikleri renklendirmek için kullanılacaktır.
curvature.zero <- 2*pi / max(range(xy[,1]), range(xy[,2])) # A small threshold
i.col <- 1 + floor(127 * curvature.zero/(curvature.zero + kappa))
palette(terrain.colors(max(i.col))) # Colors
Artık köşeler eğrilmiş ve eğrilik hesaplanmış olmasına rağmen , sadece bükülme noktalarını bulmak için kalır . Onlara göstermek için köşeleri çizebilir, spline'ı çizebilir ve üzerinde çarpma noktalarını işaretleyebiliriz.
plot(xy, asp=1, xlab="x",ylab="y", type="n")
tmp <- sapply(2:length(kappa), function(i) lines(rbind(uv[,i-1],uv[,i]), lwd=2, col=i.col[i]))
points(t(sapply(time[diff(kappa < curvature.zero/2) != 0],
function(t) c(fx(t), fy(t)))), pch=19, col="Black")
points(xy)
Açık noktalar, orjinal köşelerdir xy
ve siyah noktalar, bu algoritma ile otomatik olarak tanımlanan bükülme noktalarıdır. Eğrilik güvenilir bir şekilde eğrinin uç noktalarında hesaplanamadığından, bu noktalar özel olarak işaretlenmemiştir.