如何平均分割椭圆的周长?

时间:2017-06-02 17:43:43

标签: python math geometry ellipse

以前类似的问题是asked and answered,但没有一个简单易于理解。下面的代码以相等的角度间隔计算椭圆的点,并将相邻点之间的距离相加以得到近似的周长。然后它将圆周划分为10个假设相等的弧,并输出由分割点产生的角度。

from math import sqrt,cos,sin,radians

def distance(x1,y1,x2,y2):
    return sqrt((x2-x1)**2 + (y2-y1)**2)

a = 5
b = 3
x0 = a
y0 = 0
angle = 0
d = 0
while(angle<=360):
    x = a * cos(radians(angle))
    y = b * sin(radians(angle))
    d += distance(x0,y0,x,y)
    x0 = x
    y0 = y
    angle += 0.25
print "Circumference of ellipse = %f" %d
onetenth = d/10
angle = 0
x0 = a
y0 = 0
angle0 = 0.25
for i in range(10):
    dist = 0
    while(dist<onetenth):
        x = a * cos(radians(angle))
        y = b * sin(radians(angle))
        dist += distance(x0,y0,x,y)
        x0 = x
        y0 = y
        angle += 0.25
    print "%d : angle = %.2f\tdifference = %.2f" %(i+1,angle-0.25, angle-angle0)
    angle0 = angle

它给出了输出:

Circumference of ellipse = 25.526979
1 : angle = 43.00       difference = 43.00
2 : angle = 75.50       difference = 32.50
3 : angle = 105.00      difference = 29.50
4 : angle = 137.50      difference = 32.50
5 : angle = 180.75      difference = 43.25
6 : angle = 223.75      difference = 43.00
7 : angle = 256.00      difference = 32.25
8 : angle = 285.50      difference = 29.50
9 : angle = 318.00      difference = 32.50
10 : angle = 361.50     difference = 43.50

但是这些角度不能平均分割圆周(picture)。我的逻辑/代码有什么问题,如何改进呢?

2 个答案:

答案 0 :(得分:1)

我是问题的OP,我从评论中意识到我做了一个错误的假设。该代码利用椭圆的参数方程来计算x和y坐标。参数方程中的角度不是x轴的角度。我假设它们在代码中是相同的。更正的代码是

from math import sqrt,cos,sin,atan2,radians,degrees

def distance(x1,y1,x2,y2):
    return sqrt((x2-x1)**2 + (y2-y1)**2)

a = 5
b = 3
x0 = a
y0 = 0
angle = 0
d = 0
while(angle<=360):
    x = a * cos(radians(angle))
    y = b * sin(radians(angle))
    d += distance(x0,y0,x,y)
    x0 = x
    y0 = y
    angle += 0.25
print "Circumference of ellipse = %f" %d
onetenth = d/10
angle = 0
x0 = a
y0 = 0
angle0 = 0
for i in range(10):
    dist = 0
    while(dist<onetenth):
        x = a * cos(radians(angle))
        y = b * sin(radians(angle))
        dist += distance(x0,y0,x,y)
        x0 = x
        y0 = y
        angle += 0.25
    xangle = degrees(atan2(y,x))
    print "%d : angle = %.2f\tdifference = %.2f" %(i+1, xangle, xangle-angle0)
    angle0 = xangle

通过获取点的x和y坐标的反正切来计算与x轴的角度。它给出了输出:

Circumference of ellipse = 25.526979
1 : angle = 29.23       difference = 29.23
2 : angle = 66.68       difference = 37.46
3 : angle = 114.06      difference = 47.38
4 : angle = 151.20      difference = 37.13
5 : angle = -179.55     difference = -330.75
6 : angle = -150.13     difference = 29.42
7 : angle = -112.57     difference = 37.56
8 : angle = -65.19      difference = 47.37
9 : angle = -28.38      difference = 36.81
10 : angle = 0.90       difference = 29.28

这些角度划分椭圆almost equally的圆周。

答案 1 :(得分:0)

您的程序将椭圆划分为相等的弧长度,而不是等于弧。在椭圆上,这是不一样的。在下面的代码中,我添加了每个段到输出的距离来验证这一点。

from math import sqrt,cos,sin,radians

def distance(x1,y1,x2,y2):
    return sqrt((x2-x1)**2 + (y2-y1)**2)

a = 5
b = 3
x0 = a
y0 = 0
angle = 0
d = 0
while(angle<=360):
    x = a * cos(radians(angle))
    y = b * sin(radians(angle))
    d += distance(x0,y0,x,y)
    x0 = x
    y0 = y
    angle += 0.25
print("Circumference of ellipse = {:f}".format(d))
onetenth = d/10
angle = 0
x0 = a
y0 = 0
angle0 = 0
for i in range(10):
    dist = 0
    while(dist<onetenth):
        angle += 0.025
        x = a * cos(radians(angle))
        y = b * sin(radians(angle))
        dist += distance(x0,y0,x,y)
        x0 = x
        y0 = y

    print(
        "{} : angle = {:.2f}\tdifference = {:.2f}\tDistance {:.2f}"
        .format(i+1,angle, angle-angle0,dist))
    angle0 = angle

示例输出:

Circumference of ellipse = 25.526979
1 : angle = 42.99   difference = 42.99  Distance 2.55
2 : angle = 75.27   difference = 32.28  Distance 2.55
3 : angle = 104.73  difference = 29.46  Distance 2.55
4 : angle = 137.01  difference = 32.28  Distance 2.55
5 : angle = 180.01  difference = 42.99  Distance 2.55
6 : angle = 223.00  difference = 42.99  Distance 2.55
7 : angle = 255.28  difference = 32.28  Distance 2.55
8 : angle = 284.74  difference = 29.46  Distance 2.55
9 : angle = 317.02  difference = 32.28  Distance 2.55
10 : angle = 360.02 difference = 43.00  Distance 2.55

请注意,如果将椭圆更改为圆(即a = b = 5),则角度和距离会变得均匀:

Circumference of ellipse = 31.415902
1 : angle = 36.00   difference = 36.00  Distance 3.14
2 : angle = 72.00   difference = 36.00  Distance 3.14
3 : angle = 108.00  difference = 36.00  Distance 3.14
4 : angle = 144.00  difference = 36.00  Distance 3.14
5 : angle = 180.00  difference = 36.00  Distance 3.14
6 : angle = 216.00  difference = 36.00  Distance 3.14
7 : angle = 252.00  difference = 36.00  Distance 3.14
8 : angle = 288.00  difference = 36.00  Distance 3.14
9 : angle = 324.00  difference = 36.00  Distance 3.14
10 : angle = 360.00 difference = 36.00  Distance 3.14

我还对代码进行了一些小的调整。首先,我将循环中 angle 变量的增量移动到计算之前。在最后一次传递中,角度在所有计算发生后获得额外增量。我还将增量值设置得更小,以减少最终结果中的错误。