Пример #1
0
  def _line_line_intersections(self, other):
    a = self.start
    b = self.end
    c = other.start
    d = other.end
    if c == d or a == b: return []
    if isclose(b.x, a.x):
      x = a.x
      if isclose(d.x, c.x):
        return [ ]
      slope34 = ( d.y - c.y ) / ( d.x - c.x )
      y = slope34 * (x - c.x ) + c.y
      p = Point(x,y)
      i = Intersection(self,self.tOfPoint(p), other, other.tOfPoint(p))
      return [ i ]
    if isclose(d.x, c.x):
      x = c.x
      slope12 = ( b.y - a.y ) / ( b.x - a.x )
      y = slope12 * ( x - a.x ) + a.y
      p = Point(x,y)
      i = Intersection(self,self.tOfPoint(p), other, other.tOfPoint(p))
      return [ i ]

    slope12 = ( b.y - a.y) / ( b.x - a.x )
    slope34 = ( d.y - c.y) / ( d.x - c.x )
    if isclose(slope12, slope34): return [ ]
    x = ( slope12 * a.x - a.y - slope34 * c.x + c.y ) / ( slope12 - slope34 )
    y = slope12 * ( x - a.x ) + a.y
    intersection = Point(x,y)
    if (self._bothPointsAreOnSameSideOfOrigin(intersection, b, a) and self._bothPointsAreOnSameSideOfOrigin(intersection, c, d)):
      return [ Intersection(self,self.tOfPoint(intersection), other, other.tOfPoint(intersection)) ]
    return []
Пример #2
0
    def fromNodelist(cls, path, nodelist):
        self = SegmentRepresentation(path)
        # Find first oncurve
        firstOncurve = -1
        for ix, n in enumerate(nodelist):
            if n.type != "offcurve":
                firstOncurve = ix
                break
        first = nodelist[firstOncurve]
        seg = [(first.x, first.y)]

        for n in nodelist[firstOncurve + 1:]:
            if n.type == "offcurve":
                seg.append((n.x, n.y))
            if n.type == "line" or n.type == "curve":
                seg.append((n.x, n.y))
                self.appendSegment(seg)
                seg = [(n.x, n.y)]
        for n in nodelist[:firstOncurve]:
            if n.type == "offcurve":
                seg.append((n.x, n.y))
            if n.type == "line" or n.type == "curve":
                seg.append((n.x, n.y))
                self.appendSegment(seg)
                seg = [(n.x, n.y)]

        # Closed?
        if self.path.closed:
            if len(seg) == 1 and isclose(seg[-1][0], first.x) and isclose(
                    seg[-1][1], first.y):
                pass
            else:
                seg.append((first.x, first.y))
                self.appendSegment(seg)
        return self
Пример #3
0
  def fromNodelist(cls, path, nodelist):
    self = SegmentRepresentation(path)
    # Find first oncurve
    firstOncurve = -1
    for ix, n in enumerate(nodelist):
      if n.type != "offcurve":
        firstOncurve = ix
        break
    first = nodelist[firstOncurve]
    seg = [(first.x,first.y)]

    for n in nodelist[firstOncurve+1:]:
      if n.type == "offcurve":
        seg.append((n.x,n.y))
      if n.type == "line" or n.type == "curve":
        seg.append((n.x,n.y))
        self.appendSegment(seg)
        seg = [(n.x,n.y)]
    for n in nodelist[:firstOncurve]:
      if n.type == "offcurve":
        seg.append((n.x,n.y))
      if n.type == "line" or n.type == "curve":
        seg.append((n.x,n.y))
        self.appendSegment(seg)
        seg = [(n.x,n.y)]

    # Closed?
    if self.path.closed:
      if len(seg) == 1 and isclose(seg[-1][0], first.x) and isclose(seg[-1][1], first.y):
        pass
      else:
        seg.append((first.x,first.y))
        self.appendSegment(seg)
    return self
Пример #4
0
def findshifts(segs, splitline):
    """ Yields lines which are possible positions of splitline. This includes
        all maxima and minima on the segments list and also every 20 units. """
    trans = splitline.alignmentTransformation()
    bounds = []
    maxy = -1e6
    miny = 1e6
    for _s in segs:
        # rotate segment so dealing purely in y, the splitline is in effect horizontal
        s = _s.transformed(trans)
        # add segment ends or any maxima to the list of possible positions
        if len(s) == 2:
            bounds = _addBound(bounds,
                               Bound(s[0].x, s[0].y, s[0].y > s[1].y, s.slope))
            bounds = _addBound(
                bounds, Bound(s[1].x, s[1].y, s[1].y >= s[0].y, s.slope))
            # collect overall segment list extrema in y
            maxy = max(maxy, s[0].y, s[1].y)
            miny = min(miny, s[0].y, s[1].y)
        elif len(s) == 3:
            d2 = s[0].y - 2 * s[1].y + s[2].y
            if not isclose(d2, 0.):
                rt = (s[0].y - s[1].y) / d2
                if 0 <= rt <= 1.:
                    p = s.pointAtTime(rt)
                    bounds.append(Bound(p.x, p.y, d2 < 0., 0.))
                    maxy = max(maxy, s[0].y, s[2].y, p.y)
                    miny = min(miny, s[0].y, s[2].y, p.y)
                    continue
            bounds = _addBound(
                bounds,
                Bound(s[0].x, s[0].y, s[0].y > s[2].y,
                      s.derivative()[0].slope))
            bounds = _addBound(
                bounds,
                Bound(s[2].x, s[2].y, s[2].y >= s[0].y,
                      s.derivative()[1].slope))
            maxy = max(maxy, s[0].y, s[2].y)
            miny = min(miny, s[0].y, s[2].y)
    # create transform back from horizontal to original direction
    backt = AffineTransformation()
    backt.apply_backwards(trans)
    backt.invert()
    last = None
    # yield each of the calculated bounds as a splitline
    for b in sorted(bounds, key=lambda b: (b[1], b)):
        if last is not None and isclose(last, b[1]):
            continue
        res = splitline.transformed(trans)
        res[0].y += b.y
        res[1].y += b.y
        #        yield res.transformed(backt)
        last = b[1]
    # Now yield every 20 em units as a splitline
    for y in range(int(miny), int(maxy), max(20, int((maxy - miny) * .05))):
        res = splitline.transformed(trans)
        res[0].y += y
        res[1].y += y
        yield res.transformed(backt)
Пример #5
0
def _same_bounds(b1, b2):
    """ Calculate if a point is 'inline' with a point we have already seen.
        If the point is close and the slopes are both in the same direction, then
        we say yes. The points must also be at opposite ends of the segment. """
    if b1.max == b2.max:
        return False
    if isclose(b1.x, b2.x) and isclose(b1.y, b2.y):
        return b1.slope * b2.slope >= 0
    return False
Пример #6
0
 def _findRoots(self, dimension):
   if dimension == "x":
       t = self[0].x / (self[0].x - self[1].x) if not isclose(self[0].x, self[1].x) else 100.
   elif dimension == "y":
       t = self[0].y / (self[0].y - self[1].y) if not isclose(self[0].y, self[1].y) else 100.
   else:
       raise SyntaxError("Meh")
   if 0. <= t <= 1.:
       return [t]
   return []
Пример #7
0
 def _findRoots(self, dimension):
     if dimension == "x":
         t = self[0].x / (self[0].x - self[1].x) if not isclose(
             self[0].x, self[1].x) else 100.
     elif dimension == "y":
         t = self[0].y / (self[0].y - self[1].y) if not isclose(
             self[0].y, self[1].y) else 100.
     else:
         raise SyntaxError("Meh")
     if 0. <= t <= 1.:
         return [t]
     return []
Пример #8
0
 def tOfPoint(self, point, its_on_the_line_i_swear=False):
     """Returns the t (0->1) value of the given point, assuming it lies on the line, or -1 if it does not."""
     # Just find one and hope the other fits
     # point = self.start * (1-t) + self.end * t
     if not isclose(self.end.x, self.start.x):
         t = (point.x - self.start.x) / (self.end.x - self.start.x)
     elif not isclose(self.end.y, self.start.y):
         t = (point.y - self.start.y) / (self.end.y - self.start.y)
     else:
         print("! Line %s is actually a point..." % self)
         return -1
     if its_on_the_line_i_swear or self.pointAtTime(t).distanceFrom(
             point) < 2e-7:
         return t
     return -1
Пример #9
0
 def _update_curve(self, s, attrib, fn):
     d2 = fn(s[0]) - 2 * fn(s[1]) + fn(s[2])
     if isclose(d2, 0):
         return
     t = (fn(s[0]) - fn(s[1])) / d2
     if 0 <= t <= 1:
         p = s.pointAtTime(t)
         if fn(p) < getattr(self, attrib + "i"):
             setattr(self, attrib + "i", fn(p))
         if fn(p) > getattr(self, attrib + "a"):
             setattr(self, attrib + "a", fn(p))
Пример #10
0
 def invert(self):
   m = self.matrix
   det = m[0][0] * (m[1][1]*m[2][2] - m[1][2]*m[2][1]) - \
         m[0][1] * (m[1][0]*m[2][2] - m[1][2]*m[2][0]) + \
         m[0][2] * (m[1][0]*m[2][1] - m[1][1]*m[2][0])
   if isclose(det, 0.):
       return None
   adj = [[(m[1][1]*m[2][2] - m[2][1]*m[1][2])/det, (m[2][1]*m[0][2] - m[0][1]*m[2][2])/det, (m[0][1]*m[1][2] - m[1][1]*m[0][2])/det],
          [(m[1][2]*m[2][0] - m[1][0]*m[2][2])/det, (m[0][0]*m[2][2] - m[0][2]*m[2][0])/det, (m[0][2]*m[1][0] - m[0][0]*m[1][2])/det],
          [(m[1][0]*m[2][1] - m[1][1]*m[2][0])/det, (m[0][1]*m[2][0] - m[0][0]*m[2][1])/det, (m[0][0]*m[1][1] - m[0][1]*m[1][0])/det]]
   self.matrix = adj
Пример #11
0
  def _line_line_intersections(self, other):
    a = self.start
    b = self.end
    c = other.start
    d = other.end
    if isclose(c.x, d.x) and isclose(a.x, b.x): return []
    if isclose(c.y, d.y) and isclose(a.y, b.y): return []
    if c == d or a == b: return []
    if isclose(b.x,a.x):
      x = a.x
      slope34 = ( d.y - c.y) / ( d.x - c.x )
      y = slope34 * ( x - c.x ) + c.y
      p = Point(x,y)
      i = Intersection(self,self.tOfPoint(p), other, other.tOfPoint(p))
      return [ i ]
    if isclose(c.x,d.x):
      x = c.x
      slope12 = ( b.y - a.y) / ( b.x - a.x )
      y = slope12 * ( x - a.x ) + a.y
      p = Point(x,y)
      i = Intersection(self,self.tOfPoint(p), other, other.tOfPoint(p))
      return [ i ]

    slope12 = ( b.y - a.y) / ( b.x - a.x )
    slope34 = ( d.y - c.y) / ( d.x - c.x )
    if abs(slope12 - slope34) < my_epsilon: return [ ]
    x = ( slope12 * a.x - a.y - slope34 * c.x + c.y ) / ( slope12 - slope34 )
    y = slope12 * ( x - a.x ) + a.y
    intersection = Point(x,y)
    if (self._bothPointsAreOnSameSideOfOrigin(intersection, b, a) and self._bothPointsAreOnSameSideOfOrigin(intersection, c, d)):
      return [ Intersection(self,self.tOfPoint(intersection), other, other.tOfPoint(intersection)) ]
    return []
 def invert(self):
     m = self.matrix
     det = m[0][0] * (m[1][1]*m[2][2] - m[1][2]*m[2][1]) - \
           m[0][1] * (m[1][0]*m[2][2] - m[1][2]*m[2][0]) + \
           m[0][2] * (m[1][0]*m[2][1] - m[1][1]*m[2][0])
     if isclose(det, 0.):
         return None
     adj = [[(m[1][1] * m[2][2] - m[2][1] * m[1][2]) / det,
             (m[2][1] * m[0][2] - m[0][1] * m[2][2]) / det,
             (m[0][1] * m[1][2] - m[1][1] * m[0][2]) / det],
            [(m[1][2] * m[2][0] - m[1][0] * m[2][2]) / det,
             (m[0][0] * m[2][2] - m[0][2] * m[2][0]) / det,
             (m[0][2] * m[1][0] - m[0][0] * m[1][2]) / det],
            [(m[1][0] * m[2][1] - m[1][1] * m[2][0]) / det,
             (m[0][1] * m[2][0] - m[0][0] * m[2][1]) / det,
             (m[0][0] * m[1][1] - m[0][1] * m[1][0]) / det]]
     self.matrix = adj