Рисование эллипса под углом между двумя точками в Python

Я пытаюсь нарисовать эллипс между двумя точками. Пока у меня это в основном работает:

Проблема связана с установкой высоты эллипса (ellipse_h ниже).

    x = center_x + radius*np.cos(theta+deg)
    y = center_y - ellipse_h * radius*np.sin(theta+deg)

В этом примере установлено значение -0,5:

Может ли кто-нибудь помочь мне повернуть высоту эллипса с помощью эллипса? Спасибо!

import numpy as np
import matplotlib.pyplot as plt

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

def midpoint(x1, y1, x2,  y2):
    return [(x1 + x2) / 2,(y1 + y2) / 2]

def angle(x1, y1, x2, y2):
    #radians
    return np.arctan2(y2 - y1, x2 - x1)

x1 = 100
y1 = 150
x2 = 200
y2 = 190
ellipse_h = -1
x_coords = []
y_coords = []

mid = midpoint(x1, y1, x2, y2)
center_x = mid[0]
center_y = mid[1]
ellipse_resolution = 40
step = 2*np.pi/ellipse_resolution

radius = distance(x1, y1, x2, y2) * 0.5
deg = angle(x1, y1, x2, y2)
cos = np.cos(deg * np.pi /180)
sin = np.sin(deg * np.pi /180)

for theta in np.arange(0, np.pi+step, step):
    x = center_x + radius*np.cos(theta+deg)
    y = center_y - ellipse_h * radius*np.sin(theta+deg)
    x_coords.append(x)
    y_coords.append(y)

plt.xlabel("X")
plt.ylabel("Y")
plt.title("Arc between 2 Points")

plt.plot(x_coords,y_coords)
plt.scatter([x1,x2],[y1,y2])
plt.axis('equal')

plt.show()

y2 должно быть 190 согласно вашему графику

Yacola 18.01.2023 03:00
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
2
1
70
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Простое решение — описать эллипс его стандартным параметрическим уравнением , как вы эффективно сделали. Однако, если предположить, что он центрирован в начале системы координат, становится просто применить вращение к его точкам, используя 2-мерную матрицу вращения, и, наконец, применить сдвиг, чтобы расположить его в его истинном центре. Это дает следующее:

import numpy as np
import matplotlib.pyplot as plt

# extreme points along the major axis
x1, y1 = 100, 150
x2, y2 = 200, 190

# along minor axis 
height = 15 

# number of points
n = 100

# center
x_c, y_c = (x1 + x2)/2, (y1 + y2)/2

# width (major axis) and height (minor) of the ellipse halved
a, b = np.sqrt((x2 - x1)**2 + (y2 - y1)**2)/2, height/2

# rotation angle
angle = np.arctan2(y2 - y1, x2 - x1)

# standard parametric equation of an ellipse
t = np.linspace(0, 2*np.pi, n)
ellipse = np.array([a*np.cos(t), b*np.sin(t)])  

# 2d rotation matrix
R = np.array([[np.cos(angle), -np.sin(angle)],
              [np.sin(angle),  np.cos(angle)]])  

# apply the rotation to the ellipse
ellipse_rot = R @ ellipse

plt.plot(x_c + ellipse_rot[0], y_c + ellipse_rot[1], 'r' ) 
plt.scatter([x1, x2], [y1, y2], color='k')
plt.axis('equal')
plt.show()

Смотрите вывод для разных высот:

Следуя вашему комментарию, для предельного случая круга нужно указать height = np.sqrt((x2 - x1)**2 + (y2 - y1)**2), чтобы a = b.

Надеюсь это поможет !

Невероятно, спасибо!! Есть ли простой способ определить, на какой высоте будет идеальный круг?

Dr. Pontchartrain 18.01.2023 03:24

Это так полезно, спасибо. Пробовал рисовать height = np.sqrt((x2 - x1)**2 + (y2 - y1)**2)/2 , но вот что получилось: imgur.com/a/iHWdUnt

Dr. Pontchartrain 18.01.2023 03:34

Другие вопросы по теме