目前,我試圖讓多個貝塞爾曲線具有等距點。我目前使用三次插值來找到點,但是因爲貝塞爾曲線的工作方式,某些區域比其他區域更密集,並且由於距離可變,所以證明了紋理映射的總量。 有沒有辦法按距離而不是按百分比找到貝塞爾上的點?此外,是否有可能將其擴展到多條連接的曲線?Bezier曲線上的等距點
回答
P_0和P_3之間的距離(以立方形式),是的,但我認爲你知道這一點,是直截了當的。
曲線上的距離僅僅是弧長:
fig 1 http://www.codecogs.com/eq.latex?%5Cint_%7Bt_0%7D%5E%7Bt_1%7D%20%7B%20|P'(t)|%20dt
其中:
也許,你必須T_0 = 0,T -1 = 1.0,並且dz(t)= 0(2d平面)。
這就是你如何找到給定參數的弧長,但是找到等距點需要這個函數的反函數。從一個到另一個不是微不足道的。 @Christian Romo:你是怎麼做到的?我的意思是,你可以使用二分搜索,但這會非常慢(對於我正在嘗試做的事情)。 – CromTheDestroyer 2010-11-19 04:18:21
這被稱爲「弧長」參數化。我幾年前寫了一篇關於這一點:
http://www.saccade.com/writing/graphics/RE-PARAM.PDF
的想法是預先計算「參數」曲線,並評估通過的曲線。
尚未完整閱讀論文。但是我想問一下,是否有更好的方法來定義不需要首先「轉換」的曲線。例如。你知道我是否使用NURBS來定義所有路徑/曲線,它是否支持更快的等距弧長參數化?或者以其他方式?編輯:更快我的意思是使用CPU或GPU。 – Ciantic 2013-05-11 12:49:50
我知道這是一個老問題,但我最近碰到這個問題,並創建了一個UIBezierPath
延伸解決X
座標給定Y
座標,反之亦然。寫在迅速。
https://github.com/rkotzy/RKBezierMath
extension UIBezierPath {
func solveBezerAtY(start: CGPoint, point1: CGPoint, point2: CGPoint, end: CGPoint, y: CGFloat) -> [CGPoint] {
// bezier control points
let C0 = start.y - y
let C1 = point1.y - y
let C2 = point2.y - y
let C3 = end.y - y
// The cubic polynomial coefficients such that Bez(t) = A*t^3 + B*t^2 + C*t + D
let A = C3 - 3.0*C2 + 3.0*C1 - C0
let B = 3.0*C2 - 6.0*C1 + 3.0*C0
let C = 3.0*C1 - 3.0*C0
let D = C0
let roots = solveCubic(A, b: B, c: C, d: D)
var result = [CGPoint]()
for root in roots {
if (root >= 0 && root <= 1) {
result.append(bezierOutputAtT(start, point1: point1, point2: point2, end: end, t: root))
}
}
return result
}
func solveBezerAtX(start: CGPoint, point1: CGPoint, point2: CGPoint, end: CGPoint, x: CGFloat) -> [CGPoint] {
// bezier control points
let C0 = start.x - x
let C1 = point1.x - x
let C2 = point2.x - x
let C3 = end.x - x
// The cubic polynomial coefficients such that Bez(t) = A*t^3 + B*t^2 + C*t + D
let A = C3 - 3.0*C2 + 3.0*C1 - C0
let B = 3.0*C2 - 6.0*C1 + 3.0*C0
let C = 3.0*C1 - 3.0*C0
let D = C0
let roots = solveCubic(A, b: B, c: C, d: D)
var result = [CGPoint]()
for root in roots {
if (root >= 0 && root <= 1) {
result.append(bezierOutputAtT(start, point1: point1, point2: point2, end: end, t: root))
}
}
return result
}
func solveCubic(a: CGFloat?, var b: CGFloat, var c: CGFloat, var d: CGFloat) -> [CGFloat] {
if (a == nil) {
return solveQuadratic(b, b: c, c: d)
}
b /= a!
c /= a!
d /= a!
let p = (3 * c - b * b)/3
let q = (2 * b * b * b - 9 * b * c + 27 * d)/27
if (p == 0) {
return [pow(-q, 1/3)]
} else if (q == 0) {
return [sqrt(-p), -sqrt(-p)]
} else {
let discriminant = pow(q/2, 2) + pow(p/3, 3)
if (discriminant == 0) {
return [pow(q/2, 1/3) - b/3]
} else if (discriminant > 0) {
let x = crt(-(q/2) + sqrt(discriminant))
let z = crt((q/2) + sqrt(discriminant))
return [x - z - b/3]
} else {
let r = sqrt(pow(-(p/3), 3))
let phi = acos(-(q/(2 * sqrt(pow(-(p/3), 3)))))
let s = 2 * pow(r, 1/3)
return [
s * cos(phi/3) - b/3,
s * cos((phi + CGFloat(2) * CGFloat(M_PI))/3) - b/3,
s * cos((phi + CGFloat(4) * CGFloat(M_PI))/3) - b/3
]
}
}
}
func solveQuadratic(a: CGFloat, b: CGFloat, c: CGFloat) -> [CGFloat] {
let discriminant = b * b - 4 * a * c;
if (discriminant < 0) {
return []
} else {
return [
(-b + sqrt(discriminant))/(2 * a),
(-b - sqrt(discriminant))/(2 * a)
]
}
}
private func crt(v: CGFloat) -> CGFloat {
if (v<0) {
return -pow(-v, 1/3)
}
return pow(v, 1/3)
}
private func bezierOutputAtT(start: CGPoint, point1: CGPoint, point2: CGPoint, end: CGPoint, t: CGFloat) -> CGPoint {
// bezier control points
let C0 = start
let C1 = point1
let C2 = point2
let C3 = end
// The cubic polynomial coefficients such that Bez(t) = A*t^3 + B*t^2 + C*t + D
let A = CGPointMake(C3.x - 3.0*C2.x + 3.0*C1.x - C0.x, C3.y - 3.0*C2.y + 3.0*C1.y - C0.y)
let B = CGPointMake(3.0*C2.x - 6.0*C1.x + 3.0*C0.x, 3.0*C2.y - 6.0*C1.y + 3.0*C0.y)
let C = CGPointMake(3.0*C1.x - 3.0*C0.x, 3.0*C1.y - 3.0*C0.y)
let D = C0
return CGPointMake(((A.x*t+B.x)*t+C.x)*t+D.x, ((A.y*t+B.y)*t+C.y)*t+D.y)
}
// TODO: - future implementation
private func tangentAngleAtT(start: CGPoint, point1: CGPoint, point2: CGPoint, end: CGPoint, t: CGFloat) -> CGFloat {
// bezier control points
let C0 = start
let C1 = point1
let C2 = point2
let C3 = end
// The cubic polynomial coefficients such that Bez(t) = A*t^3 + B*t^2 + C*t + D
let A = CGPointMake(C3.x - 3.0*C2.x + 3.0*C1.x - C0.x, C3.y - 3.0*C2.y + 3.0*C1.y - C0.y)
let B = CGPointMake(3.0*C2.x - 6.0*C1.x + 3.0*C0.x, 3.0*C2.y - 6.0*C1.y + 3.0*C0.y)
let C = CGPointMake(3.0*C1.x - 3.0*C0.x, 3.0*C1.y - 3.0*C0.y)
return atan2(3.0*A.y*t*t + 2.0*B.y*t + C.y, 3.0*A.x*t*t + 2.0*B.x*t + C.x)
}
}
- 1. 實現Bezier曲線
- 2. 在bicubic bezier曲線上滾動
- 3. 查找三次Bezier曲線
- 4. 如何在cocos2d中獲取Bezier曲線上某點的座標?
- 5. 關於Bezier曲線實現的問題?
- 6. Bezier曲線總是相同的長度
- 7. 線段中的等距點
- 8. 在螺旋線上繪製等距點
- 9. 在線上查找最大等距點
- 10. 繪製Bezier曲線的問題,在最後一點
- 11. 如何選擇Bezier樣條曲線?
- 12. 從SVG文件中取出Bezier曲線
- 13. 添加三次Bezier曲線單張
- 14. 曲線上的點掉出曲線
- 15. 在Bezier曲線中放置「好」控制點
- 16. 畫布上的等距點
- 17. 在特定路徑(ex bezier曲線)上拖放as3
- 18. 用於速記/平滑SVG路徑計算控制點的Bezier曲線
- 19. Bezier點動畫
- 20. 爲什麼Bezier曲線變成iOS UIView中的形狀?
- 21. 沿着Bezier曲線路徑的iPhone移動UI圖像視圖
- 22. 如何在WPF中繪製Bezier曲線的一部分?
- 23. 在Bezier曲線中添加顏色的算法
- 24. greensock tween找到bezier曲線的末端旋轉
- 25. 動畫bezier直線
- 26. 一種繪製等距曲線的方法
- 27. 距離某一點的線段距離上的點
- 28. pyqtgraph的等級曲線:isocurve
- 29. 等價於ggplot的曲線()
- 30. 如何在UWP中沿着Cubic Bezier曲線製作UserControl動畫
也http://math.stackexchange.com/a/61796/589見。 – lhf 2016-01-13 12:09:59