เมื่อเส้นโค้งประกอบด้วยส่วนของเส้นตรงจุดภายในทั้งหมดของส่วนดังกล่าวจะเป็นจุดเปลี่ยนซึ่งไม่น่าสนใจ ในทางกลับกันเส้นโค้งควรถูกมองว่าเป็นจุดยอดของเซกเมนต์เหล่านั้น โดยการแบ่งเส้นโค้งสองส่วนที่แตกต่างกันได้ในแต่ละส่วนนั้นเราสามารถคำนวณความโค้งได้ จุดโรคติดเชื้อที่พูดอย่างเคร่งครัดนั้นเป็นสถานที่ที่ความโค้งเป็นศูนย์
ในตัวอย่างมีความยาวเหยียดที่ความโค้งเกือบเป็นศูนย์ สิ่งนี้ชี้ให้เห็นว่าจุดที่ระบุควรประมาณจุดสิ้นสุดของพื้นที่ที่มีความโค้งต่ำเช่นนี้
อัลกอริธึมที่มีประสิทธิภาพจะทำให้เส้นโค้งเป็นจุดศูนย์กลางคำนวณความโค้งตามชุดจุดกึ่งกลางหนาแน่นระบุช่วงของความโค้งใกล้ศูนย์ (ใช้การประเมินที่สมเหตุสมผลว่ามันหมายถึงอะไร "ใกล้") และทำเครื่องหมายจุดสิ้นสุดของช่วงเหล่านั้น .
นี่คือR
โค้ดที่ใช้งานได้เพื่อแสดงแนวคิดเหล่านี้ เริ่มต้นด้วยสตริงบรรทัดที่แสดงเป็นลำดับของพิกัด:
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)
Spline พิกัดxและyแยกจากกันเพื่อให้ได้เส้นโค้งที่กำหนด (พารามิเตอร์จะถูกเรียกtime
)
n <- dim(xy)[1]
fx <- splinefun(1:n, xy[,1], method="natural")
fy <- splinefun(1:n, xy[,2], method="natural")
สอดแทรกเส้นโค้งสำหรับการพล็อตและการคำนวณ:
time <- seq(1,n,length.out=511)
uv <- sapply(time, function(t) c(fx(t), fy(t)))
เราต้องการฟังก์ชั่นในการคำนวณความโค้งของเส้นโค้งที่มีพารามิเตอร์ มันจำเป็นต้องประเมินอนุพันธ์อันดับหนึ่งและสองของเส้นโค้ง ด้วยเส้นโค้งจำนวนมาก (เช่นลูกบาศก์เส้นโค้ง) นี่เป็นการคำนวณทางพีชคณิตอย่างง่าย R
จัดเตรียมอนุพันธ์สามตัวแรกโดยอัตโนมัติ (ในสภาพแวดล้อมอื่น ๆ หนึ่งอาจต้องการคำนวณอนุพันธ์เป็นตัวเลข)
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
ฉันเสนอเพื่อประเมินเกณฑ์สำหรับความโค้งศูนย์ในแง่ของขอบเขตของเส้นโค้ง อย่างน้อยนี่เป็นจุดเริ่มต้นที่ดี มันควรจะปรับตามความทรมานของโค้ง (นั่นคือเพิ่มขึ้นสำหรับโค้งยาว) สิ่งนี้จะถูกนำมาใช้ในการระบายสีแปลงตามความโค้ง
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
ตอนนี้จุดที่ได้รับการขบและโค้งคำนวณมันยังคงอยู่เพียงเพื่อจะพบจุดโรคติดเชื้อ เพื่อแสดงให้เห็นเราอาจพล็อตจุดยอดพล็อตเส้นโค้งและทำเครื่องหมายจุดโรคติดเชื้อที่มัน
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)
จุดเปิดเป็นจุดยอดเดิมในxy
และจุดสีดำเป็นจุดเปลี่ยนทิศทางที่ระบุโดยอัตโนมัติด้วยอัลกอริทึมนี้ เนื่องจากความโค้งไม่สามารถคำนวณได้อย่างน่าเชื่อถือที่จุดปลายของเส้นโค้งจุดเหล่านั้นจึงไม่ถูกทำเครื่องหมายเป็นพิเศษ