Как можно вписать окружности в грани данного куба?

Рейтинг: 5Ответов: 1Опубликовано: 02.05.2023
import numpy as np
from matplotlib.patches import Ellipse
import matplotlib.pyplot as plt

# Задаем начальные значения углов alpha и beta
alpha_rad, beta_rad = np.radians(int(input("Введіть кут α: "))), np.radians(int(input("Введіть куб β: ")))

# Задаем координаты вершин куба
vertices = np.array([[-1, -1, -1],
                     [1, -1, -1],
                     [1, 1, -1],
                     [-1, 1, -1],
                     [-1, -1, 1],
                     [1, -1, 1],
                     [1, 1, 1],
                     [-1, 1, 1]])

# Отображаем проекцию куба на графике
fig = plt.figure()
ax = fig.add_subplot(111)

# Матрица претворения
transform_matrix = np.dot(
    np.array([[1, 0, 0],
              [0, np.cos(alpha_rad), np.sin(alpha_rad)],
              [0, -np.sin(alpha_rad), np.cos(alpha_rad)]]),
    np.array([[np.cos(beta_rad), 0, -np.sin(beta_rad)],
              [0, 1, 0],
              [np.sin(beta_rad), 0, np.cos(beta_rad)]]))
projected_vertices = np.dot(vertices, transform_matrix)

# Отрисовываем куб для начальных углов и вписываем окружности в грани куба
for i in range(0, 4):
    # Отрисовываем ребра куба
    ax.plot([projected_vertices[i, 0], projected_vertices[(i + 1) % 4, 0]],
            [projected_vertices[i, 1], projected_vertices[(i + 1) % 4, 1]])
    ax.plot([projected_vertices[i + 4, 0], projected_vertices[((i + 1) % 4) + 4, 0]],
            [projected_vertices[i + 4, 1], projected_vertices[((i + 1) % 4) + 4, 1]])
    ax.plot([projected_vertices[i, 0], projected_vertices[i + 4, 0]],
            [projected_vertices[i, 1], projected_vertices[i + 4, 1]])

plt.show()

Проекция куба

Пример результата как должно выглядить вписанная окружность в одной из граней введите сюда описание изображения

Ответы

▲ 7Принят

Раз вы умеете проектировать и рисовать отрезки, то вы умеете проектировать и рисовать ломаные. Тогда самый короткий путь - нарисовать окружности ломанными и нарисовать отрезки этих ломаных.

Я не удержался и отрефакторил ваш код. Так удобнее:

import itertools
import matplotlib.pyplot as plt
import numpy as np


def make_projection(alpha, beta):
    t = np.dot([
        [1, 0             , 0            ],
        [0,  np.cos(alpha), np.sin(alpha)],
        [0, -np.sin(alpha), np.cos(alpha)]
    ], [
        [np.cos(beta), 0, -np.sin(beta)],
        [0           , 1,  0           ],
        [np.sin(beta), 0,  np.cos(beta)]
    ])
    return lambda points: np.dot(points, t)[:, :-1]


def roll_xyz(a, k):
    return np.roll(a, k, axis=1)


def cube_edges():
    vertices = np.array(tuple(itertools.product((-1, 1), repeat=3)))
    for k in range(3):
        vs = roll_xyz(vertices, k)
        for e in zip(vs, vs[vs.shape[0] // 2:]):
            yield np.stack(e)


def cube_circles():
    a = np.linspace(0, 2 * np.pi, num=90);
    c = np.cos(a)
    s = np.sin(a)
    for k in range(3):
        for z in (-1, 1):
            circle = np.stack((c, s, np.full(a.shape, z)), axis=-1)
            yield roll_xyz(circle, k)


def main():
    alpha = np.radians(float(input("Введіть кут α: ")))
    beta  = np.radians(float(input("Введіть кут β: ")))
    proj = make_projection(alpha, beta)

    plt.axis('equal')
    for line in itertools.chain(cube_edges(), cube_circles()):
        plt.plot(*np.transpose(proj(line)))
    plt.show()


main()
$ python cube.py
Введіть кут α: 15
Введіть кут β: 40

введите сюда описание изображения