Ios 如何确定三次bezier路径端点处的曲率
我一直在做一个项目,我使用贝塞尔路径来绘制我需要的曲线。我的项目中的每个基本形状都由三条端对端排列的三次贝塞尔曲线组成,以便坡度匹配它们相交的位置 我需要解决的基本问题是,由三条贝塞尔曲线组成的复合曲线是否与自身相交。经过一段时间的思考,我发现在给定曲线约束的情况下,我可以将任务简化为其他任务: 三条Bezier路径中的每一条的曲率都应该在曲率方向上与其邻接的曲线相反。换句话说,应该有一个拐点,一条贝塞尔曲线与另一条贝塞尔曲线相邻。如果不是这样,我希望拒绝生成曲线的参数集,并选择另一个集 在任何情况下,我的基本问题是如何检测曲线之间是否存在拐点 在图中,三条贝塞尔曲线中的每一条都使用不同的颜色显示。左侧黑色曲线在它们相交的点处以与红色曲线相反的方向弯曲,但右侧黑色曲线以相同的方向弯曲。存在一个拐点,红色和左侧黑色曲线相交,但红色和右侧黑色曲线不相交 编辑: 下面,我添加了另一个图像,显示了包围贝塞尔路径的多边形。黑色曲线中显示的多边形交叉线测试的是拐点,而不是回路。我猜想,可以通过检查封闭多边形是否相交来测试一条曲线与另一条曲线相交,如红色和蓝色曲线所示。 另外,由于存在一些关于限制的问题,我将在这里列出其中一些:Ios 如何确定三次bezier路径端点处的曲率,ios,bezier,Ios,Bezier,我一直在做一个项目,我使用贝塞尔路径来绘制我需要的曲线。我的项目中的每个基本形状都由三条端对端排列的三次贝塞尔曲线组成,以便坡度匹配它们相交的位置 我需要解决的基本问题是,由三条贝塞尔曲线组成的复合曲线是否与自身相交。经过一段时间的思考,我发现在给定曲线约束的情况下,我可以将任务简化为其他任务: 三条Bezier路径中的每一条的曲率都应该在曲率方向上与其邻接的曲线相反。换句话说,应该有一个拐点,一条贝塞尔曲线与另一条贝塞尔曲线相邻。如果不是这样,我希望拒绝生成曲线的参数集,并选择另一个集 在任何
- 最左边的点和最右边的点具有相同的y值
- 最左侧点控制点的x值小于
最右侧点的控制点的x值。这将保持
黑色和蓝色的曲线相互交叉 - 最左侧和最右侧点的坡度大约在+/-10范围内 水平度
- 黑色和红色曲线的交点,以及 红色和蓝色曲线将整个曲线大致分成两部分 三分之一。我没有确切的数字,但一个样本界就是这样 红色曲线左端的x值介于25%之间 和最右边点x值的40%
- 交点的y值为+/-某个小分数 总宽度的
- 交叉点处的坡度大于0.6且小于3.0(正或负) 否定)
曲率方程相当简单。你只需要曲率的符号,所以你可以略过一点数学。你基本上对一阶导数和二阶导数的叉积的符号感兴趣 这种简化仅适用于曲线平滑连接。如果切线不相等,则需要进行更复杂的测试 曲线p的曲率符号:
ax = P[1].x - P[0].x; // a = P1 - P0
ay = P[1].y - P[0].y;
bx = P[2].x - P[1].x - ax; // b = P2 - P1 - a
by = P[2].y - P[1].y - ay;
cx = P[3].x - P[2].x - bx*2 - ax; // c = P3 - P2 - 2b - a
cy = P[3].y - P[2].y - by*2 - ay;
bc = bx*cy - cx*by;
ac = ax*cy - cx*ay;
ab = ax*by - bx*ay;
r = ab + ac*t + bc*t*t;
请注意,r是一阶导数和二阶导数的叉积,符号表示曲率方向。在左曲线t=1处和右曲线t=0处计算r。如果产品为负值,则存在一个拐点
如果有曲线U、V和W,其中U为左黑色,V为中红色,W为右黑色,则计算上述各曲线的bc、ac和ab。如果两个连接都是拐点,则以下测试为真:
(Uab+Uac+Ubc)*(Vab) < 0 && (Vab+Vac+Vbc)*(Wab) < 0
假设有4个点:P0、P1、P2和P3,它们描述了一条三次贝塞尔曲线(cBc)。P0和P3是起点和终点,P1和P2是方向点 当P0、P1和P2共线时,cBc在P0处有一个拐点 当P1、P2和P3共线时,cBC在P3处有一个拐点 评论 1) 使用矢量积(分别为P0P1 x P1P2和P1P2 x P2P3)检查共线性。结果应为零长度向量 2) 避免出现P0、P1、P2和P3都是共线的情况,它们创建的cBc不是一般意义上的曲线 推论
当P1=P2时,cBc两边都有拐点。@Victor Engel:谢谢你的澄清。现在,解决方案更容易了 简而言之,看看两条曲线的扭矩。如果它们拉在一起,就会出现“拐点”,如果它们相对,就会出现“曲率”
// start with the classic bezier curve equation
P = (1-t)^3*P0 + 3*(1-t)^2*t*P1 + 3*(1-t)*t^2*P2 + t^3*P3
// convert to polynomial
P = P0 + 3*t*(P1 - P0) + 3*t^2*(P2 - 2*P1 + P0) + t^3*(P3 - 3*P2 + 3*P1 - P0)
// rename the terms to a,b,c
P = P0 + 3at + 3btt + cttt
// find the first and second derivatives
P' = 3a + 6bt + 3ctt
P" = 6b + 6ct
// and the cross product after some reduction
P' x P" = ab + act + bctt
a = P2P3
b = P1P2
u = Q0Q1
v = Q1Q2
Tp = b x a
if Tp=0 {very rarely vectors a, b can be parallel.}
b = P0P1
Tp = b x a
if Tp=0
No! It's can't be! Who straightened the curve???
STOP
endif
endif
Tq = u x v
if Tq=0 {also vectors u, v can be parallel.}
v = Q2Q3
Tq = u x v
if Tq=0
Oh no! What happened to my curve???
STOP
endif
endif
if Tp*Tq < 0 then Houston! We have AN "INFLEXION"!
else WE CONTINUE THE TURN!