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

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

Но эти углы не делят окружность одинаково ( изображение ). Что не так с моей логикой / кодом и как я могу его улучшить?

Я являюсь ОП вопроса, и из комментариев я понял, что сделал неправильное предположение. В коде используются параметрические уравнения эллипса для вычисления координат x и y. Угол в параметрических уравнениях не является углом, созданным с осью х. Я предположил, что они одинаковы в коде. Исправленный код

 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 в 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 в 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 

Он вычисляет угол с осью х, принимая дугу касательной координат точки х и у. Он дает результат:

 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 

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

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

 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 в 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 в 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 

Я также сделал пару небольших корректировок кода. Во-первых, я перемещал приращение переменной угла в вашем цикле до вашего вычисления. На заключительном проходе угол получал дополнительный прирост после всех вычислений. Я также сделал значение приращения меньше, чтобы уменьшить ошибку в конечном результате.