示例#1
0
    def convertRToCenter(cls, start: QVector3D, end: QVector3D, radius: float,
                         absoluteIJK: bool, clockwise: bool) -> QVector3D:
        R = radius
        center = QVector3D()

        x = end.x() - start.x()
        y = end.y() - start.y()

        h_x2_div_d = 4 * R * R - x * x - y * y
        if h_x2_div_d < 0:
            print("Error computing arc radius.")

        h_x2_div_d = (-math.sqrt(h_x2_div_d)) / math.hypot(x, y)

        if not clockwise:
            h_x2_div_d = -h_x2_div_d

        # Special message from gcoder to software for which radius
        # should be used.
        if R < 0:
            h_x2_div_d = -h_x2_div_d
            # TODO: Places that use this need to run ABS on radius.
            radius = -radius

        offsetX = 0.5 * (x - (y * h_x2_div_d))
        offsetY = 0.5 * (y + (x * h_x2_div_d))

        if not absoluteIJK:
            center.setX(start.x() + offsetX)
            center.setY(start.y() + offsetY)
        else:
            center.setX(offsetX)
            center.setY(offsetY)

        return center
示例#2
0
    def getAngle(cls, start: QVector3D, end: QVector3D) -> float:
        '''
        Return the angle in radians when going from start to end.
        '''
        deltaX = end.x() - start.x()
        deltaY = end.y() - start.y()

        angle = 0.0

        if deltaX != 0:  # prevent div by 0
            # it helps to know what quadrant you are in
            if deltaX > 0 and deltaY >= 0:  # 0 - 90
                angle = math.atan(deltaY / deltaX)
            elif deltaX < 0 and deltaY >= 0:  # 90 to 180
                angle = cls.M_PI - math.fabs(math.atan(deltaY / deltaX))
            elif deltaX < 0 and deltaY < 0:  # 180 - 270
                angle = cls.M_PI + math.fabs(math.atan(deltaY / deltaX))
            elif deltaX > 0 and deltaY < 0:  # 270 - 360
                angle = cls.M_PI * 2 - math.fabs(math.atan(deltaY / deltaX))
        else:
            # 90 deg
            if deltaY > 0:
                angle = cls.M_PI / 2.0
            #270 deg
            else:
                angle = cls.M_PI * 3.0 / 2.0

        return angle
示例#3
0
    def generatePointsAlongArcBDring_Arc(
            cls, plane: PointSegment.Plane, start: QVector3D, end: QVector3D,
            center: QVector3D, clockwise: bool, R: float, minArcLength: float,
            arcPrecision: float, arcDegreeMode: bool) -> List[QVector3D]:
        '''
        Generates the points along an arc including the start and end points.
        '''
        radius = R

        # Rotate vectors according to plane
        m = QMatrix4x4()
        m.setToIdentity()
        if plane == PointSegment.Plane.XY:
            pass
        elif plane == PointSegment.Plane.ZX:
            m.rotate(90, 1.0, 0.0, 0.0)
        elif plane == PointSegment.Plane.YZ:
            m.rotate(-90, 0.0, 1.0, 0.0)

        start = m * start
        end = m * end
        center = m * center

        # Check center
        if qIsNaN(center.length()):
            return []

        # Calculate radius if necessary.
        if radius == 0:
            radius = math.sqrt(
                math.pow((start.x() - center.x(), 2.0) +
                         math.pow(end.y() - center.y(), 2.0)))

        startAngle = cls.getAngle(center, start)
        endAngle = cls.getAngle(center, end)
        sweep = cls.calculateSweep(startAngle, endAngle, clockwise)

        # Convert units.
        arcLength = sweep * radius

        numPoints = 0

        if arcDegreeMode and arcPrecision > 0:
            numPoints = max(1.0, sweep / (cls.M_PI * arcPrecision / 180))
        else:
            if arcPrecision <= 0 and minArcLength > 0:
                arcPrecision = minArcLength

            numPoints = math.ceil(arcLength / arcPrecision)

        return cls.generatePointsAlongArcBDring_Num(plane, start, end, center,
                                                    clockwise, radius,
                                                    startAngle, sweep,
                                                    numPoints)
示例#4
0
    def generatePointsAlongArcBDring_Num(cls, plane: PointSegment.Plane,
                                         p1: QVector3D, p2: QVector3D,
                                         center: QVector3D, isCw: bool,
                                         radius: float, startAngle: float,
                                         sweep: float,
                                         numPoints: int) -> List[QVector3D]:
        '''
        Generates the points along an arc including the start and end points.
        '''
        # Prepare rotation matrix to restore plane
        m = QMatrix4x4()
        m.setToIdentity()

        if plane == PointSegment.plane.XY:
            pass
        elif plane == PointSegment.plane.ZX:
            m.rotate(-90, 1.0, 0.0, 0.0)
        elif plane == PointSegment.plane.YZ:
            m.rotate(90, 0.0, 1.0, 0.0)

        lineEnd = QVector3D(p2.x(), p2.y(), p1.z())
        segments = []
        angle = 0.0

        # Calculate radius if necessary.
        if radius == 0:
            radius = math.sqrt(
                math.pow((p1.x() - center.x()), 2.0) +
                math.pow((p1.y() - center.y()), 2.0))

        zIncrement = (p2.z() - p1.z()) / numPoints

        for i in range(numPoints):
            if isCw:
                angle = (startAngle - i * sweep / numPoints)
            else:
                angle = (startAngle + i * sweep / numPoints)

            if angle >= cls.M_PI * 2:
                angle = angle - cls.M_PI * 2

            lineEnd.setX(math.cos(angle) * radius + center.x())
            lineEnd.setY(math.sin(angle) * radius + center.y())
            lineEnd.setZ(lineEnd.z() + zIncrement)

            segments.append(m * lineEnd)

        segments.append(m * p2)

        return segments
示例#5
0
    def addLinearPointSegment(self, nextPoint: QVector3D, fastTraverse: bool) -> PointSegment:
        ps = PointSegment.PointSegment_FromQVector3D(nextPoint, self.m_commandNumber)

        self.m_commandNumber += 1

        zOnly = False

        # Check for z-only
        if (self.m_currentPoint.x() == nextPoint.x()) and \
           (self.m_currentPoint.y() == nextPoint.y()) and \
           (self.m_currentPoint.z() != nextPoint.z()) : \
            zOnly = True

        ps.setIsMetric(self.m_isMetric)
        ps.setIsZMovement(zOnly)
        ps.setIsFastTraverse(fastTraverse)
        ps.setIsAbsolute(self.m_inAbsoluteMode)
        ps.setSpeed(self.m_traverseSpeed if fastTraverse else self.m_lastSpeed)
        ps.setSpindleSpeed(self.m_lastSpindleSpeed)
        self.m_points.append(ps)

        # Save off the endpoint.
        self.m_currentPoint = nextPoint

        return ps
示例#6
0
    def createCircle(self, center: QVector3D, radius: float, arcs: int,
                     color: QVector3D) -> List[VertexData]:
        # Vertices
        circle: List[VertexData] = []

        # Prepare vertex
        vertex = VertexData()

        vertex.color = color
        vertex.start = QVector3D(sNaN, sNaN, sNaN)

        # Create line loop
        for i in range(self.arcs + 1):
            angle = 2 * M_PI * i / self.arcs
            x = center.x() + radius * math.cos(angle)
            y = center.y() + radius * math.sin(angle)

            if i > 1:
                circle.append(VertexData.clone(circle[-1]))
            elif i == self.arcs:
                circle.append(VertexData.clone(circle[0]))

            vertex.position = QVector3D(x, y, center.z())
            circle.append(VertexData.clone(vertex))

        return circle
示例#7
0
    def generateG1FromPoints(cls, start: QVector3D, end: QVector3D,
                             absoluteMode: bool, precision: int) -> str:
        sb = "G1"

        if absoluteMode:
            if not qIsNaN(end.x()):
                sb.append("X" + "%.*f" % (precision, end.x()))
            if not qIsNaN(end.y()):
                sb.append("Y" + "%.*f" % (precision, end.y()))
            if not qIsNaN(end.z()):
                sb.append("Z" + "%.*f" % (precision, end.z()))
        else:
            if not qIsNaN(end.x()):
                sb.append("X" + "%.*f" % (precision, end.x() - start.x()))
            if not qIsNaN(end.y()):
                sb.append("Y" + "%.*f" % (precision, end.y() - start.y()))
            if not qIsNaN(end.z()):
                sb.append("Z" + "%.*f" % (precision, end.z() - start.z()))

        return sb
示例#8
0
    def PointSegment_FromVectorQVector3DQVector3D(cls, point: QVector3D,
                                                  num: int, center: QVector3D,
                                                  radius: float,
                                                  clockwise: bool):
        this = PointSegment(point, num)

        this.m_isArc = True
        this.m_arcProperties = ArcProperties()
        this.m_arcProperties.center = QVector3D(center.x(), center.y(),
                                                center.z())
        this.m_arcProperties.radius = radius
        this.m_arcProperties.isClockwise = clockwise
示例#9
0
    def updatePointWithCommand_FromVector3D(cls, initial: QVector3D, x: float,
                                            y: float, z: float,
                                            absoluteMode: bool) -> QVector3D:
        '''
        Update a point given the new coordinates.
        '''
        newPoint = QVector3D(initial.x(), initial.y(), initial.z())

        if absoluteMode:
            if not qIsNaN(x): newPoint.setX(x)
            if not qIsNaN(y): newPoint.setY(y)
            if not qIsNaN(z): newPoint.setZ(z)
        else:
            if not qIsNaN(x): newPoint.setX(newPoint.x() + x)
            if not qIsNaN(y): newPoint.setY(newPoint.y() + y)
            if not qIsNaN(z): newPoint.setZ(newPoint.z() + z)

        return newPoint
示例#10
0
 def calculateVolume(self, size: QtGui.QVector3D) -> float:
     return size.x() * size.y() * size.z()
示例#11
0
    def PointSegment_FromQVector3D(cls, b: QVector3D, num: int):
        this = PointSegment()
        this.m_point = QVector3D(b.x(), b.y(), b.z())
        this.m_lineNumber = num

        return this
示例#12
0
 def _(self, p3d: QVector3D):
     self.testExtremes(p3d.x(), p3d.y(), p3d.z())
示例#13
0
 def cloneQVector3D(cls, v: QVector3D) -> QVector3D:
     ''' faster as deepcopy '''
     return QVector3D(v.x(), v.y(), v.z())