diff options
Diffstat (limited to 'misc/pylib/robofab/path/intersect.py')
-rw-r--r-- | misc/pylib/robofab/path/intersect.py | 108 |
1 files changed, 0 insertions, 108 deletions
diff --git a/misc/pylib/robofab/path/intersect.py b/misc/pylib/robofab/path/intersect.py deleted file mode 100644 index ea0600c19..000000000 --- a/misc/pylib/robofab/path/intersect.py +++ /dev/null @@ -1,108 +0,0 @@ -from robofab.pens.filterPen import flattenGlyph -from robofab.objects.objectsRF import RGlyph as _RGlyph -import math - -_EPSILON = 1e-15 - - -def normalise(a1, a2): - """Normalise this vector to length 1""" - n = math.sqrt((a1*a1)+(a2*a2)) - return (a1/n, a2/n) - -def inbetween((a1, a2), (b1, b2), (c1, c2)): - """Return True if point b is in between points a and c.""" - x = (a1-_EPSILON<=b1<=c1+_EPSILON) or (a1+_EPSILON>=b1>=c1-_EPSILON) - y = (a2-_EPSILON<=b2<=c2+_EPSILON) or (a2+_EPSILON>=b2>=c2-_EPSILON) - return x == y == True - -def sectlines((a1, a2), (p1, p2), (b1, b2), (q1, q2)): - '''Calculate the intersection point of two straight lines. Result in floats.''' - if (a1, a2) == (p1, p2): - return None - r1 = a1-p1 - r2 = a2-p2 - r1, r2 = normalise(r1, r2) - s1 = b1-q1 - s2 = b2-q2 - s1, s2 = normalise(s1, s2) - f = float(s1*r2 - s2*r1) - if f == 0: - return None - mu = (r1*(q2 - p2) + r2*(p1 - q1)) / f - m1 = mu*s1 + q1 - m2 = mu*s2 + q2 - if (m1, m2) == (a1, a2): - return None - if inbetween((a1, a2), (m1, m2), (p1,p2)) and inbetween((b1, b2), (m1, m2), (q1,q2)): - return m1, m2 - else: - return None - -def _makeFlat(aGlyph, segmentLength = 10): - """Helper function to flatten the glyph with a given approximate segment length.""" - return flattenGlyph(aGlyph, segmentLength) - -def intersect(aGlyph, startPt, endPt, segmentLength=10): - """Find the intersections between a glyph and a straight line.""" - flat = _makeFlat(aGlyph) - return _intersect(flat, startPt, endPt, segmentLength) - -def _intersect(flat, startPt, endPt, segmentLength=10): - """Find the intersections between a flattened glyph and a straight line.""" - if len(flat.contours) == 0: - return None - if startPt == endPt: - return None - sect = None - intersections = {} - # new contains the flattened outline - for c in flat: - l =len(c.points) - for i in range(l): - cur = c.points[i] - next = c.points[(i+1)%l] - sect = sectlines((cur.x, cur.y), (next.x, next.y), startPt, endPt) - if sect is None: - continue - intersections[sect] = 1 - return intersections.keys() - -def intersectGlyphs(glyphA, glyphB, segmentLength=10): - """Approximate the intersection points between two glyphs by - flattening both glyphs and checking each tiny segment for - intersections. Slow, but perhaps more realistic then - solving the equasions. - - Seems to work for basic curves and straights, but untested - for edges cases, alsmost hits, near hits, double points, crap like that. - """ - flatA = _makeFlat(glyphA) - flatB = _makeFlat(glyphB) - intersections = [] - for c in flatA: - l =len(c.points) - for i in range(l): - cur = c.points[i] - next = c.points[(i+1)%l] - sect = _intersect(flatB, (cur.x, cur.y), (next.x, next.y)) - if sect is None: - continue - intersections = intersections + sect - return intersections - -def makeTestGlyph(): - g = _RGlyph() - pen = g.getPen() - pen.moveTo((100, 100)) - pen.lineTo((800, 100)) - pen.curveTo((1000, 300), (1000, 600), (800, 800)) - pen.lineTo((100, 800)) - pen.lineTo((100, 100)) - pen.closePath() - return g - -if __name__ == "__main__": - g = makeTestGlyph() - print intersect(g, (-10, 200), (650, 150)) - print intersect(g, (100, 100), (600, 600)) |