예제 #1
0
def step_15(flag: int, i: int, q: QPoint, line: QLine, r1: QPoint, r2: QPoint,
            cutter: Rect):
    # проверка вертикальности отрезка
    if line.x1() == line.x2():
        return step_23(flag, i, q, line, r1, r2, cutter, 1e30)

    m = (line.y2() - line.y1()) / (line.x2() - line.x1())

    # step 17
    if q.x() < cutter.left():
        y = m * (cutter.left() - q.x()) + q.y()

        # обнаружено корректное пересечение
        if cutter.bottom() <= y <= cutter.top():
            if i == 1:
                r1.setX(cutter.left())
                r1.setY(y)
            else:
                r2.setX(cutter.left())
                r2.setY(y)

            # проверка пересечения с левым краем
            return step_12(flag, i, line, r1, r2, cutter)

    # step 20
    if q.x() > cutter.right():
        y = m * (cutter.right() - q.x()) + q.y()

        # обнаружено корректное пересечение
        if cutter.bottom() <= y <= cutter.top():
            if i == 1:
                r1.setX(cutter.right())
                r1.setY(y)
            else:
                r2.setX(cutter.right())
                r2.setY(y)

            # проверка пересечения с правым крааем
            return step_12(flag, i, line, r1, r2, cutter)

    return step_23(flag, i, q, line, r1, r2, cutter, m)
예제 #2
0
def cut_one(line: QLine, count):
    # Вычисление директрисы заданного отрезка:
    # D = P_2-P_1
    d = QPointF(line.x2() - line.x1(), line.y2() - line.y1())

    # Инициализация пределов значений параметра t при условии,
    # что отрезок полностью видим:
    # t_н=0,t_к=1
    top = 0
    bottom = 1

    # Начало цикла по всем сторонам отсекателя.
    # Для каждой i-ой стороны отсекателя выполнить следующие действия:
    for i in range(-2, count - 2):
        # Вычисление вектора внутренней нормали к очередной
        # i-ой стороне отсекателя - N_вi
        norm = normal(wind.cutter[i], wind.cutter[i + 1], wind.cutter[i + 2])

        # Вычисление вектора W_i=P_1-f_i (f_i берем за вершины стороны)
        w = QPointF(line.x1() - wind.cutter[i].x(),
                    line.y1() - wind.cutter[i].y())

        # Вычисление скалярного произведения векторов:
        # W_iскал=W_i N_вi
        # D_скал=DN_вi
        d_scal = scalar_mult(d, norm)
        w_scal = scalar_mult(w, norm)

        # Если D_скал=0, Если W_скi>0, то отрезок
        # (точка) видим(-а) относительно текущей стороны отсекателя
        if d_scal == 0:
            if w_scal < 0:
                return []
            else:
                continue

        # Вычисление параметра t:
        # t=-W_iскал/D_скал
        t = -w_scal / d_scal

        if d_scal > 0:
            if t <= 1:
                top = max(top, t)
            else:
                return
        elif d_scal < 0:
            if t >= 0:
                bottom = min(bottom, t)
            else:
                return

        # Проверка фактической видимости отсечённого отрезка. Если t_н > t_в, то выход
        if top > bottom:
            break

    # Проверка фактической видимости отсечённого отрезка.
    #  Если t_н≤t_в, то изобразить отрезок в
    #  интервале от P(t_н ) до P(t_в ).
    if top <= bottom:
        return QLine(round(line.x1() + d.x() * top),
                     round(line.y1() + d.y() * top),
                     round(line.x1() + d.x() * bottom),
                     round(line.y1() + d.y() * bottom))

    return []
예제 #3
0
class NGL_Line(NGL_Base):
    """
    NGL_Line(NGL_Base)
    Provides a embedded NGL library line widget.
    """

    # Signal used to indicate changes to the status of the widget.
    valueChanged = pyqtSignal(QLine)

    def __init__(self, parent=None):
        """ Constructor for ngl widget """
        super(NGL_Line, self).__init__(parent)

        self._line = QLine(0, 0, 150, 150)
        self._static = True
        self.update()

    def paintEvent(self, event):
        """ Paint ngl widget event """
        p = QPainter()
        p.begin(self)
        p.drawLine(self._line)
        p.end()

    def sizeHint(self):
        """ Return Qt sizeHint """
        return self._size()

    def _size(self):
        width = abs(self._line.x2() - self._line.x1()) + 1
        height = abs(self._line.y2() - self._line.y1()) + 1
        return QSize(width, height)

    def update(self):
        self._size_update()
        super(NGL_Line, self).update()

    def _size_update(self):
        """ Size update for widget """
        w = self._size().width()
        h = self._size().height()

        self.setMinimumSize(w, h)
        self.setMaximumSize(w, h)

    # # Provide getter and setter methods for the property.
    @pyqtProperty(QPoint)
    def P1(self):
        return self._line.p1()

    @P1.setter
    def P1(self, point):
        self._line.setP1(point)
        self.update()

    # Provide getter and setter methods for the property.
    @pyqtProperty(QPoint)
    def P2(self):
        return self._line.p2()

    @P2.setter
    def P2(self, point):
        self._line.setP2(point)
        self.update()

    def doNGLCode(self, **kwargs):
        template = 'NGL_GP_DrawLine({x0}, {y0}, {x1}, {y1}, {color});'

        # convert coordinates
        g = self._ngl_geometry()

        y1 = self._ngl_y(self.P1.y(), g.height() - 1)
        y2 = self._ngl_y(self.P2.y(), g.height() - 1)

        return template.format(
            x0 = g.x(),
            y0 = g.y() + y1,
            x1 = g.x() + g.width() - 1,
            y1 = g.y() + y2,
            color = self._ngl_color('color: rgb'))