问题描述
函数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;
}
但我如何计算角度以获得相等或大致相等的圆周所以根据Jozi在OP的评论中所说的话,所需要的不是如何将一个椭圆细分为相等的片段(这将需要一大堆可怕的积分),它是从大致相等长度的线段构造一个椭圆。 .uwgb.edu / dutchs / MATHALGO / Ellipses.HTMrel =nofollow noreferrer>有很多方法可以做到这一点,但我认为最适合OP的目的是同心圆方法,在页面上列为'草拟者的方法'。如果你不介意安装Mathematica播放器,这里有一个整洁的应用程序:
x 轴是以弧度表示的角度,而 y 轴是1弧度角度更改所对应的弧的长度。这个公式可以使用我刚刚链接的维基百科文章中的公式推导出来的公式是: y = Sqrt(a ^ 2 Sin ^ 2(x)+ b ^ 2 Cos ^ 2(x))。但要注意的重要一点是,该函数的积分 - 该曲线下的面积 - 是整个象限中弧的长度。
现在,我们可以用一条直线逼近它:
有渐变 m =(ab)/(Pi / 2)
和 y 拦截 c = b
。使用简单的几何图形,我们可以推断红色曲线下的面积为 A =(a + b)* Pi / 4
。
使用这些知识,并且知道曲线下面的区域是曲线的总长度,构造椭圆近似的问题归结为找到一个(其他正方形也可以,但这是最简单的)红线,使得每个矩形具有相等的面积。 / p>
将该句转换为等式,并用左手边界表示矩形在正交中的位置 x
和它的宽度 w
,我们得到:
(v * m )* w ^ 2 +(m * x + c)* w - A / k == 0
其中 k
是我们想用来逼近象限的数量,而 v
是一个加权函数I很快就会来。这可以通过首先设置 x0 = 0
并解决 w0
来构造正交,然后用它来设置 x1 = w0
并解决 w1
。然后设置 x2 = w1
等等,直到获得所有 k
左边界点。 k + 1
th分界点显然是 Pi / 2
。
权重函数 v
有效地表示矩形穿过红线的位置。一个常数 v = 0.5
就相当于它在中间穿过,并以10分得到这个结果:
但你可以玩与它看什么更好的平衡点。理想情况下,它应该保持在 [0,1]
的范围内,并且您使用的值的总和应该是 k / 2
。
如果你想要一个更好的近似而不用考虑加权函数,你可以尝试使用最小二乘法拟合一条线,而不是仅仅将它拟合到端点,或者你可以尝试拟合一个三次多项式到蓝色曲线而不是线性多项式。这将需要解决四舍五入,但如果你手头有一个数学软件包,这应该不成问题。
This calculates vertex coordinates on ellipse:
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;
}
But how can I calculate the "angle" to get equal or roughly equal circumference segments?
So from what Jozi's said in the OP's comments, what's needed isn't how to subdivide an ellipse into equal segments (which would require a whole bunch of horrible integrals), it's to construct an ellipse from line segments of roughly equal length.
There are a whole pile of ways to do that, but I think the best suited for the OP's purposes would be the concentric circle method, listed on the page as 'the draftman's method'. If you don't mind installing the Mathematica player, there's a neat lil' app here which illustrates it interactively.
The problem with those methods is that the segment lengths are only roughly equal at low eccentricities. If you're dealing in extreme eccentricities, things get a lot more complicated. The simplest solution I can think of is to linearly approximate the length of a line segment within each quadrant, and then solve for the positions of the endpoints in that quadrant exactly.
In detail: this is an ellipse quadrant with parameters a = 5, b = 1
:
And this is a plot of the length of the arc subtended by an infinitesimal change in the angle, at each angle:
The x axis is the angle, in radians, and the y axis is the length of the arc that would be subtended by a change in angle of 1 radian. The formula, which can be derived using the equations in the Wikipedia article I just linked, is y = Sqrt(a^2 Sin^2(x) + b^2 Cos^2(x))
. The important thing to note though is that the integral of this function - the area under this curve - is the length of the arc in the whole quadrant.
Now, we can approximate it by a straight line:
which has gradient m = (a-b) / (Pi/2)
and y intercept c = b
. Using simple geometry, we can deduce that the area under the red curve is A = (a+b)*Pi/4
.
Using this knowledge, and the knowledge that the area under the curve is the total length of the curve, the problem of constructing an approximation to the ellipse reduces to finding say a midpoint-rule quadrature (other quadratures would work too, but this is the simplest) of the red line such that each rectangle has equal area.
Converting that sentence to an equation, and representing the position of a rectangle in a quadrature by it's left hand boundary x
and its width w
, we get that:
(v*m)*w^2 + (m*x+c)*w - A/k == 0
where k
is the number of pieces we want to use to approximate the quadrant, and v
is a weighting function I'll come to shortly. This can be used to construct the quadrature by first setting x0 = 0
and solving for w0
, which is then used to set x1 = w0
and solve for w1
. Then set x2 = w1
, etc etc until you've got all k
left-hand boundary points. The k+1
th boundary point is obviously Pi/2
.
The weighting function v
effectively represents where the rectangle crosses the red line. A constant v = 0.5
is equivalent to it crossing in the middle, and gets you this with 10 points:
but you can play around with it to see what better balances the points. Ideally it should stay in the range [0, 1]
and the sum of the values you use should be k/2
.
If you want an even better approximation without messing around with weighting functions, you could try least-squares fitting a line rather than just fitting it to the endpoints, or you could try fitting a cubic polynomial to the blue curve instead of a linear polynomial. It'll entail solving quartics but if you've a maths package on hand that shouldn't be a problem.
这篇关于如何将椭圆划分成相等的片段?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!