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

Graphics 将二次曲线转换为三次曲线,graphics,vector,Graphics,Vector,看着这些,我终于明白了为什么编程老师总是告诉我数学是如此重要。遗憾的是,我没有听 有谁能提供一个更具体的——例如,计算机语言y——公式来将二次曲线转换为三次曲线?理解可能存在一些舍入错误,这很好 给定由变量表示的四元曲线: StartX, StartY ControlX, ControlY EndX, EndY 希望StartX,StartY和EndX,EndY保持不变,但现在有一条三次曲线的Control1X,Control1Y和Control2X,Control2Y 是不是 Control

看着这些,我终于明白了为什么编程老师总是告诉我数学是如此重要。遗憾的是,我没有听

有谁能提供一个更具体的——例如,计算机语言y——公式来将二次曲线转换为三次曲线?理解可能存在一些舍入错误,这很好

给定由变量表示的四元曲线:

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相同的基本函数?

您的代码是正确的,只是您应该使用
2.0/3.0
而不是
0.66
,通过使用

Control1 = (Start + 2 * Control) / 3
Control2 = (End   + 2 * Control) / 3
请注意,线段也可以通过以下方式转换为三次Bezier曲线:

Control1 = Start
Control2 = End
当转换混合各种类型曲线(线性、二次、三次)的复杂路径时,这非常方便

还有一个将椭圆弧转换为立方体的基本变换(有一些不明显的小错误):您只需在椭圆四边形上至少分割弧(首先在符号的两个正交轴上切割椭圆,如果椭圆是圆,则在穿过中心的任意正交轴上切割椭圆,然后表示每个弧;当椭圆是圆时,两个焦点在同一点(圆心)上混淆,因此可以对其中一个正交轴使用任何方向是)

许多SVG渲染器通过在八分之一点上添加额外的分割来实现这一点(这样您不仅可以获得两个主轴通过的点的精确位置,而且还可以获得每个象限的两个等分对角轴(当椭圆是圆时)的精确位置(当椭圆不是圆时,将其视为仅沿小轴通过线性变换展平的圆,执行相同的计算),因为八分之一点的位置也非常精确:

cos(pi/4)=sin(pi/4)=sqrt(2)/2≈ 0.71,因为此附加拆分将允许在与圆成45度的对角线相交的点上精确渲染切线

然后将完整的椭圆转换为8个立方弧(即椭圆上的8个点和16个控制点):您几乎不会注意到椭圆弧和这些生成的立方弧之间的差异

您可以创建一个算法,该算法使用将贝塞尔曲线拆分为直线段列表时计算的相同“展平误差”,然后使用经典的快速Bresenham算法绘制直线段;“展平”算法只需测量两条直线段长度之和的相对偏差,这两条直线段将椭圆的两个焦点连接到生成的立方弧的任何一点,因为此和在任何真实椭圆上都是恒定的:如果对生成的立方弧控制点进行此测量,则差值应低于a给定期望和的百分比,或在绝对距离精度范围内,可用于使用简单线性公式创建更好的控制点近似值,以便这些添加的点位于实际椭圆上


当您希望从路径导出其他曲线时,特别是在给定距离处的“缓冲区”曲线,特别是当这些路径必须转换为具有定义的“笔划宽度”的“笔划”时,这种任意路径的变换非常有用:您需要计算两个“内部”和“外部”曲线,然后集中于如何转换斜接/斜接/方形/圆角,然后以方便的距离切割长斜接(匹配“斜接限制”因子乘以“笔划宽度”)

更高级的渲染器还将在两个圆弧之间有一个角而不是两个线段时使用切线圆表示的斜接(这对于绘制可爱的地理地图很有用)

将任意路径混合线段、椭圆弧和贝塞尔弧转换为仅立方弧是计算精确图像的必要步骤,在放大时不会看到过多缺陷。当“笔划”缓冲区必须产生一些效果(例如计算虚线)时,这是必要的,然后使用半透明像素或子像素增强结果以平滑渲染笔划(只有当所有东西都被展平为线段时,平滑才容易计算,如果只需要管理只包含三次贝塞尔的路径,则alsos的开发可能更简单:如果需要,它可以很容易地并行化,并通过硬件加速).贝塞尔圆弧总是很有趣,因为绘制它们很快,只需要基本的算术运算,并且绘制它们所需的时间与曲线的长度成正比,每个点都以相同的精度绘制

总之,所有曲线均可用三次贝塞尔弧表示,且允许最大可测量偏差(如果先放大测量网格以进行半色调或亚像素着色,然后使用合理快速的渲染准确地表示每条曲线,然后在任意缩放级别使用平滑的曲线(包括半色调或透明度),可以将此最大偏差设置为半像素或一个子像素最终使用经典Bresenham算法绘制线性笔划时的水平(仅使用快速整数算法)。这些渲染曲线的所有位置都将具有正确的tangeant,在近似点上没有任何意外的角度可见,并且近似中的其余控制点也将使曲率的所有位置(即tangeant圆的半径)都具有良好的平滑渲染,因此您也可以使用此近似来导出其他测量值,例如加速度、惯性力或带电粒子路径的磁效应)

如果您需要更高的精度,请使用阶数为4的贝塞尔圆弧(即曲线上点之间有3个控制点)来获得平滑的导数