Ejemplo n.º 1
0
def boundingDiamond(wid=50, inner=1500, owid=250, outer=2250, left="Left", right="Right", center="Center", centeru="?"):
    print "boundingDiamond"
    toReturn = Shape([])
    
    v = Vector(1,1)
    w = Vector(1,-1)
    
    oo = outer/2.
    oi = (outer - owid)/2.
    
#    print outer, wid, outer-wid
#    print oo, oi

    m = (Matrix(1, -1, 1, 1)/math.sqrt(2))

    rect1 = Polyline([v*oo, w*oo, -v*oo, -w*oo, v*oo, v*oi, -w*oi, -v*oi, w*oi, v*oi], True, False, 3)*m;
    
    oo = inner/2.
    oi = (inner - wid)/2.
    rect2 = Polyline([v*oo, w*oo, -v*oo, -w*oo, v*oo, v*oi, -w*oi, -v*oi, w*oi, v*oi], True, False, 3)

    toReturn.add(rect(Vector(-inner/2, -inner/3), Vector(-inner/2 + wid, inner/3)).setMaterial(3))
    toReturn.add(rect(Vector(inner/2, -inner/3), Vector(inner/2 - wid, inner/3)).setMaterial(3))
    if centeru[0] != '?':
        toReturn.add(rect(Vector(-inner/3, inner/2-wid), Vector(inner/3, inner/2)).setMaterial(3))
    toReturn.add(rect(Vector(-inner/3, -inner/2+wid), Vector(inner/3, -inner/2)).setMaterial(3))

#    rect1 = (rect(v*(-oi), v*oi)).add(rect(v*(-oo), v*oo))

#    print rect1

#    toReturn.add(rect(v*(-oi), v*oi));
#    toReturn.add(rect(v*(-oo), v*oo));

    toReturn.add(rect1.setMaterial(3))
#    toReturn.add(rect2)

    toReturn.add((font.shapeFromStringBoundedCentered(left, wid, -1) +      Vector(-inner/2. - inner/4. + 3*wid, 0)).setMaterial(3))
    toReturn.add((font.shapeFromStringBoundedCentered(center, wid, -1) +    Vector(0, -inner/2. - inner/4. + 4*wid)).setMaterial(3))
    toReturn.add((font.shapeFromStringBoundedCentered(right, wid, -1) +      Vector(inner/2. + inner/4. - 3*wid, 0)).setMaterial(3))
    if centeru[0] != '?' and centeru[0] != ' ':
        toReturn.add((font.shapeFromStringBoundedCentered(centeru, wid, -1) +    Vector(0, +inner/2. + inner/4. - 4*wid)).setMaterial(3))

    mark = alignmentMark(100).setMaterial(3)*m;
    
    mx = inner - 5*wid;
    
    toReturn.add(mark + Vector(0, mx));
    toReturn.add(mark + Vector(0, -mx));
    toReturn.add(mark + Vector(mx, 0));
    toReturn.add(mark + Vector(-mx, 0));
    
    return toReturn
Ejemplo n.º 2
0
def circle(c, r, p=precision):
    if r < p:
        steps = 8
    else:
        steps = int(math.ceil(2*math.pi*r/p))
    
    toReturn = Polyline([], True)

    v = Vector(r,0)
    m = Matrix(2*math.pi/steps)
    
    for i in range(0,steps):
        v *= m
        toReturn.add(c + v)

#    print toReturn
    return toReturn
Ejemplo n.º 3
0
    def set_value(self, field_name, value):
        """ sets an attribute value for a given field name """
        if field_name in self.fields:
            if not value is None:
                self._dict['attributes'][field_name] = _unicode_convert(value)
                self._json = json.dumps(self._dict, default=_date_handler)
            else:
                pass
        elif field_name.upper() in ['SHAPE', 'SHAPE@', "GEOMETRY"]:
            if isinstance(value, AbstractGeometry):
                if isinstance(value, Point):
                    self._dict['geometry'] = {
                        "x": value.asDictionary['x'],
                        "y": value.asDictionary['y']
                    }
                elif isinstance(value, MultiPoint):
                    self._dict['geometry'] = {
                        "points": value.asDictionary['points']
                    }
                elif isinstance(value, Polyline):
                    self._dict['geometry'] = {
                        "paths": value.asDictionary['paths']
                    }
                elif isinstance(value, Polygon):
                    self._dict['geometry'] = {
                        "rings": value.asDictionary['rings']
                    }
                else:
                    return False
                self._json = json.dumps(self._dict, default=_date_handler)
            elif isinstance(value, arcpy.Geometry):
                if isinstance(value, arcpy.PointGeometry):
                    self.set_value(
                        field_name,
                        Point(value, value.spatialReference.factoryCode))
                elif isinstance(value, arcpy.Multipoint):
                    self.set_value(
                        field_name,
                        MultiPoint(value, value.spatialReference.factoryCode))

                elif isinstance(value, arcpy.Polyline):
                    self.set_value(
                        field_name,
                        Polyline(value, value.spatialReference.factoryCode))

                elif isinstance(value, arcpy.Polygon):
                    self.set_value(
                        field_name,
                        Polygon(value, value.spatialReference.factoryCode))

        else:
            return False
        return True
Ejemplo n.º 4
0
def linear(p0, p1, p=precision):
    toReturn = Polyline([], False)
    
    steps = int(math.ceil((p1-p0).norm()/p))
    
    toReturn.add(p0.copy())
    
    for i in range(1,steps):
        t = float(i)/steps
        toReturn.add( p0*(1.0-t) + p1*t )
    
    toReturn.add(p1.copy())

    return toReturn
Ejemplo n.º 5
0
def cBezier(p0, p1, p2, p3, p=precision):   # See wikipedia
    toReturn = Polyline([], False)
    
    estimatedLength = (p1-p0).norm() + (p2-p1).norm() + (p3-p2).norm()
    steps = int(math.ceil(estimatedLength/p))
    
    toReturn.add(p0.copy())
                
    for i in range(1,steps):
        t = float(i)/steps
        toReturn.add( p0*((1.0-t)*(1.0-t)*(1.0-t)) + p1*(3*(1.0-t)*(1.0-t)*t) + p2*(3*(1.0-t)*t*t) + p3*(t*t*t) )
    
    toReturn.add(p3.copy())

    return toReturn
Ejemplo n.º 6
0
def qBezier(p0, p1, p2, p=precision):   # See wikipedia
    toReturn = Polyline([], False)  # Really odd bug if this is replaced with 'Polyline()'
    
    estimatedLength = (p1-p0).norm() + (p2-p1).norm()
    steps = int(math.ceil(estimatedLength/p))
    
    if steps > 1e4:          # Arbitrary, check this....
        return Polyline([], False)
    
    toReturn.add(p0.copy())
    
    for i in range(1,steps):
        t = float(i)/steps
        toReturn.add( p0*((1.0-t)*(1.0-t)) + p1*(2.*(1.0-t)*t) + p2*(t*t) )
    
    toReturn.add(p2.copy())

    return toReturn
Ejemplo n.º 7
0
    def __init__(self, path, radius):
        #Shapes' list
        self.shapes = []

        self.path = path

        #SVG file parsing : opening the file, setting up a custom parser
        self.svg_file = open(path)
        parser = etree.XMLParser(ns_clean=True,
                                 remove_comments=True,
                                 remove_blank_text=True)
        #Generating a parsing tree
        self.tree = tree = etree.parse(self.svg_file, parser)

        ######################################################################
        ### Parsing ATTRIBUTES                                              ##
        ### Height, width, unit, ...                                        ##
        ######################################################################

        svgNode = tree.xpath("//n:svg", namespaces={'n': NS['svg']})[0]

        #Parsing the width, height, and their unit (should be 'px')
        self.width = self.height = self.unit = None
        for attribute in ['width', 'height']:
            regexp = re.match("([\d]+)(.+)", svgNode.attrib[attribute])
            if regexp:
                setattr(self, attribute, int(regexp.group(1)))
                self.unit = regexp.group(2)
            else:
                raise Exception("No {} ! Can't parse SVG.".format(attribute))

        # Parsing the map's scale
        self.pixel_per_mm = None
        if 'pixel_per_mm' in svgNode.attrib:
            self.pixel_per_mm = float(svgNode.attrib['pixel_per_mm'])

        # Parsing the 'real' angle of the map's north
        # (What a compass would show if oriented toward the map's top)
        self.north_angle = None
        if 'north_angle' in svgNode.attrib:
            self.north_angle = float(svgNode.attrib['north_angle'])

        #Bounding rectangle ( TODO : mm -> xp, etc.)
        self.rect = Rectangle(-1, -1, self.width + 1, self.height + 1)
        self.shapes.append(self.rect)

        ######################################################################
        ### Parsing SHAPES                                                  ##
        ### We search all the groups and subgroups and parse their elements ##
        ######################################################################

        #PARSING PATHS (polylines and ellipses)
        paths = tree.xpath("//n:path", namespaces={'n': NS['svg']})
        #We'll add the "sodipodi" namespace here because arc shapes (like ellipsis) use it
        sodipodi_type = add_ns('type', NS['sodipodi'])
        if paths:
            for path in paths:
                if sodipodi_type in path.attrib and path.attrib[
                        sodipodi_type] == 'arc':
                    cx = float(path.attrib[add_ns('cx', NS['sodipodi'])])
                    cy = float(path.attrib[add_ns('cy', NS['sodipodi'])])
                    rx = float(path.attrib[add_ns('rx', NS['sodipodi'])])
                    ry = float(path.attrib[add_ns('ry', NS['sodipodi'])])

                    dx, dy = parseTransform(path)
                    cx, cy = cx + dx, cy + dy

                    ellipse = Ellipse(cx, cy, rx, ry)
                    self.shapes.append(ellipse)
                else:
                    print "[ ! ] Paths - except ellipses - are not implemented yet"
                    # points = self.parse_points(path.attrib['d'])
                    # print points

        #PARSING RECTANGLES
        rectangles = tree.xpath("//n:rect", namespaces={'n': NS['svg']})
        if rectangles:
            for rect in rectangles:
                x = float(rect.attrib['x'])
                y = float(rect.attrib['y'])
                w = float(rect.attrib['width'])
                h = float(rect.attrib['height'])

                dx, dy = parseTransform(rect)
                x, y = x + dx, y + dy

                rectangle = Rectangle(x, y, w, h)
                self.shapes.append(rectangle)

        #PARSING POLYGONES
        polygones = tree.xpath("//n:polygone", namespaces={'n': NS['svg']})
        if polygones:
            for polygone in polygones:
                points = self.parse_points(polygone.attrib['points'])

                dx, dy = parseTransform(polygone)
                for point in points:
                    point.x += dx
                    point.y += dy

                polygone = Polygone(points)
                self.shapes.append(polygone)

        #PARSING POLYLINES
        polylines = tree.xpath("//n:polyline", namespaces={'n': NS['svg']})

        if polylines:
            for poly in polylines:
                points = self.parse_points(poly.attrib['points'])

                dx, dy = parseTransform(poly)
                for point in points:
                    point.x += dx
                    point.y += dy

                polyline = Polyline(points)
                self.shapes.append(polyline)

        if self.pixel_per_mm is not None:
            self.discreteMap = DiscreteMap(self,
                                           radius=int(radius *
                                                      self.pixel_per_mm))
        else:
            self.discreteMap = DiscreteMap(self)
Ejemplo n.º 8
0
def arc(c, i, f, chooseShortest=True, p=precision):   # 'direction' : CCW=1, CW=-1, Shortest=0
    r1 = (i - c).norm()
    r2 = (f - c).norm()
    
#    print r1 - r2

    if r1 - r2 > 1e-6:  # Arbitrary!
        print "Can't make an arc with two radii: " + str(r1) + " and " + str(r2)
        return Polyline([], False)
    if (f - i).norm2() < 1e-6:  # Arbitrary!
        print "Start and end of arc at same place..."
        return Polyline([], False)
    
    r = r1

    print (i - c), (f - c)

    dir = (i - c).cross(f - c)

    print "Dir: ", dir

    if dir == 0:
#        dir = 1
        ang = -math.pi
        chooseShortest=True
        print "Arcs are equidistant, choosing CCW as shortest"
    else:
        ang = dir*math.acos(((i - c).Unit()) * ((f - c).Unit()))

#    print (i - c).Unit()
#    print (f - c).Unit()


    if not chooseShortest:
        if ang > 0:
            ang = ang - 2*math.pi
        else:
            ang = 2*math.pi + ang

    if r < p:
        steps = 8
    elif r > 1000:          # Arbitrary, check this....
        return Polyline([], False)
    else:
        steps = int(math.ceil(abs(ang)*r/p))

#    print steps, ang, r, p

    toReturn = Polyline([], False)
    
    if steps > 0:
        v = (i - c)
        print ang/steps
        m = Matrix(ang/steps)
            
        toReturn.add(i)

        for i in range(0,steps-1):
            v *= m
            #        print center + v
            toReturn.add(c + v)

        toReturn.add(f)

#    print toReturn
    return toReturn
Ejemplo n.º 9
0
def thickenPolyline(polyline_,
                    widthType_="CUBIC",  # "LINEAR", "CUBIC", "SPLINE", "FUNCTION", "CONSTANT"
                    widthParams=1.0,     # Single number (constant width), or list [ i, f ], or (in the case of "FUNCTION") a string, "CONSTANT" only uses the first value.
                    filletType_="SHARP", # "ROUND", "SHARP", "BLUNT", "QBEZIER"     !! NotImplemented
                    capType_="FLAT"):    # "FLAT", "ROUND", "ROUNDRECESSED"         !! NotImplemented
    
    
    if isinstance(polyline_, list):
        [polyline, di, df] = polyline_
        df = -df
    else:
        polyline = polyline_
        di = None
        df = None

    if not isinstance(polyline, Polyline):
        print "No polyline given to thicken..."
        return None
    
    if isinstance(widthType_, str):     widthType = widthTypes[widthType_]
    if isinstance(filletType_, str):    filletType = filletTypes[filletType_]
    if isinstance(capType_, str):       capType = capTypes[capType_]
    
    if isinstance(widthParams, list):
        if widthType == 4: # CONSTANT
            widthParams = widthParams[0]
    elif isinstance(widthParams, str):
        if widthType != 3:
            print "Error, given function string, but not function type..."
    else:
         widthType = 4  # CONSTANT

#    print widthType, widthParams

    length = polyline.length()
    currentLength = 0
    
    if widthType == 1 or widthType == 2 or widthType == 3:
        i = 1
        while i < polyline.size:       # Check here...
            segmentLength2 = (polyline.points[i] - polyline.points[i-1]).norm2()
            if segmentLength2 > 4*precision*precision:
                print "Length short, adding linear"
                addition = linear(polyline.points[i-1], polyline.points[i])
                polyline.points = polyline.points[0:i-1] + addition.points + polyline.points[i+1:]
                polyline.size = len(polyline.points)
            i += 1

#    polyline.plot()
#    return

    toReturn = Polyline([], True)

#    return toReturn

    p0 = polyline.perp(0, filletType, calcWidth(0, widthType, widthParams), di)
    
    for i in range(1, polyline.size - 1):
        currentLength += (polyline.points[i] - polyline.points[i-1]).norm()
        t = currentLength/length
#        print t, calcWidth(t, widthType, widthParams), (polyline.points[i] - polyline.points[i-1])
        toReturn.add(polyline.perp(i, filletType, calcWidth(t, widthType, widthParams)))
    
    p1 = polyline.perp(polyline.size - 1, filletType, calcWidth(1, widthType, widthParams), df)
    p2 = polyline.perp(polyline.size - 1, filletType, -calcWidth(1, widthType, widthParams), df)

    if capType == 0:
        toReturn.add(p1)
        toReturn.add(p2)
    elif capType == 1:
        toReturn.add(arc((p1+p2)/2, p1, p2))
    
    for i in range(polyline.size - 2, 0, -1):
        currentLength -= (polyline.points[i] - polyline.points[i-1]).norm()
        t = currentLength/length
#        print t, calcWidth(t, widthType, widthParams)
        toReturn.add(polyline.perp(i, filletType, -calcWidth(t, widthType, widthParams)))

    p3 = polyline.perp(0, filletType, -calcWidth(0, widthType, widthParams), di)


    if capType == 0:
        toReturn.add(p3)
        toReturn.add(p0)
    elif capType == 1:
        toReturn.add(arc((p0+p3)/2, p3, p0))

#    print toReturn
    return toReturn
Ejemplo n.º 10
0
def connect(i_, f_, type="CIRCULAR", di=None, df=None):    # "LINEAR", "QBEZIER", "CBEZIER", "CIRCULAR", "MONOCIRCULAR"
    if isinstance(i_, Connection):
        i =  i_.v
        di = i_.dir
    else:
        i = i_

    if isinstance(f_, Connection):
        f =  f_.v
        df = f_.dir
    else:
        f = f_

    if i == f:
        print "Error: There is no distance to connect..."
        return None

    if type == "LINEAR" or di == None or df == None:
        return Polyline([i, f], False)
    elif di * df == -1 and abs(di * (f-i).unit()) == 1:
        return Polyline([i, f], False)
    elif di * df == 1 and abs(di * (f-i).unit()) == 1:
        print "Sorry, can't make this path"
        return None
    else:
        # Check if norm is zero?
        di.Unit()
        df.Unit()
        
        if   type == "QBEZIER":
            c = getIntersection(i, di, f, df)
            
            if c is not None:
                if (c-i)*di > 1e-10 and (c-f)*df > 1e-10:
                    print (c-i)*di, (c-f)*df
                    return qBezier(i, c, f)
        
            print "Error: Intersection could not be found; returning linear path"
            return None #Polyline([i, f], False)
        elif type == "CBEZIER":
            l = (f - i).norm()/2
#            c = getIntersection(i, di, f, df)
            return cBezier(i, i + di*l, f + df*l, f);
        elif type == "CIRCULAR":
            # Find the Radius of the two circles (confusing math that I won't explain):
            D =  f -  i
            
            
            d = df.perp() - di.perp()
            a = (d.norm2() - 4)
            b = 2*(d*D)
            c = D.norm2()
            
            lList = [None, None, None, None]
            paramList = [None, None, None, None]
            rlist = [getRoot(a,b,c,1), getRoot(a,b,c,-1)]
            
            print rlist

            j = 0
            for r in rlist:
                for s in [1, -1]:
                    if r != None:
                        ci = i + di.perp()*(s*r)
                        cf = f + df.perp()*(s*r)
                        
                        m = (ci + cf)/2
                        
                        if abs((cf - ci).norm2() - 4*r*r) < 1e-6:
                            lList[j] = abs(r)*(abs(getArcAng(ci, i, m, (m-i)*di > 0)) + abs(getArcAng(cf, m, f, (m-f)*df > 0)))

                    j += 1

            minl = "inf"
            minj = -1
            for j in range(0,4):
#                print j, lList[j]
                if lList[j] != None and lList[j] < minl:
                    minl = lList[j]
                    minj = j

            j = 0
            for r in rlist:
                for s in [1, -1]:
                    if j == minj:
                        ci = i + di.perp()*(s*r)
                        cf = f + df.perp()*(s*r)
                        
                        m = (ci + cf)/2

                        toReturn = Polyline()
                        toReturn.add(arc(ci, i, m, (m-i)*di > 0))
                        toReturn.add(arc(cf, m, f, (m-f)*df > 0))

                        return toReturn

                    j += 1
#            return toReturn

#            r1 = getRoot(a,b,c,1)
#            
#            ci1 = i - di.perp()*r1
#            cf1 = f - df.perp()*r1
#            
#            if abs((cf1 - ci1).norm2() - 4*r1*r1) > 1e-6:
#                ci1 = i + di.perp()*r1
#                cf1 = f + df.perp()*r1
#            
#            m1 = (ci1 + cf1)/2
#            l1 = getArcAng(ci1, i, m1, (m1-i)*di > 0) + getArcAng(cf1, m1, f, (m1-f)*df > 0)
#
#
#            r2 = getRoot(a,b,c,-1)
#            
#            ci2 = i + di.perp()*r2
#            cf2 = f + df.perp()*r2
#            
#            if abs((cf1 - ci1).norm2() - 4*r2*r2) > 1e-6:
#                ci2 = i - di.perp()*r2
#                cf2 = f - df.perp()*r2
#
#            m2 = (ci1 + cf1)/2
#            l2 = getArcAng(ci2, i, m2, (m2-i)*di > 0) + getArcAng(cf2, m2, f, (m2-f)*df > 0)
#
#            if r1*l1 < r2*l2:
#                m = m1
#                ci = ci1
#                cf = cf1
#            else:
#                m = m2
#                ci = ci2
#                cf = cf2


            
#            for d in [df.perp() - di.perp()]: #, df.perp() + di.perp()]:
#                a = (d.norm2() - 4)
#                b = 2*(d*D)
#                c = D.norm2()
#                
#                rlist[j] =      getRoot(a,b,c,1)
#                rlist[j-1] =    getRoot(a,b,c,-1)
#            
#                j += 2
#            
#            print rlist
#
#            minr = "inf"
#            minj = -1
#            for j in range(0,3):
#                if rlist[j] != None and abs(rlist[j]) < minr:
#                    minr = abs(rlist[j])
#                    minj = j
#
##            minjList = []
##
##            for j in range(0,3):
##                if rlist[j] != None and abs(rlist[j]) == minr:
##                    minjList += [j]
##
##            if len(minjList) > 1:
##                for j in minrList:
#
#
#            # With knowledge of the radius, find the centers
#            r = minr
#            print r
#            if minj == 0 or minj == 1:
##                print i
##                print di.perp()*r
#                ci = i + di.perp()*r
#                cf = f + df.perp()*r
#                
#                print (cf - ci).norm2()- 4*r*r
#
##                print (cf - ci).norm2(), 4*r*r
#
#                if abs((cf - ci).norm2() - 4*r*r) > 1e-6:    # Arbitrary error!
#                    ci = i - di.perp()*r
#                    cf = f - df.perp()*r
#                
##                    print (cf - ci).norm2(), 4*r*r
#                    print (cf - ci).norm2()- 4*r*r
#
#                    if abs((cf - ci).norm2() - 4*r*r) > 1e-6:    # Arbitrary error!
#                        print "Error occured with radius checking"
#                        return None
#            elif minj == 2 or minj == 3:
#                ci = i + di.perp()*r
#                cf = f - df.perp()*r
#                
##                print (cf - ci).norm2(), 4*r*r
#                print (cf - ci).norm2()- 4*r*r
##                print "here"
#
#                if abs((cf - ci).norm2() - 4*r*r) > 1e-6:    # Arbitrary error!
##                    print "here2"
#                    ci = i - di.perp()*r
#                    cf = f + df.perp()*r
#                
##                    print (cf - ci).norm2(), 4*r*r
#                    print (cf - ci).norm2()- 4*r*r
#
#                    if abs((cf - ci).norm2() - 4*r*r) > 1e-6:    # Arbitrary error!
#                        print "Error occured with radius checking"
#                        return None
#            else:
#                # No radius found...
#                print "Sorry, can't find two minimum circles"
#                return None

#            plotLine(i, ci)
#            plotLine(ci, cf)
#            plotLine(cf, f)

#            return toReturn

        elif type == "MONOCIRCULAR":
#            print "MONOCIRCULAR"
            intersection = getIntersection(i, di, f, df)
            
            if intersection == None:
                if di*df == 1:
                    if di*i > df*f:
                        midpoint = getIntersection(i, di.perp(), f, df)
                        c = (midpoint + i)/2
                        return arc(c, i, midpoint) + Polyline([f], False)     # Check arc direction!!! (removed repeated point?)
                    else:
                        midpoint = getIntersection(i, di, f, df.perp())
                        c = (midpoint + f)/2
                        return Polyline([i], False) + arc(c, midpoint, f)     # Check arc direction!!!
                
                else:
                    print "CIRCULAR would be better for this case because directions are antiparallell; returning linear in the meantime..."
                    return Polyline([i, f], False)

            
            toReturn = Polyline([])
    
            if (intersection - i)*di > 0 and (intersection - f)*df > 0:     # Converging
                if (intersection - i)*di < (intersection - f)*df:
                    midpoint = intersection - df*((intersection - i)*di)
                    c = getIntersection(i, di.perp(), midpoint, df.perp())  # Check if intersection exists for all of these...
                
                    return arc(c, i, midpoint) + Polyline([f], False)
                else:
                    midpoint = intersection - di*((intersection - f)*df)
                    c = getIntersection(midpoint, di.perp(), f, df.perp())

                    return Polyline([i], False) + arc(c, midpoint, f)
            elif (intersection - i)*di > 0 or (intersection - f)*df > 0:    # Opposite
                if (i - intersection)*di < 0:
                    midpoint = intersection - di*((intersection - f)*df)
                    c = getIntersection(midpoint, di.perp(), f, df.perp())
                    
                    return Polyline([i], False) + arc(c, midpoint, f, False)
                else:
                    midpoint = intersection - df*((intersection - i)*di)
                    c = getIntersection(i, di.perp(), midpoint, df.perp())
                    
                    return arc(c, i, midpoint, False) + Polyline([f], False)
            else:                                                           # Diverging
                if (intersection - i)*di > (intersection - f)*df:               # If i is shorter
                    midpoint = intersection - di*((intersection - f)*df)
                    c = getIntersection(midpoint, di.perp(), f, df.perp())
                    
                    print c
                    
                    if c.norm2() < 1e6:
#                        return Polyline([i, midpoint, c, f], False) #arc(c, i, midpoint, False) + Polyline([f], False)
#                        return arc(c, i, midpoint, False) + Polyline([f], False)
                        return Polyline([i], False) + arc(c, midpoint, f, False)
                else:
                    midpoint = intersection - df*((intersection - i)*di)
                    c = getIntersection(i, di.perp(), midpoint, df.perp())
                    
                    print c
                    if c.norm2() < 1e6:
#                        return Polyline([i, c, midpoint, f], False) #+ arc(c, midpoint, f, False)
#                        return Polyline([i], False) + arc(c, midpoint, f, False)
                        return arc(c, i, midpoint, False) + Polyline([f], False)


#            if (c - i).norm2() < (c - f).norm2():
#                if (c - i) * di == 0:
#                    print "CIRCULAR would be better for this case; returning linear in the meantime..."
#                    return Polyline([i, f], False)
#                elif (c - i) * di > 0 and (f - c) * df > 0:
#                    midpoint = c - df*( (c-i).norm() )
#                
#                    toReturn.add(arc(c, i, midpoint))
#                    toReturn.add(f)
#                elif (c - i) * di < 0 and (f - c) * df < 0:
#                    midpoint = c - df*( (c-i).norm() )
#                    
#                    toReturn.add(arc(c, i, midpoint))
#                    toReturn.add(f)

            return NotImplemented
Ejemplo n.º 11
0
    def shapeFromGlyph(self, glyph):    # Save loaded glyphs for speed
        toReturn = Shape([],[])
        
        if glyph.isComposite():
            print "Warning: This case is broken!, it does not transform..."
            #            print "COMPOSITE"
            for component in glyph.components:
                print component
                print component.getComponentInfo()
                [name, transform] = component.getComponentInfo()
                print transform
                print type(transform)
                m = Matrix(transform)
                print m
                print self.tt['glyf'][name]
                toReturn.add(self.shapeFromGlyph(self.tt['glyf'][name]))
#                for item in self.getCMAP().cmap.items():
#                    if item[1] == name:
#                        toReturn.add(self.shapeFromGlyph(self.tt[ 'glyf' ][item[0]]))
#                        break
        else:
            
#            print "NOT COMPOSITE"
            last = 0
            for i in range(glyph.numberOfContours):
                toAdd = Polyline([], True)
                prevV = None
                prevOn = None
                prevprevV = None
                prevprevOn = None
                
                firstV = None
                firstOn = None
                secondV = None
                secondOn = None
                for j in range(last, glyph.endPtsOfContours[i] + 1):
                    v = Vector(glyph.coordinates[j][0], glyph.coordinates[j][1])/float(self.width)  # This is a temporary fix!
                    on = glyph.flags[j] & 0x01
                    
                    if firstOn == None:
                        firstOn = on
                        firstV = v
                    elif secondOn == None:
                        secondOn = on
                        secondV = v
                    
#                    print v
#                    print prevprevOn, prevOn, on
#                    print prevprevV, prevV, v

                    if prevOn and on:
                        if prevprevOn == None:
                            toAdd.add(prevV)
                        toAdd.add(v)
                    elif prevOn != None and prevprevOn != None:
                        if prevprevOn and not prevOn:
                            if on:          # 101
                                toAdd.add(qBezier(prevprevV, prevV, v))
                            elif not on:    # 100
#                                print (prevV + v)
#                                print (prevV + v)/2
                                toAdd.add(qBezier(prevprevV, prevV, (prevV + v)/2))
                        elif not prevprevOn and not prevOn:
                            if on:          # 001
                                toAdd.add(qBezier((prevprevV + prevV)/2, prevV, v))
                            elif not on:    # 000
                                toAdd.add(qBezier((prevprevV + prevV)/2, prevV, (prevV + v)/2))
                                
                    prevprevOn = prevOn
                    prevprevV = prevV
                    prevOn = on
                    prevV = v
#                    print "toAdd: "
#                    print toAdd
#                    print "First Here"
#                    print prevOn, on, firstOn
#                    print prevprevV, v, firstV

#                toAdd.add(Vector(0,0))

                if not on:
                    if firstOn != None and not firstOn:
                        if prevprevOn:
                            toAdd.add(qBezier(prevprevV, v, (v + firstV)/2))
                        else:
                            toAdd.add(qBezier((prevprevV + v)/2, v, (v + firstV)/2))
                    if firstOn != None and firstOn:
                        if prevprevOn:
                            toAdd.add(qBezier(prevprevV, v, firstV))
                        else:
                            toAdd.add(qBezier((prevprevV + v)/2, v, firstV))
                                    
#                if firstOn != None and secondOn != None:
#                    print "First Second Here"
#                    print on, firstOn, secondOn
##                    if on and firstOn and secondOn:                # 111
#                    if on and not firstOn and secondOn:             # 101
#                        toAdd.add(qBezier(v, firstV, secondV))
#                    if on and not firstOn and not secondOn:         # 100
#                        toAdd.add(qBezier(v, firstV, (firstV + secondV)/2))
#                    if not on and not firstOn and secondOn:         # 001
#                        toAdd.add(qBezier((v + firstV)/2, firstV, secondV))
#                    if not on and not firstOn and not secondOn:     # 000
#                        toAdd.add(qBezier((v + firstV)/2, firstV, (firstV + secondV)/2))

#                toAdd.add(v)
                last = glyph.endPtsOfContours[i] + 1
#                print toAdd.area()
#                toAdd.add(Vector(0,0))
                toReturn.add(toAdd)
#                print "toReturn: "
#                print toReturn

            if len(toReturn.polylines) > 1:
                k = 0
    
                for i in range(0, toReturn.size):
#                    print toReturn.polylines[i].area()
                    if abs(toReturn.polylines[i].area()) > abs(toReturn.polylines[k].area()):   # Save area for speed
                        k = i
                
                finList = []
                    
                for i in range(0, toReturn.size):
                    if toReturn.polylines[i].area() < 0:
#                        print k, i
#                        print toReturn.polylines[i]

#                        print toReturn.polylines[k]

#                        toReturn.polylines[i].points.reverse()

                        m = 0 #toReturn.polylines[i].size-1
                            
                        j = 0
                        norm = (toReturn.polylines[k].points[0] - toReturn.polylines[i].points[m]).norm2()    # Possible error if empty
                            
                        toReturn.polylines[k].sizeCalc()
                                
                        for l in range(0, toReturn.polylines[k].size):
#                            print norm, (toReturn.polylines[k].points[l] - toReturn.polylines[i].points[m]).norm2()
                            if (toReturn.polylines[k].points[l] - toReturn.polylines[i].points[m]).norm2() < norm:
                                j = l
                                norm = (toReturn.polylines[k].points[l] - toReturn.polylines[i].points[m]).norm2()
                                    
#                        print j
# toReturn.polylines[k].points[j],
                        toReturn.polylines[k].points = toReturn.polylines[k].points[0:j+1] + toReturn.polylines[i].points + [toReturn.polylines[i].points[0]] +  toReturn.polylines[k].points[j:]
#                        toReturn.polylines[k].points = toReturn.polylines[k].points[0:j+1] + [toReturn.polylines[i].points[toReturn.polylines[i].size-1]] + toReturn.polylines[i].points + toReturn.polylines[k].points[j:]
                        toReturn.polylines[k].sizeCalc()
                    else:
                        finList += [ toReturn.polylines[i] ]
                            
                toReturn = Shape(finList)
#                        toReturn.polylines.remove(i)
#                finList = [toReturn.polylines[k]]
#        
#                for polyline in toReturn.polylines:
#                    print polyline
#                    if polyline != toReturn.polylines[k]:
#                        print polyline.area()
#                        if polyline.area() < 0:
#                    
#                            highest = polyline.points[0]
#                            print "HIGHEST: ", highest
#                            j = 0
#                            
#                            for i in range(0, polyline.size):
#                                if polyline.points[i].y > highest.y:
#                                    highest = polyline.points[i]
#                                    j = i
#                    
#                            polyline.points.insert(i, highest)
#                            polyline.points.insert(i, highest + Vector(0,2))
#                            polyline.points.insert(i, highest)
#                    
#                        else:
#                            print "extended"
#                            finList.extend(polyline)
#                    
#                    toReturn.polylines[k].union(polyline)
#
#                return Shape(finList,[])

        return toReturn
Ejemplo n.º 12
0
    def interpretToken(self, token_, f):
        shapesByLayer = {}
        
        print ':'.join(x.encode('hex') for x in token_)
        length =    int(token_[0:2].encode('hex'), 16)
        token =    int(token_[2].encode('hex'), 16)   # Rename as token
        dataType =  int(token_[3].encode('hex'), 16)
        
        DEBUG = True
        
        if DEBUG: print "LENGTH: " + str(length) + "\t" + hex(token) + "  \t"
        
#        if (dataType == 0 and length != 0) or (dataType == 2 and length != 2) or (dataType == 3 and length != 4) or (dataType == 5 and length != 8):
#            print "Possible error; unexpected length"

        if   token == 0x00: #02:
            if DEBUG: print "HEADER"
            if length != 6: print "Possible error; unexpected length"
#            self.version =  read(f.read(2))
            self.version = struct.unpack(">h", f.read(2))[0]
            print self.version
        elif token == 0x01: #02:
            if DEBUG: print "BGNLIB"
            
            vals = struct.unpack(">hhhhhhhhhhhh", f.read(24))
            
#            self.modificationTime.year =    vals[0]
#            self.modificationTime.month =   vals[1]
#            self.modificationTime.day =     vals[2]
#            self.modificationTime.hour =    vals[3]
#            self.modificationTime.minute =  vals[4]
#            self.modificationTime.second =  vals[5]
#            
#            self.accessTime.year =    vals[6]
#            self.accessTime.month =   vals[7]
#            self.accessTime.day =     vals[8]
#            self.accessTime.hour =    vals[9]
#            self.accessTime.minute =  vals[10]
#            self.accessTime.second =  vals[11]

            self.modificationTime.set(vals[0], vals[1], vals[2], vals[3], vals[4], vals[5])
            self.accessTime.set(vals[6], vals[7], vals[8], vals[9], vals[10], vals[11])

#            self.modificationTime.set(read(f.read(2)), read(f.read(2)), read(f.read(2)), read(f.read(2)), read(f.read(2)), read(f.read(2)))
#            self.accessTime.set(read(f.read(2)), read(f.read(2)), read(f.read(2)), read(f.read(2)), read(f.read(2)), read(f.read(2)))

            print self.modificationTime
            print self.accessTime
        elif token == 0x02: #06:
            if DEBUG: print "LIBNAME"
            string = f.read(length - 4) # Error check this...
            print "Library Name: " + string
        elif token == 0x03: #05:
            if DEBUG: print "UNITS"
            
#            databaseUnitUser = read(f.read(8)) # Fix encoding
#            databaseUnitMeters = read(f.read(8))

            data1 = f.read(8)
            data2 = f.read(8)
            
            print data1, ' '.join(format(ord(x), 'b') for x in data1)
            print data2, ' '.join(format(ord(x), 'b') for x in data2)
            
            databaseUnitUser = read(data1) # Fix encoding
            databaseUnitMeters = read(data2)
            
            if DEBUG:
                print databaseUnitUser
                print databaseUnitMeters
        elif token == 0x04: #00:
            if DEBUG: print "ENDLIB"
        elif token == 0x05: #02:
            if DEBUG: print "BGNSTR"
            
#            self.modificationTimeS.set(int(f.read(2).encode('hex'), 16), int(f.read(2).encode('hex'), 16), int(f.read(2).encode('hex'), 16), int(f.read(2).encode('hex'), 16), int(f.read(2).encode('hex'), 16), int(f.read(2).encode('hex'), 16))
#            
#            self.accessTimeS.set(int(f.read(2).encode('hex'), 16), int(f.read(2).encode('hex'), 16), int(f.read(2).encode('hex'), 16), int(f.read(2).encode('hex'), 16), int(f.read(2).encode('hex'), 16), int(f.read(2).encode('hex'), 16))

            vals = struct.unpack(">hhhhhhhhhhhh", f.read(24))
            self.modificationTimeS.set(vals[0], vals[1], vals[2], vals[3], vals[4], vals[5])
            self.accessTimeS.set(vals[6], vals[7], vals[8], vals[9], vals[10], vals[11])
            
#            self.modificationTimeS.year =    vals[0]
#            self.modificationTimeS.month =   vals[1]
#            self.modificationTimeS.day =     vals[2]
#            self.modificationTimeS.hour =    vals[3]
#            self.modificationTimeS.minute =  vals[4]
#            self.modificationTimeS.second =  vals[5]
#            
#            self.accessTimeS.year =    vals[6]
#            self.accessTimeS.month =   vals[7]
#            self.accessTimeS.day =     vals[8]
#            self.accessTimeS.hour =    vals[9]
#            self.accessTimeS.minute =  vals[10]
#            self.accessTimeS.second =  vals[11]

            print self.modificationTimeS
            print self.accessTimeS
        elif token == 0x06: #06:
            if DEBUG: print "STRNAME"
            
            string = f.read(length - 4) # Error check this...
            print "Structure Name: " + string
        elif token == 0x07: #00:
            if DEBUG: print "ENDSTR"
        elif token == 0x08: #00:
            if DEBUG: print "BOUNDARY"
        elif token == 0x09: #00:
            if DEBUG: print "PATH"
        elif token == 0x0A: #00:
            if DEBUG: print "SREF"
        elif token == 0x0B: #00:
            if DEBUG: print "AREF"
        elif token == 0x0C: #00:
            if DEBUG: print "TEXT"
        elif token == 0x0D: #02:
            self.currentLayer = struct.unpack(">h", f.read(2))[0]
#            self.currentLayer = read(f.read(2))
            if DEBUG:
                print "LAYER"
                print self.currentLayer
        elif token == 0x0F: #03:
            if DEBUG: print "WIDTH"
            pathWidth = struct.unpack(">h", f.read(2))[0]
        elif token == 0x10: #03:
            if DEBUG: print "XY"

            polyline = Polyline([], True, False, self.currentLayer)

            length -= 4
            
            while length > 0:
                length -= 8
                
                v = Vector(struct.unpack(">i", f.read(4))[0]*self.databaseUnitUser, struct.unpack(">i", f.read(4))[0]*self.databaseUnitUser)
#                v = Vector(int(f.read(4).encode('hex'), 16), int(f.read(4).encode('hex'), 16))
#                v = Vector(read(f.read(4)), read(f.read(4)))
                polyline.add(v)
#                polyline.add(Vector(read(f.read(4)), read(f.read(4))))
#                if DEBUG: print v #, bin(v.x), bin(v.y)

#            if self.currentLayer in self.shapes:
#                self.shapes[self.currentLayer].polylines += [polyline]
#            else:
#                self.shapes[self.currentLayer] = Shape([polyline])

            if self.currentLayer in shapesByLayer:
                self.shapes[self.currentLayer].polylines += [polyline]
            else:
                self.shapes[self.currentLayer] = Shape([polyline])
        elif token == 0x11: #00:
            if DEBUG: print "ENDEL"
        elif token == 0x0002:  # SNAME
            if DEBUG: print "SNAME"
        elif token == 0x0002:  # COLROW
            if DEBUG: print "COLROW"
        elif token == 0x0002:  # NODE
            if DEBUG: print "NODE"
        elif token == 0x0002:  # TEXTTYPE
            if DEBUG: print "TEXTTYPE"
        elif token == 0x0002:  # PRESENTATION
            if DEBUG: print "PRESENTATION"
        elif token == 0x0002:  # STRING
            if DEBUG: print "STRING"
        elif token == 0x0002:  # STRANS
            if DEBUG: print "STRANS"
        elif token == 0x0002:  # MAG
            if DEBUG: print "MAG"
            magnificationFactor = read(f.read(8))
        elif token == 0x0002:  # ANGLE
            if DEBUG: print "ANGLE"
            angleDegreesCCW = read(f.read(8))
        elif token == 0x0002:  # REFLIBS
            if DEBUG: print "REFLIBS"
        elif token == 0x0002:  # FONTS
            if DEBUG: print "FONTS"
        elif token == 0x0002:  # PATHTYPE
            if DEBUG: print "PATHTYPE"
        elif token == 0x0002:  # GENERATIONS
            if DEBUG: print "GENERATIONS"
        elif token == 0x0002:  # ATTRTABLE
            if DEBUG: print "ATTRTABLE"
        elif token == 0x0002:  # EFLAGS
            if DEBUG: print "EFLAGS"
        elif token == 0x0002:  # NODETYPE
            if DEBUG: print "NODETYPE"
        elif token == 0x0002:  # PROPATTR
            if DEBUG: print "PROPATTR"
        elif token == 0x0002:  # PROPVALUE
            if DEBUG: print "PROPVALUE"
        else:
            if DEBUG: print "token not understood..."
            b2 = f.read(2)
            print ':'.join(x.encode('hex') for x in b2)

        for layer in shapesByLayer:
            self.shapes += [shapesByLayer[layer]]