将二次曲线转换为三次曲线

11

阅读如何将二次贝塞尔曲线转换为三次贝塞尔曲线?之后,我终于明白编程老师们为什么总是告诉我数学很重要了。可惜我没有听。

有谁能提供一个更具体的,即计算机语言风格的公式,用于将二次曲线转换为三次曲线?理解可能存在一些舍入误差,这是可以接受的。

给定由变量表示的二次曲线:

StartX, StartY
ControlX, ControlY
EndX, EndY

希望保持StartX,StartY和EndX,EndY不变,但现在拥有一个立方曲线的Control1X,Control1Y和Control2X,Control2Y。

这是...

Control1X = StartX + (.66 * (ControlX - StartX))
Control2X = EndX + (.66 * (ControlX - EndX))

使用相同的基本函数计算Control1Y和Control2Y?


请参见https://dev59.com/m3A75IYBdhLWcg3wrrJS。 - lhf
2个回答

阿里云服务器只需要99元/年,新老用户同享,点击查看详情
10

你的代码是正确的,除了你应该使用2.0/3.0而不是0.66


5
您可以通过使用「舍入误差」来避免大多数舍入误差。
Control1 = (Start + 2 * Control) / 3
Control2 = (End   + 2 * Control) / 3

请注意,线段也可以通过以下方式转换为三次贝塞尔曲线:

Control1 = Start
Control2 = End
这在转换混合了各种曲线(线性、二次和三次)的复杂路径时非常方便。 还有一种基本的变换,用于将椭圆弧转换为三次曲线(带有一些微小且不易察觉的误差):您只需要至少在椭圆四分之一弧上进行分割(首先在对称轴的两个正交轴上切割椭圆,或者在通过中心的任意正交轴上切割椭圆,如果椭圆是一个圆,则表示每个弧;当椭圆是一个圆时,两个焦点在同一点上重合,即圆的中心,因此您可以为其中一个正交轴使用任何方向)。许多SVG渲染器通过在八分之一处添加额外的分割来执行此操作(以便您不仅可以获取两个主轴穿过的点的精确位置,而且还可以获取两个对角线轴的精确位置,在这些情况下,八分之一也是相当精确的位置:cos(pi/4)=sin(pi/4)=sqrt(2)/2 ≈ 0.71,并且由于此额外的分割将允许在穿过圆的对角线的点上精确渲染切线,因此这对于绘制可爱的地理地图非常有用)。然后将整个椭圆转换为8个三次曲线(即椭圆上的8个点和16个控制点):您几乎不会注意到椭圆弧和这些生成的三次曲线之间的差异。 您可以创建一个算法,该算法使用与将贝塞尔曲线拆分为线性段列表时计算的相同“平坦误差”,然后使用经典的快速Bresenham算法绘制这些线性段; “平坦化”算法只需测量连接椭圆的两个焦点与生成的三次曲线的任何点的两条直线段长度之和的相对偏差,因为这个和在任何真正的椭圆上都是恒定的:如果您在三次曲线的生成控制点上进行此测量,则差异应低于给定百分比的预期总和,或者在绝对距离精度范围内,并且可以用于使用简单的线性公式创建更好的控制点的逼近,以便这些添加的点将位于真实的椭圆上。 这种任意路径的变换在您想从路径派生其他曲线时非常有用,特别是在必须将这些路径转换为具有定义的“描边宽度”的“笔画”时,您需要计算两个“内部”和“外部”曲线,然后集中精力如何转换斜接/端点/正方形/圆角,然后在方便的距离(匹配“斜接限制”因子乘以“描边宽度”)处切割长斜接。 更先进的渲染器还将使用切线圆表示两个弧之间的拐角而不是两个线段(这对于绘制可爱的地理地图非常有用)... 将混合线段、椭圆弧和贝塞尔曲线的任意路径转换为仅包含立方曲线是计算精确图像的必要步骤,以避免在缩放时出现过多的缺陷。当您的“描边”缓冲区需要进行一些效果(例如计算虚线)时,这是必要的,并使用半透明像素或子像素增强结果以平滑呈现的笔画(只有在将所有内容展平为线段后才容易计算平滑,如果它只需要处理仅包含立方贝塞尔曲线的路径,则还可以更简单地开发:如果需要,可以轻松并行化,并通过硬件加速)。贝塞尔曲线始终很有趣,因为绘制它们很快且仅需要基本算术运算,并且绘制它们所需的时间与曲线长度成比例,每个点都具有相同的精度级别。 总之,所有曲线都可以用最大可测偏差允许的立方贝塞尔曲线表示(您可以将此最大偏差设置为半个像素或一个子像素,如果您首先将测量网格放大到半调或子像素阴影,然后使用合理快速的渲染准确地表示每个曲线,最终使用经典的Bresenham算法使用快速整数运算绘制线性笔画时,可以在任何缩放级别上获得平滑的曲线呈现,包括半调或透明度级别)。这些渲染的曲线将在任何地方都具有正确的切线,没有在近似点上可见的意外角度,并且近似中剩余的控制点也将在曲率处产生良好的平滑呈现(即切线圆的半径),因此您还可以使用此近似来推导其他测量值,例如加速度、惯性力或带电粒子路径的磁效应。 如果您需要更高的精度,请使用4次贝塞尔曲线(即在曲线上的点之间有3个控制点)以获得补充程度的平滑导出(例如力的梯度),或者只需进一步分割立方曲线,直到导出足够平滑(但是使用4次贝塞尔曲线相对于仅使用立方贝塞尔曲线,需要更少的点曲线和更少的控制点来实现相同的精度容差)。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,