Нарисуйте прямоугольник под углом - PullRequest
0 голосов
/ 20 ноября 2018

Как я могу изменить приведенный ниже код, чтобы drawRect также принимал параметр angle?

(x, y) представляет центроид. Как я понимаю, я бы хотел определить координаты четырех углов, а затем повернуть их на (x, y) на столько градусов, сохраняя при этом одинаковое расстояние.

# draw a line from a to b
def line(a, b):
  # [code omitted]

def drawRect(x, y, w, h):
    a = (x - w / 2, y - h / 2)
    b = (x + w / 2, y - h / 2)
    c = (x + w / 2, y + h / 2)
    d = (x - w / 2, y + h / 2)
    line(a, b)
    line(b, c)
    line(c, d)
    line(d, a)

Ответы [ 3 ]

0 голосов
/ 20 ноября 2018

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

class rotate:
    def __init__(self, degrees):
        angle = math.radians(degrees)
        self.sin = math.sin(angle)
        self.cos = math.cos(angle)

    def pt(self, x, y):
        return x * self.cos + y * self.sin, y * self.cos - x * self.sin

def drawRect(x, y, w, h, degrees):
    rot = rotate(degrees)
    x1, y1 = rot.pt(-w / 2, -h / 2)
    a = x + x1, y + y1
    x2, y2 = rot.pt( w / 2, -h / 2)
    b = x + x2, y + y2
    x3, y3 = rot.pt( w / 2,  h / 2)
    c = x + x3, y + y3
    x4, y4 = rot.pt(-w / 2,  h / 2)
    d = x + x4, y + y4
    line(a, b)
    line(b, c)
    line(c, d)
    line(d, a)
0 голосов
/ 20 ноября 2018

Я бы использовал numpy, так как он допускает гораздо более удобный массив - и в этом случае матричные вычисления.

import numpy as np

Сначала вы можете определить функцию вращения, которая принимает уголв градусах и возвращает соответствующую матрицу вращения:

def rot(phi):
  phi = np.deg2rad(phi)
  return np.array([[np.cos(phi), -np.sin(phi)], [np.sin(phi), np.cos(phi)]])

Затем вы можете добавить вращение к вашей функции, например:

def drawRect(x, y, w, h, angle):
    a = np.array((-w / 2, -h / 2))
    b = np.array((w / 2, -h / 2))
    c = np.array((w / 2, h / 2))
    d = np.array((-w / 2, h / 2))
    if angle != 0:
        a = np.matmul(rot(angle), a)
        b = np.matmul(rot(angle), b)
        c = np.matmul(rot(angle), c)
        d = np.matmul(rot(angle), d)
    a += [x, y]
    b += [x, y]
    c += [x, y]
    d += [x, y]
    line(a, b)
    line(b, c)
    line(c, d)
    line(d, a)
0 голосов
/ 20 ноября 2018

Другое возможное решение (а также не проверенное):

from math import cos, sin, pi
def drawRect(x, y, w, h, angle):
    x_vec = (cos(angle), sin(angle))
    y_vec = (cos(angle+pi/2.0), sin(angle+pi/2.0))
    a = (x - x_vec[0]*w/2 - y_vec[0]*h/2, y - x_vec[1]*w/2 - y_vec[1]*h/2)
    b = (x + x_vec[0]*w/2 + y_vec[0]*h/2, y - x_vec[1]*w/2 - y_vec[1]*h/2)
    c = (x + x_vec[0]*w/2 + y_vec[0]*h/2, y + x_vec[1]*w/2 + y_vec[1]*h/2)
    d = (x - x_vec[0]*w/2 - y_vec[0]*h/2, y + x_vec[1]*w/2 + y_vec[1]*h/2)
    line(a, b)
    line(b, c)
    line(c, d)
    line(d, a)
...