Esempio n. 1
0
 def addCanvasPolygon(self,
                      ps,
                      color=(0, 0, 0),
                      fill=True,
                      stroke=False,
                      **kwargs):
     polygon = QtGui.QPolygonF()
     for ver in ps:
         polygon.append(QtCore.QPointF(*ver))
     color = [int(c * 255) for c in color]
     pen = QtGui.QPen(QtGui.QColor(*color), 1, PenStile_DashLine)
     self.painter.setPen(pen)
     self.painter.setBrush(QtGui.QColor(0, 0, 0))
     self.painter.drawPolygon(polygon)
Esempio n. 2
0
 def polyClose(self): #make into hot key not button
     if self.measuring_area:
         if self.line_count > 2: #cant make polygon w/ two lines
             self.measuring_area = False
             A = self.A.calcArea()
             self.areaValues = np.append(self.areaValues, A) #add area values
             #draw permanent polygon
             points = [ QtCore.QPointF(x,y) for x,y in zip( self.A.x, self.A.y ) ]
             self.scene.polyItem2 = QGraphicsPolygonItem(QtGui.QPolygonF(points))
             self.scene.polyItem2.setBrush( QtGui.QBrush(QtGui.QColor(255,255,255,127)) )
             if self.scene.polyItem:
                 self.scene.removeItem(self.scene.polyItem) #remove mouseover polygon
                 self.scene.polyItem = False #remove mouseover polygon
             self.scene.removeItem(self.scene.testline)
             self.scene.testline = False
             self.scene.addItem(self.scene.polyItem2) #shade in polygon
             self.parent().statusbar.showMessage('Polygon area measurement completed')
             self.parent().areaButton.setChecked(False)
             self.parent().bezier.setEnabled(True) #make bezier fit available again
         else:
             print("cannot draw polygon with fewer than three vertices")
Esempio n. 3
0
    def mousePressEvent(self, event):
        #http://pyqt.sourceforge.net/Docs/PyQt4/qgraphicsscenemouseevent.html
        #https://stackoverflow.com/questions/21197658/how-to-get-pixel-on-qgraphicspixmapitem-on-a-qgraphicsview-from-a-mouse-click
        data = self.mapToScene(event.pos())

        #draw piecewise lines for non-width measurements
        rules = [self.measuring_length, self.measuring_angle, self.measuring_area]

        if self.scene.testline and self._thispos and any(rules):
            start = self._thispos
            end = QtCore.QPointF(data)

            if self._lastpos and self.measuring_angle:

                a = self._lastpos - self._thispos
                b = data - self._thispos
                a = np.array([a.x(), a.y()])
                b = np.array([b.x(), b.y()])
                self.measuring_angle = False
                t = np.arccos(np.dot(a, b) / (np.linalg.norm(a) * np.linalg.norm(b)))
                t *= 180 / np.pi  #convert to degrees
                self.T.update(t)
                self.angleValues = np.append(self.angleValues,t)
                self.parent().statusbar.showMessage('Angle measurement complete')
                self.parent().angleButton.setChecked(False)
                self.parent().bezier.setEnabled(True)

            self.scene.realline = QGraphicsLineItem(QtCore.QLineF(start, end))
            self.scene.addItem(self.scene.realline)

        #Collect piecewise line start/end points
        self._lastpos = self._thispos  # save old position value
        self._thispos = QtCore.QPointF(data)  # update current position

        if self.measuring_length:
            self.L.update(data.x(), data.y())  # update total length
            self.line_count += 1

        elif self.measuring_area:
            self.line_count += 1
            intersect = False
            if self.line_count > 2: #cant make polygon w/ two lines
                intersect, xi, yi, k = self.A.checkIntersect(data.x(),data.y())
                self.parent().areaButton.setEnabled(True)
            if intersect:
                self.measuring_area = False
                self.A.update(xi,yi) #update with intersect point
                self.A.x, self.A.y = self.A.x[k:], self.A.y[k:] #only use points after intersection
                A = self.A.calcArea()
                self.areaValues = np.append(self.areaValues, A) #add area values
                #draw permanent polygon
                points = [ QtCore.QPointF(x,y) for x,y in zip( self.A.x, self.A.y ) ]
                self.scene.polyItem2 = QGraphicsPolygonItem(QtGui.QPolygonF(points))
                self.scene.polyItem2.setBrush( QtGui.QBrush(QtGui.QColor(255,255,255,127)) )
                self.scene.removeItem(self.scene.polyItem) #remove mouseover polygon
                self.scene.polyItem = False #remove mouseover polygon
                self.scene.addItem(self.scene.polyItem2) #shade in polygon
                self.parent().statusbar.showMessage('Polygon area measurement completed')
                self.parent().areaButton.setChecked(False)
                self.parent().bezier.setEnabled(True) #make bezier fit available again
                QApplication.setOverrideCursor(QtCore.Qt.ArrowCursor)  #change cursor
            else:
                self.A.update(data.x(),data.y()) #update with click point

        #https://stackoverflow.com/questions/30898846/qgraphicsview-items-not-being-placed-where-they-should-be
        if self.measuring_widths:  #measure widths, snap to spines

            k = int(self.k / 2) + 1  #same origin for spine on either side
            x0, y0 = self.xp[k], self.yp[k]
            x1, y1 = data.x(), data.y()

            #perpindicular slopes
            vx = self.slopes[:,k][1]
            vy = -self.slopes[:,k][0]

            A = np.matrix([[vx, -vy], [vy, vx]])
            b = np.array([x1 - x0, y1 - y0])
            t = np.linalg.solve(A,b)

            xi = x0 + t[0]*vx
            yi = y0 + t[0]*vy

            self.W.update(xi,yi)
            p = QtCore.QPointF(xi, yi)

            s = 10  #dot size
            self.scene.ellipseItem = QGraphicsEllipseItem(0, 0, s, s)
            self.scene.ellipseItem.setPos(p.x() - s / 2, p.y() - s / 2)
            qb = QtGui.QBrush()
            qb.setColor(QtGui.QColor('red'))
            self.scene.ellipseItem.setBrush(qb)
            self.scene.ellipseItem.setFlag(
                QGraphicsItem.GraphicsItemFlag.ItemIgnoresTransformations,
                False)  #size stays small, but doesnt translate if false
            self.scene.addItem(self.scene.ellipseItem)
            self.k += 1

            if self.k < self.nspines:
                self.d[str(self.k)].setPen(QtGui.QPen(
                    QtGui.QColor('yellow'))) #Highlight next spine
                    
            if self.k == self.nspines:
                self.parent().statusbar.showMessage('Width measurements complete')
                self.measuring_widths = False
                self.parent().widthsButton.setEnabled(False)
                self.parent().widthsButton.setChecked(False)
                self.parent().bezier.setEnabled(True)
                width = np.sqrt(
                    (self.W.x[1::2] - self.W.x[0::2])**2 +
                    (self.W.y[1::2] - self.W.y[0::2])**2)  #calculate widths
                self.widths[-1] = width
Esempio n. 4
0
    def mouseMoveEvent(self, event):
        data = self.mapToScene(event.position().toPoint())
        rules = [self.measuring_length, self.measuring_angle, self.measuring_area]

        modifiers = QApplication.keyboardModifiers()
        if modifiers == QtCore.Qt.KeyboardModifier.ShiftModifier and self.oldPos:
            QApplication.setOverrideCursor(QtCore.Qt.CursorShape.OpenHandCursor)
            self.newPos = data
            delta = self.newPos - self.oldPos
            self.translate(delta.x(), delta.y())
        elif (any(rules) or self.measuring_widths):
            QApplication.setOverrideCursor(QtCore.Qt.CursorShape.CrossCursor)  #change cursor
        else:
            QApplication.setOverrideCursor(QtCore.Qt.CursorShape.ArrowCursor)  #change cursor   

        #dragging line
        if self._thispos and any(rules):
            if self.measuring_length:
                self.parent().statusbar.showMessage(
                    'Click to place next point... double click to finish')
            if self.measuring_area:
                self.parent().statusbar.showMessage(
                    'Click to place next point... close polygon to finish')
            if self.measuring_angle:
                self.parent().statusbar.showMessage(
                    'Click point to define vector')

            end = QtCore.QPointF(data)#self.mapToScene(event.pos()))
            start = self._thispos

            if self.measuring_angle and self._lastpos:
                start = self._thispos

            if self.scene.testline:  #remove old line
                self.scene.removeItem(self.scene.testline)
                self.scene.testline = False

            if self.measuring_area and self.line_count > 2:
                intersect, xi, yi, k = self.A.checkIntersect(data.x(),data.y())
                if self.scene.area_ellipseItem: #remove existing intersect
                    self.scene.removeItem(self.scene.area_ellipseItem)
                    self.scene.area_ellipseItem = False
                if self.scene.polyItem:
                    self.scene.removeItem(self.scene.polyItem)
                    self.scene.polyItem = False
                if intersect:
                    #indicate intersect point
                    p = QtCore.QPointF(xi, yi)
                    self.scene.area_ellipseItem = QGraphicsEllipseItem(0, 0, 10, 10)
                    self.scene.area_ellipseItem.setPos(p.x() - 10 / 2, p.y() - 10 / 2)
                    self.scene.area_ellipseItem.setBrush(
                    QtGui.QBrush(QtCore.QtColor('blue'))) #, style=QtCore.Qt.BrushStyle.SolidPattern))
                    self.scene.area_ellipseItem.setFlag(
                    QGraphicsItem.GraphicsItemFlag.ItemIgnoresTransformations,
                    False)  #size stays small, but doesnt translate if set to false
                    self.scene.addItem(self.scene.area_ellipseItem)
                    #shade polygon region
                    points = [ QtCore.QPointF(x,y) for x,y in zip( self.A.x[k:], self.A.y[k:] ) ]
                    points.append(QtCore.QPointF(xi,yi))
                    self.scene.polyItem = QGraphicsPolygonItem(QtGui.QPolygonF(points))
                    self.scene.polyItem.setBrush( QtGui.QBrush(QtGui.QColor(255,255,255,127)) )
                    self.scene.addItem(self.scene.polyItem)

            self.scene.testline = QGraphicsLineItem(QtCore.QLineF(start, end))
            self.scene.addItem(self.scene.testline)