Java 如何用二次贝塞尔曲线逼近圆的八分之一?

Java 如何用二次贝塞尔曲线逼近圆的八分之一?,java,bezier,ellipse,approximation,quadratic-curve,Java,Bezier,Ellipse,Approximation,Quadratic Curve,在我使用Java编写的矢量图形程序中,理想情况下,任何形状都可以由Path2D类的修改形式表示,该类使用二次贝塞尔曲线。理想情况下,椭圆也可以表示为Path2D对象。互联网上有大量关于使用三次贝塞尔曲线近似圆的象限的文档,但是使用Path2D类,三次贝塞尔曲线是不可能的。我一直在使用Desmos试图找到圆的八分之一的近似值,半径1以(0,0)为中心的圆的中点(在两个控制点之间)约为(0.993,0.412)。当然,有一些无理数可以更精确地表示为使用平方根或三角函数的公式 我尝试使用公式4*tan

在我使用Java编写的矢量图形程序中,理想情况下,任何形状都可以由Path2D类的修改形式表示,该类使用二次贝塞尔曲线。理想情况下,椭圆也可以表示为Path2D对象。互联网上有大量关于使用三次贝塞尔曲线近似圆的象限的文档,但是使用Path2D类,三次贝塞尔曲线是不可能的。我一直在使用Desmos试图找到圆的八分之一的近似值,半径
1
(0,0)
为中心的圆的中点(在两个控制点之间)约为
(0.993,0.412)
。当然,有一些无理数可以更精确地表示为使用平方根或三角函数的公式


我尝试使用公式
4*tan(pi/(2*n))/3
。要么这个公式不适用于八分之一,要么在我找到它的地方解释得很糟糕

t如果你说你在哪里找到的话会有所帮助-任意角度的公式(显然包括八分之一,只需插入π/4作为你的角度)与你展示的非常不同。找到真正的公式和解释,继续

二次曲线非常简单,因为控制点是端点切线的线性交点。因此,给定具有垂直切线的起点(1,0)(因为它是圆,这是圆的工作原理)和某个角度φ的终点(cos(phi),sin(phi)),以及切线(sin(phi),-cos(phi)),我们可以确定该曲线的控制点,如下所示:

Cx = cos(phi) - b * sin(phi)
Cy = sin(phi) + b * cos(phi)
其中:

    cos(phi) - 1
b = ------------
      sin(phi)
(这里的实际数学在上面的链接中解释)

插入PI/4来计算第一个八分之一意味着我们得到:

Cx = 1 (obviously; it's a vertical tangent, so the x coordinate is fixed)
Cy = sqrt(2) - 1
完成了:你不需要导出任何其他的值,因为所有其他的八分之一只是这些值的反射,你可以在纸上画一个圆,画线来显示八分之一,用它的坐标值标记第一个八分之一,然后去“哦,显然其他坐标是……”--上述公式也适用于半径为1的圆,但您知道如何乘法,因此您知道如何缩放值,以便它们与所需圆匹配

我很好奇为什么你想要二次曲线,因为它们客观上比三次曲线更糟糕。例如:您需要16个点来模拟具有二次八分之一的圆,而对于具有更高精度的四分之一立方,您只需要12个点


此外,即使你死心塌地只使用二次函数,你的软件用户也可能会转向其他软件。他们希望cubics能够提供给您,如果您的其他软件值得使用,他们会向您提出申请。为此制定计划,或者从一开始就支持二次和三次。毕竟,SVG等已经做到了。

如果您指的是java.awt.geom.Path2D,它确实支持带有curveTo()方法的立方贝塞尔曲线。真的吗?如果是,怎么做?curveTo()方法似乎不接受八个double(三次Bézier曲线每个点的x和y坐标)作为参数。curveTo()只接受六个double作为最后三个控制点的(x,y)坐标。第一个控制点与“当前点”相同。类似地,quadTo()只需要4倍(不是6倍),lineTo()只需要2倍(不是4倍)。那么,如何使用curveTo()定义三次Bezier曲线呢?假设有四个已知的x坐标和四个已知的y坐标。Path2D对象如何使用这些来生成三次Bezier曲线?我使用二次曲线是因为我在Java中使用的Path2D对象不允许三次Bezier曲线。至少我找不到任何方法。什么?当然有,它就在文档中:。您使用的是路径,因此如果您还没有坐标,请首先
移动到(x,y)
某个坐标(如果您是因为上一个路径命令而移动的,请不要移动到),然后调用
curveTo(c1x,c1y,c2x,c2y,x,y)
从上一个坐标移动到下一个坐标,在三次贝塞尔曲线上使用两个控制点。这确实有效。谢谢你的解释。