Esempio n. 1
0
    def cornerMitre(self, mitreSize=5, isRadius=False):
        # - Calculate unit vectors and shifts
        nextNode = self.getNextOn(False)
        prevNode = self.getPrevOn(False)

        nextUnit = Coord(nextNode.asCoord() - self.asCoord()).unit
        prevUnit = Coord(prevNode.asCoord() - self.asCoord()).unit

        if not isRadius:
            angle = math.atan2(nextUnit | prevUnit, nextUnit & prevUnit)
            radius = abs((float(mitreSize) / 2) / math.sin(angle / 2))
        else:
            radius = mitreSize

        nextShift = nextUnit * radius
        prevShift = prevUnit * radius

        # - Insert Node and process
        nextNode = self.__class__(
            self.insertAfter(.01))  # Was 0?, something went wrong in 6871
        nextNode.smartReloc(
            self.x, self.y)  # Go back because something went wrong in 6871

        self.smartShift(*prevShift.tuple)
        nextNode.smartShift(*nextShift.tuple)
        nextNode.fl.convertToLine()

        return (self.fl, nextNode.fl)
Esempio n. 2
0
    def alignTo(self, entity, alignMode='', align=(True, True)):
        '''Align Abstract nodes container to.
		Arguments:
			entity ()
			alignMode (String) : L(left), R(right), C(center), T(top), B(bottom), E(vertical center) !ORDER MATTERS
		'''

        # - Helper
        def getAlignDict(item):
            align_dict = {
                'L': item.x(),
                'R': item.x() + item.width(),
                'C': item.x() + item.width() / 2,
                'B': item.y(),
                'T': item.y() + item.height(),
                'E': item.y() + item.height() / 2
            }

            return align_dict

        # - Init
        if len(alignMode) == 2:
            alignX, alignY = alignMode.upper()

            # -- Get target for alignment
            if isinstance(
                    entity,
                (fl6.flNode, pNode, eNode, Coord, pqt.QtCore.QPointF)):
                target = Coord(entity.x, entity.y)

            elif isinstance(
                    entity,
                (fl6.flContour,
                 self.__class__)):  #(fl6.flContour, pContour, self.__class__)

                if isinstance(entity, fl6.flContour):
                    temp_entity = self.__class__(fl6.flContour.nodes())
                else:
                    temp_entity = entity

                align_dict = getAlignDict(temp_entity)
                target = Coord(align_dict[alignX], align_dict[alignY])

            # -- Get source for alignment
            align_dict = getAlignDict(self)
            source = Coord(align_dict[alignX], align_dict[alignY])

            # - Process
            shift = source - target
            shift_dx = abs(
                shift.x) * [1, -1][source.x > target.x] if align[0] else 0.
            shift_dy = abs(
                shift.y) * [1, -1][source.y > target.y] if align[1] else 0.

            self.shift(shift_dx, shift_dy)

        else:
            print('ERROR:\t Invalid Align Mode: {}'.format(alignMode))
Esempio n. 3
0
    def cornerRound(self,
                    size=5,
                    proportion=None,
                    curvature=None,
                    isRadius=False):
        # - Calculate unit vectors and shifts
        nextNode = self.getNextOn(False)
        prevNode = self.getPrevOn(False)

        nextUnit = Coord(nextNode.asCoord() - self.asCoord()).unit
        prevUnit = Coord(prevNode.asCoord() - self.asCoord()).unit

        if not isRadius:
            angle = math.atan2(nextUnit | prevUnit, nextUnit & prevUnit)
            radius = abs((float(size) / 2) / math.sin(angle / 2))
        else:
            radius = size

        nextShift = nextUnit * radius
        prevShift = prevUnit * radius

        # - Insert Nodes and process
        nextNode = self.__class__(
            self.insertAfter(.01))  # Was 0?, something went wrong in 6871
        nextNode.smartReloc(
            self.x, self.y)  # Go back because something went wrong in 6871

        self.smartShift(*prevShift.tuple)
        nextNode.smartShift(*nextShift.tuple)

        # -- Make round corner
        nextNode.fl.convertToCurve(True)
        segment = self.getSegmentNodes()

        # -- Curvature and handle length
        curve = Curve(segment)

        if proportion is not None:
            new_curve = curve.solve_proportional_handles(proportion)
            segment[1].x = new_curve.p1.x
            segment[1].y = new_curve.p1.y
            segment[2].x = new_curve.p2.x
            segment[2].y = new_curve.p2.y

        if curvature is not None:
            new_curve = curve.solve_hobby(curvature)
            segment[1].x = new_curve.p1.x
            segment[1].y = new_curve.p1.y
            segment[2].x = new_curve.p2.x
            segment[2].y = new_curve.p2.y

        return segment
Esempio n. 4
0
    def slantShift(self, shift_x, shift_y, angle):
        '''Slanted move - move a node (in inclined space) according to Y coordinate slanted at given angle.
		
		Arguments:
			shift_x, shift_y (float)
			angle (float): Angle in degrees
		'''
        # - Init
        cNode = Coord((self.x + shift_x, self.y))
        cNode.angle = angle

        # - Calculate & set
        newX = cNode.solve_width(cNode.y + shift_y)
        #self.fl.smartSetXY(pqt.QtCore.QPointF(newX, self.y + shift_y))
        self.smartReloc(newX, self.y + shift_y)
Esempio n. 5
0
    def interpShift(self, shift_x, shift_y):
        '''Interpolated move aka Interpolated Nudge.
		
		Arguments:
			shift_x, shift_y (float)
		'''
        if self.isOn:
            # - Init
            shift = Coord(shift_x, shift_y)
            currSegmet, prevSegment = self.getSegment(), self.getSegment(-1)

            if prevSegment == None:
                prevSegment = self.contour.segments()[-1]

            # - Process segments
            if len(currSegmet) == 4:
                currCurve = Curve(currSegmet)
                new_currCurve = currCurve.lerp_first(shift)

                currNode_bcpOut = self.getNext(False)
                nextNode_bcpIn = currNode_bcpOut.getNext(False)
                nextNode = nextNode_bcpIn.getOn(False)

                currSegmetNodes = [
                    self, currNode_bcpOut, nextNode_bcpIn, nextNode
                ]

                # - Set node positions
                for i in range(len(currSegmetNodes)):
                    currSegmetNodes[i].smartReloc(
                        *new_currCurve.points[i].tuple)

            if len(prevSegment) == 4:
                prevCurve = Curve(prevSegment)
                new_prevCurve = prevCurve.lerp_last(shift)

                currNode_bcpIn = self.getPrev(False)
                prevNode_bcpOut = currNode_bcpIn.getPrev(False)
                prevNode = prevNode_bcpOut.getOn(False)

                prevSegmentNodes = [
                    prevNode, prevNode_bcpOut, currNode_bcpIn, self
                ]

                # - Set node positions
                for i in range(len(prevSegmentNodes) - 1, -1, -1):
                    prevSegmentNodes[i].smartReloc(
                        *new_prevCurve.points[i].tuple)

            if len(currSegmet) == 2 and len(prevSegment) == 2:
                self.smartShift(*shift.tuple)
Esempio n. 6
0
    def cornerTrapInc(self, incision=10, depth=50, trap=2, smooth=True):
        '''Trap a corner by given incision into the glyph flesh.
		
		Arguments:
			incision (float): How much to cut into glyphs flesh based from that corner inward;
			depth (float): Length of the traps sides;
			trap (float): Width of the traps bottom;
			smooth (bool): Creates a smooth trap.

		Returns:
			tuple(flNode, flNode, flNode, flNode) four base (ON) nodes of the trap.
		'''
        # - Init
        remains = depth - incision
        base_coord = self.asCoord()

        # - Calculate for aperture postision and structure
        nextNode = self.getNextOn(False)
        prevNode = self.getPrevOn(False)

        nextUnit = Coord(nextNode.asCoord() - self.asCoord()).unit
        prevUnit = Coord(prevNode.asCoord() - self.asCoord()).unit

        angle = math.atan2(nextUnit | prevUnit, nextUnit & prevUnit)
        aperture = abs(2 * (remains / math.sin(math.radians(90) - angle / 2) *
                            math.sin(angle / 2)))
        adjust = float(aperture - trap) / 2
        radius = abs((float(aperture) / 2) / math.sin(angle / 2))

        bCoord = self.asCoord() + (nextUnit * -radius)
        cCoord = self.asCoord() + (prevUnit * -radius)

        aCoord = self.asCoord() + (prevUnit * radius)
        dCoord = self.asCoord() + (nextUnit * radius)

        # - Calculate for depth
        abUnit = Coord(aCoord - bCoord).unit
        dcUnit = Coord(dCoord - cCoord).unit

        bCoord = aCoord + abUnit * -depth
        cCoord = dCoord + dcUnit * -depth

        # - Calculate for trap (size)
        bcUnit = (bCoord - cCoord).unit
        cbUnit = (cCoord - bCoord).unit

        bCoord += bcUnit * -adjust
        cCoord += cbUnit * -adjust

        # - Insert Nodes and cleanup
        b = self.__class__(
            self.insertAfter(0.01))  # .01 quickfix - should be 0
        c = self.__class__(b.insertAfter(0.01))
        d = self.__class__(c.insertAfter(0.01))

        b.fl.convertToLine()
        c.fl.convertToLine()
        d.fl.convertToLine()

        # - Position nodes
        self.smartReloc(*aCoord.tuple)
        b.smartReloc(*bCoord.tuple)
        d.smartReloc(*dCoord.tuple)
        c.smartReloc(*cCoord.tuple)

        # - Make smooth trap transition
        if smooth:
            # -- Convert nodes and extend bpc-s
            b.fl.convertToCurve()
            d.fl.convertToCurve()

            # -- Set nodes as smooth
            self.fl.smooth = True
            d.fl.smooth = True

            # -- Align bpc-s to the virtual lines connection sides of the trap with the original base node
            side_ab = Line(self.asCoord(), base_coord)
            side_cd = Line(base_coord, d.asCoord())
            control = (True, False)

            bpc_a, bpc_c = self.getNext(False), c.getNext(False)
            bpc_b, bpc_d = b.getPrev(False), d.getPrev(False)

            bpc_a.alignTo(side_ab, control)
            bpc_b.alignTo(side_ab, control)
            bpc_c.alignTo(side_cd, control)
            bpc_d.alignTo(side_cd, control)

        return (self.fl, b.fl, c.fl, d.fl)
Esempio n. 7
0
    def cornerTrap(self, aperture=10, depth=20, trap=2):
        '''Trap a corner by given aperture.

		Arguments:
			aperture (float): Width of the traps mouth (opening);
			depth (float): Length of the traps sides;
			trap (float): Width of the traps bottom.

		Returns:
			tuple(flNode, flNode, flNode, flNode)
		'''
        # - Init
        adjust = float(aperture - trap) / 2

        # - Calculate for aperture postision and structure
        nextNode = self.getNextOn(False)
        prevNode = self.getPrevOn(False)

        nextUnit = Coord(nextNode.asCoord() - self.asCoord()).unit
        prevUnit = Coord(prevNode.asCoord() - self.asCoord()).unit

        angle = math.atan2(nextUnit | prevUnit, nextUnit & prevUnit)
        radius = abs((float(aperture) / 2) / math.sin(angle / 2))

        bCoord = self.asCoord() + (nextUnit * -radius)
        cCoord = self.asCoord() + (prevUnit * -radius)

        aCoord = self.asCoord() + (prevUnit * radius)
        dCoord = self.asCoord() + (nextUnit * radius)

        # - Calculate for depth
        abUnit = Coord(aCoord - bCoord).unit
        dcUnit = Coord(dCoord - cCoord).unit

        bCoord = aCoord + abUnit * -depth
        cCoord = dCoord + dcUnit * -depth

        # - Calculate for trap (size)
        bcUnit = (bCoord - cCoord).unit
        cbUnit = (cCoord - bCoord).unit

        bCoord += bcUnit * -adjust
        cCoord += cbUnit * -adjust

        # - Insert Nodes and cleanup
        b = self.__class__(
            self.insertAfter(0.01))  # .01 quickfix - should be 0
        c = self.__class__(b.insertAfter(0.01))
        d = self.__class__(c.insertAfter(0.01))

        b.fl.convertToLine()
        c.fl.convertToLine()
        d.fl.convertToLine()

        # - Position nodes
        self.smartReloc(*aCoord.tuple)
        b.smartReloc(*bCoord.tuple)
        d.smartReloc(*dCoord.tuple)
        c.smartReloc(*cCoord.tuple)

        return (self.fl, b.fl, c.fl, d.fl)
Esempio n. 8
0
 def asCoord(self):
     '''Returns Coord object of the node.'''
     return Coord(float(self.x), float(self.y))
Esempio n. 9
0
 def getCoord(self):
     return [Coord(node) for node in self.nodes]
Esempio n. 10
0
 def asCoord(self):
     '''Returns Coord object of the Bottom lest corner.'''
     return Coord(float(self.x()), float(self.y()))