这计算椭圆上的顶点坐标:
function calculateEllipse(a, b, angle)
{
var alpha = angle * (Math.PI / 180) ;
var sinalpha = Math.sin(alpha);
var cosalpha = Math.cos(alpha);
var X = a * cosalpha - b * sinalpha;
var Y = a * cosalpha + b * sinalpha;
}
但是如何计算“角度”以获得相等或大致相等的圆周段?
答案 0 :(得分:2)
所以从Jozi在OP的评论中所说的,所需要的不是如何将椭圆细分为相等的段(这需要一大堆可怕的积分),而是从大致相等长度的线段构造一个椭圆
There are a whole pile of ways to do that,但我认为最适合OP目的的是同心圆方法,在页面上列为“选秀方法”。如果你不介意安装Mathematica播放器,那就是一个整洁的小应用here,它以交互方式说明它。
这些方法的问题在于,在低偏心率下,段长度仅大致相等。如果你处理的是极端怪癖,事情会变得复杂得多。我能想到的最简单的解决方案是线性逼近每个象限内线段的长度,然后精确求解该象限中端点的位置。
详细说明:这是一个参数为a = 5, b = 1
的椭圆象限:
这是length of the arc subtended by an infinitesimal change in the angle在每个角度的情节:
x 轴是以弧度表示的角度, y 轴是由1弧度角度变化所对应的弧的长度。该公式可以使用我刚刚链接的维基百科文章中的公式导出,y = Sqrt(a^2 Sin^2(x) + b^2 Cos^2(x))
。值得注意的是,该函数的积分 - 该曲线下的面积 - 是整个象限中弧的长度。
现在,我们可以用直线近似它:
其中包含渐变m = (a-b) / (Pi/2)
和 y 拦截c = b
。使用简单几何,我们可以推断出红色曲线下面的区域是A = (a+b)*Pi/4
。
利用这些知识,以及曲线下面积是曲线总长度的知识,构造椭圆近似的问题减少到发现说midpoint-rule quadrature(其他正方形也会起作用,但这是最简单的红线,每个矩形的面积相等。
将该句子转换为等式,并用左手边界x
及其宽度w
表示矩形的正交位置,我们得到:
(v*m)*w^2 + (m*x+c)*w - A/k == 0
其中k
是我们想要用来近似象限的片段数,而v
是一个加权函数,我将很快介绍。这可用于通过首先设置x0 = 0
并求解w0
来构建正交,然后将其用于设置x1 = w0
并求解w1
。然后设置x2 = w1
等等,直到你得到所有k
左手边界点。第k+1
个边界点显然是Pi/2
。
加权函数v
有效地表示矩形穿过红线的位置。一个常数v = 0.5
相当于它在中间交叉,并以10分得到你:
但你可以玩它来看看有什么更好的平衡点。理想情况下,它应该保持在[0, 1]
范围内,并且您使用的值的总和应为k/2
。
如果你想要一个更好的近似而不用弄乱加权函数,你可以尝试对线进行最小二乘拟合,而不是仅仅将它拟合到端点,或者你可以尝试将三次多项式拟合到蓝色曲线而不是线性多项式。这将需要解决四分法,但如果你手头有一个数学包,那应该不是问题。
答案 1 :(得分:0)
评论太长了,所以我想这必须是一个答案......
这是一种形成一阶近似的数学上简单的方法。选择一个象限。您可以通过X和Y轴上的反射生成其他象限的数据。计算(x,y)角度= 0度,1度,... 90度。现在你想要连续点的小长度。如果(x_n,y_n)是角度= n处的坐标,那么毕达哥拉斯告诉我们点(x_n,y_n)和(x_n + 1,y_n + 1)之间的距离D是D = sqrt((x_n + 1 - x_n) ^ 2 +(y_n + 1-y_n)^ 2)。使用此公式可生成椭圆周围累积距离的表格,范围为0度到90度。这与您寻求的功能相反。当然,您不必选择1度的步长;你可以使用任何精确分为90度的角度。
如果要查找与周长步长x对应的角度,请在表格中找到最大角度n,使部分周长小于或等于x。角度n + 1的部分周长将大于x。使用线性插值来查找对应于x的小数角度。
我们所做的只是用直线段逼近椭圆并使用它们代替原始曲线;它是一阶近似。使用Simpson规则或类似规则而不是线性插值可以做得更好。
是的,您必须提前计算表格。但是一旦你有了表格,计算就很容易了。如果你不需要太多精确度,这在数学和编码方面都非常简单。