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)
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 []
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'))