Рисование эллиптических линий между двумя кругами без пересечения матплотлиба - PullRequest
0 голосов
/ 05 февраля 2019

Я пытаюсь нарисовать эллиптические линии, используя matplotlib для соединения двух окружностей, но хотел бы сделать так, чтобы эллиптические линии не пересекали ни одну из окружностей.

В настоящее время мой дизайн привел к следующему: enter image description here

у которого, как вы можете видеть, есть линии, проходящие как через окружность A, так и B. Я решил использовать matplotlib.patches.Arc, так как не хотел его заполнять, и это позволило мне нарисовать левуюи правая часть.Вот что у меня есть:

from matplotlib import pyplot
from matplotlib.patches import Arc
import math

def calculate_perimeter(a, b):
    perimeter = math.pi * (3*(a+b) - math.sqrt( (3*a + b) * (a + 3*b) ))
    return perimeter

def draw_circle(xy, radius, text):
    circle = pyplot.Circle(xy, radius=radius,     fill=False)
    pyplot.gca().add_patch(circle)
    pyplot.gca().annotate(text, xy=xy,     fontsize=10, ha='center', va='center')

def draw_arc(xy1, xy2, a, b, theta1, theta2):
    # Calculate center of the elliptical arc
    center = (xy1[0], (xy1[1] + xy2[1])/2.0)
    arc = Arc(center, a, b, theta1=theta1, theta2=theta2)
    pyplot.gca().add_patch(arc)

if __name__ == '__main__':
    pyplot.figure()
    center_circle1 = (5, 5)
    center_circle2 = (5, 20)
    dist_y = center_circle2[1] - center_circle1[1]
    adjustment = 5.3 # @TODO: How do I calculate what this needs to be?
    # Circles
    draw_circle(center_circle1, 1, 'A')
    draw_circle(center_circle2, 1, 'B')
    # Draw right side of arc
    theta1 = 270.0 + adjustment
    theta2 = 90.0 - adjustment
    draw_arc(center_circle1, center_circle2, 3, dist_y, theta1, theta2)
    # Draw left side of arc
    theta1 = 90.0 + adjustment
    theta2 = 270.0 - adjustment
    draw_arc(center_circle1, center_circle2, 3, dist_y, theta1, theta2)
    pyplot.axis('scaled')
    pyplot.axis('off')
    pyplot.show()

Например, когда я ставлю adjustment = 5.3, я получаю: enter image description here

Если я увеличу эту область, хотя этоЛегко видеть, что это не совпадает: enter image description here

Тогда возникает мой вопрос: как рассчитать, каким должно быть adjustment

Я думал, что смогубыть в состоянии рассчитать периметр, если я считаю его полным эллипсом и вычту сумму, которая перекрывается в одном из кругов, и использую ее для получения adjustment, но я не уверен, сработает ли это или как рассчитать, сколькоперекрывается внутри.Любая помощь по этому вопросу будет принята.

1 Ответ

0 голосов
/ 05 февраля 2019

Вместо того, чтобы настраивать фигуру вручную, рассмотрите возможность использования zorder в конструкторе Patch.

Различные художники на графике располагаются друг над другом вертикально, с самыми высокими zorderнаверху.Поэтому, установив zorder, вы заставите круги рисовать над эллипсом, затеняя его.

Пример кода:

from matplotlib import pyplot as plt
from matplotlib.patches import Circle, Arc

fig, ax = plt.subplots(figsize=(6, 6))

ax.add_patch(Circle((0.5, 0.75), 0.05, edgecolor='black', facecolor='white', zorder=3))
ax.add_patch(Circle((0.5, 0.25), 0.05, edgecolor='black', facecolor='white', zorder=3))
ax.add_patch(Arc((0.5, 0.5), 0.1, 0.5))

, который генерирует

this.

...