Как разделить длину окружности эллипса поровну?

Подобные вопросы были задавались и отвечали ранее здесь, но ни один из них не был достаточно простым чтобы я понял. Приведенный ниже код вычисляет точки эллипса с равными угловыми интервалами и суммирует расстояния между соседними точками, чтобы получить приблизительную длину окружности. Затем он делит окружность на 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). Что не так с моей логикой/кодом и как я могу его улучшить?


person absoluteIdiot    schedule 02.06.2017    source источник
comment
Я предполагаю, что математически можно показать, что эллипс, у которого любые два равных угла вырезают одну и ту же часть окружности, должен быть кругом. В этом смысле единственное, что здесь неверно, это то, что вы ожидаете, что равные части окружности будут вырезаны под одинаковыми углами. По коду вроде нормально.   -  person ImportanceOfBeingErnest    schedule 02.06.2017
comment
Большая часть математики на en.wikipedia.org/wiki/Ellipse проходит мимо моей головы, но похоже, что вы (частично) пытаетесь вычислить координаты точек на эллипсе, используя формулу, указанную в параметрическом представлении. Обратите внимание, что здесь указано, что параметр t [...] не является углом [...] с осью X. Так что в лучшем случае ваша переменная angle имеет вводящее в заблуждение имя; в худшем случае вы печатаете значения, которые не имеют ничего общего с данными, которые вы на самом деле ищете.   -  person Kevin    schedule 02.06.2017
comment
Какой код вы использовали для создания этой картинки? Возможно, ошибка в этом коде, а не в том, который вы разместили.   -  person Kevin    schedule 02.06.2017
comment
Попробуйте распечатать расчет расстояния в каждой точке. Я подозреваю, что есть места, где значения взрываются.   -  person stark    schedule 02.06.2017
comment
Ваши расчеты верны, но ваша картина неверна: вы путаете угол, который линия образует с осью x, с углом, который вы используете для параметризации точек эллипса. Это не одно и то же. Например, первая негоризонтальная линия должна соединять начало координат с точкой (5 * cos (радианы (43)), 3 * sin (радианы (43))). Эта линия не имеет угла 43 градуса к горизонтали (фактический угол линии к горизонтали составляет приблизительно 29,2 градуса).   -  person Mark Dickinson    schedule 02.06.2017
comment
Хм; Я должен был сначала прочитать другие комментарии. Что сказал @Kevin.   -  person Mark Dickinson    schedule 02.06.2017
comment
@ Кевин, как ты сказал, я ошибочно предположил, что угол в параметрических уравнениях равен углу с осью X. После исправления новая диаграмма выглядит как эта, что я считаю правильным. Картинки сделаны вручную (не кодом) в Geogebra с выводом ракурсов из программы.   -  person absoluteIdiot    schedule 03.06.2017
comment
@ Марк, как вы сказали, я ошибочно предположил, что угол в параметрических уравнениях равен углу с осью X. После исправления новая диаграмма выглядит как эта, что я считаю правильным.   -  person absoluteIdiot    schedule 03.06.2017


Ответы (2)


Я отвечаю на вопрос, и из комментариев я понял, что сделал неправильное предположение. Код использует параметрические уравнения эллипса для вычисления координат 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, взяв арктангенс координат x и y точки. Это дает результат:

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

Эти углы делят окружность эллипса почти поровну.

person absoluteIdiot    schedule 09.06.2017

Ваша программа делит эллипс на равные дуги длины, а не на равные дуги. На эллипсе это не то же самое. В приведенном ниже коде я добавил расстояние каждого сегмента к выходным данным, чтобы убедиться в этом.

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 в вашем цикле до вашего вычисления. На последнем проходе угол получал дополнительное приращение после выполнения всех вычислений. Я также уменьшил значение приращения, чтобы уменьшить ошибку в конечном результате.

person user7823241    schedule 02.06.2017