<s> import objc <EOL> from collections import namedtuple <EOL> from . cocoa import CGPathRelease <EOL> import cPathmatics <EOL> Pathmatician = objc . lookUpClass ( '<STR_LIT>' ) <EOL> def convert_path ( ns_path ) : <EOL> """<STR_LIT>""" <EOL> pth = Pathmatician . cgPath_ ( ns_path ) <EOL> CGPathRelease ( pth ) <EOL> return pth <EOL> try : <EOL> from cPathmatics import fast_inverse_sqrt , angle , distance , coordinates <EOL> isqrt = inverse_sqrt = fast_inverse_sqrt <EOL> except ImportError : <EOL> from math import degrees , atan2 <EOL> from math import sqrt , pow <EOL> from math import radians , sin , cos <EOL> def inverse_sqrt ( x ) : <EOL> return <NUM_LIT:1.0> / sqrt ( x ) <EOL> isqrt = inverse_sqrt <EOL> def angle ( x0 , y0 , x1 , y1 ) : <EOL> a = degrees ( atan2 ( y1 - y0 , x1 - x0 ) ) <EOL> return a <EOL> def distance ( x0 , y0 , x1 , y1 ) : <EOL> return sqrt ( pow ( x1 - x0 , <NUM_LIT:2> ) + pow ( y1 - y0 , <NUM_LIT:2> ) ) <EOL> def coordinates ( x0 , y0 , distance , angle ) : <EOL> x1 = x0 + cos ( radians ( angle ) ) * distance <EOL> y1 = y0 + sin ( radians ( angle ) ) * distance <EOL> return x1 , y1 <EOL> def reflect ( x0 , y0 , x1 , y1 , d = <NUM_LIT:1.0> , a = <NUM_LIT> ) : <EOL> d *= distance ( x0 , y0 , x1 , y1 ) <EOL> a += angle ( x0 , y0 , x1 , y1 ) <EOL> x , y = coordinates ( x0 , y0 , d , a ) <EOL> return x , y <EOL> from cPathmatics import intersects , union , intersect , difference , xor <EOL> try : <EOL> from cPathmatics import linepoint , linelength , curvepoint , curvelength <EOL> except ImportError : <EOL> from math import sqrt , pow <EOL> def linepoint ( t , x0 , y0 , x1 , y1 ) : <EOL> """<STR_LIT>""" <EOL> out_x = x0 + t * ( x1 - x0 ) <EOL> out_y = y0 + t * ( y1 - y0 ) <EOL> return ( out_x , out_y ) <EOL> def linelength ( x0 , y0 , x1 , y1 ) : <EOL> """<STR_LIT>""" <EOL> a = pow ( abs ( x0 - x1 ) , <NUM_LIT:2> ) <EOL> b = pow ( abs ( y0 - y1 ) , <NUM_LIT:2> ) <EOL> return sqrt ( a + b ) <EOL> def curvepoint ( t , x0 , y0 , x1 , y1 , x2 , y2 , x3 , y3 , handles = False ) : <EOL> """<STR_LIT>""" <EOL> mint = <NUM_LIT:1> - t <EOL> x01 = x0 * mint + x1 * t <EOL> y01 = y0 * mint + y1 * t <EOL> x12 = x1 * mint + x2 * t <EOL> y12 = y1 * mint + y2 * t <EOL> x23 = x2 * mint + x3 * t <EOL> y23 = y2 * mint + y3 * t <EOL> out_c1x = x01 * mint + x12 * t <EOL> out_c1y = y01 * mint + y12 * t <EOL> out_c2x = x12 * mint + x23 * t <EOL> out_c2y = y12 * mint + y23 * t <EOL> out_x = out_c1x * mint + out_c2x * t <EOL> out_y = out_c1y * mint + out_c2y * t <EOL> if not handles : <EOL> return ( out_x , out_y , out_c1x , out_c1y , out_c2x , out_c2y ) <EOL> else : <EOL> return ( out_x , out_y , out_c1x , out_c1y , out_c2x , out_c2y , x01 , y01 , x23 , y23 ) <EOL> def curvelength ( x0 , y0 , x1 , y1 , x2 , y2 , x3 , y3 , n = <NUM_LIT:20> ) : <EOL> """<STR_LIT>""" <EOL> length = <NUM_LIT:0> <EOL> xi = x0 <EOL> yi = y0 <EOL> for i in range ( n ) : <EOL> t = <NUM_LIT:1.0> * ( i + <NUM_LIT:1> ) / n <EOL> pt_x , pt_y , pt_c1x , pt_c1y , pt_c2x , pt_c2y = curvepoint ( t , x0 , y0 , x1 , y1 , x2 , y2 , x3 , y3 ) <EOL> c = sqrt ( pow ( abs ( xi - pt_x ) , <NUM_LIT:2> ) + pow ( abs ( yi - pt_y ) , <NUM_LIT:2> ) ) <EOL> length += c <EOL> xi = pt_x <EOL> yi = pt_y <EOL> return length <EOL> from plotdevice import DeviceError <EOL> from Quartz import NSMoveToBezierPathElement as MOVETO , NSLineToBezierPathElement as LINETO <EOL> from Quartz import NSCurveToBezierPathElement as CURVETO , NSClosePathBezierPathElement as CLOSE <EOL> def segment_lengths ( path , relative = False , n = <NUM_LIT:20> ) : <EOL> """<STR_LIT>""" <EOL> lengths = [ ] <EOL> first = True <EOL> for el in path : <EOL> if first == True : <EOL> close_x , close_y = el . x , el . y <EOL> first = False <EOL> elif el . cmd == MOVETO : <EOL> close_x , close_y = el . x , el . y <EOL> lengths . append ( <NUM_LIT:0.0> ) <EOL> elif el . cmd == CLOSE : <EOL> lengths . append ( linelength ( x0 , y0 , close_x , close_y ) ) <EOL> elif el . cmd == LINETO : <EOL> lengths . append ( linelength ( x0 , y0 , el . x , el . y ) ) <EOL> elif el . cmd == CURVETO : <EOL> x3 , y3 , x1 , y1 , x2 , y2 = el . x , el . y , el . ctrl1 . x , el . ctrl1 . y , el . ctrl2 . x , el . ctrl2 . y <EOL> lengths . append ( curvelength ( x0 , y0 , x1 , y1 , x2 , y2 , x3 , y3 , n ) ) <EOL> if el . cmd != CLOSE : <EOL> x0 = el . x <EOL> y0 = el . y <EOL> if relative : <EOL> length = sum ( lengths ) <EOL> try : <EOL> return map ( lambda l : l / length , lengths ) <EOL> except ZeroDivisionError : <EOL> return [ <NUM_LIT:0.0> ] * len ( lengths ) <EOL> else : <EOL> return lengths <EOL> def length ( path , segmented = False , n = <NUM_LIT:20> ) : <EOL> """<STR_LIT>""" <EOL> if not segmented : <EOL> return sum ( segment_lengths ( path , n = n ) , <NUM_LIT:0.0> ) <EOL> else : <EOL> return segment_lengths ( path , relative = True , n = n ) <EOL> def _locate ( path , t , segments = None ) : <EOL> """<STR_LIT>""" <EOL> from . . gfx . geometry import Point <EOL> if segments == None : <EOL> segments = path . segmentlengths ( relative = True ) <EOL> if len ( segments ) == <NUM_LIT:0> : <EOL> raise DeviceError , "<STR_LIT>" <EOL> for i , el in enumerate ( path ) : <EOL> if i == <NUM_LIT:0> or el . cmd == MOVETO : <EOL> closeto = Point ( el . x , el . y ) <EOL> if t <= segments [ i ] or i == len ( segments ) - <NUM_LIT:1> : break <EOL> else : t -= segments [ i ] <EOL> try : t /= segments [ i ] <EOL> except ZeroDivisionError : pass <EOL> if i == len ( segments ) - <NUM_LIT:1> and segments [ i ] == <NUM_LIT:0> : i -= <NUM_LIT:1> <EOL> return ( i , t , closeto ) <EOL> def point ( path , t , segments = None ) : <EOL> """<STR_LIT>""" <EOL> from . . gfx . bezier import Curve <EOL> if len ( path ) == <NUM_LIT:0> : <EOL> raise DeviceError , "<STR_LIT>" <EOL> i , t , closeto = _locate ( path , t , segments = segments ) <EOL> x0 , y0 = path [ i ] . x , path [ i ] . y <EOL> p1 = path [ i + <NUM_LIT:1> ] <EOL> if p1 . cmd == CLOSE : <EOL> x , y = linepoint ( t , x0 , y0 , closeto . x , closeto . y ) <EOL> return Curve ( LINETO , ( ( x , y ) , ) ) <EOL> elif p1 . cmd == LINETO : <EOL> x1 , y1 = p1 . x , p1 . y <EOL> x , y = linepoint ( t , x0 , y0 , x1 , y1 ) <EOL> return Curve ( LINETO , ( ( x , y ) , ) ) <EOL> elif p1 . cmd == CURVETO : <EOL> x3 , y3 , x1 , y1 , x2 , y2 = p1 . x , p1 . y , p1 . ctrl1 . x , p1 . ctrl1 . y , p1 . ctrl2 . x , p1 . ctrl2 . y <EOL> x , y , c1x , c1y , c2x , c2y = curvepoint ( t , x0 , y0 , x1 , y1 , x2 , y2 , x3 , y3 ) <EOL> return Curve ( CURVETO , ( ( c1x , c1y ) , ( c2x , c2y ) , ( x , y ) ) ) <EOL> else : <EOL> raise DeviceError , "<STR_LIT>" % p1 <EOL> def points ( path , amount = <NUM_LIT:100> ) : <EOL> """<STR_LIT>""" <EOL> if len ( path ) == <NUM_LIT:0> : <EOL> raise DeviceError , "<STR_LIT>" <EOL> try : <EOL> delta = <NUM_LIT:1.0> / ( amount - <NUM_LIT:1> ) <EOL> except ZeroDivisionError : <EOL> delta = <NUM_LIT:1.0> <EOL> for i in xrange ( amount ) : <EOL> yield point ( path , delta * i ) <EOL> def contours ( path ) : <EOL> """<STR_LIT>""" <EOL> from . . gfx . bezier import Bezier <EOL> contours = [ ] <EOL> current_contour = None <EOL> empty = True <EOL> for i , el in enumerate ( path ) : <EOL> if el . cmd == MOVETO : <EOL> if not empty : <EOL> contours . append ( current_contour ) <EOL> current_contour = Bezier ( ) <EOL> current_contour . moveto ( el . x , el . y ) <EOL> empty = True <EOL> elif el . cmd == LINETO : <EOL> empty = False <EOL> current_contour . lineto ( el . x , el . y ) <EOL> elif el . cmd == CURVETO : <EOL> empty = False <EOL> current_contour . curveto ( el . ctrl1 . x , el . ctrl1 . y , <EOL> el . ctrl2 . x , el . ctrl2 . y , el . x , el . y ) <EOL> elif el . cmd == CLOSE : <EOL> current_contour . closepath ( ) <EOL> if not empty : <EOL> contours . append ( current_contour ) <EOL> return contours <EOL> def findpath ( points , curvature = <NUM_LIT:1.0> ) : <EOL> """<STR_LIT>""" <EOL> from . . gfx . geometry import Point <EOL> from . . gfx . bezier import Bezier <EOL> from types import TupleType , ListType <EOL> for i , pt in enumerate ( points ) : <EOL> if type ( pt ) in ( TupleType , ListType ) : <EOL> points [ i ] = Point ( pt [ <NUM_LIT:0> ] , pt [ <NUM_LIT:1> ] ) <EOL> if len ( points ) == <NUM_LIT:0> : return None <EOL> if len ( points ) == <NUM_LIT:1> : <EOL> path = Bezier ( None ) <EOL> pt = points [ <NUM_LIT:0> ] <EOL> path . moveto ( pt . x , pt . y ) <EOL> return path <EOL> if len ( points ) == <NUM_LIT:2> : <EOL> path = Bezier ( None ) <EOL> pt1 , pt2 = points [ : <NUM_LIT:2> ] <EOL> path . moveto ( pt1 . x , pt1 . y ) <EOL> path . lineto ( pt2 . x , pt2 . y ) <EOL> return path <EOL> curvature = max ( <NUM_LIT:0> , min ( <NUM_LIT:1> , curvature ) ) <EOL> if curvature == <NUM_LIT:0> : <EOL> path = Bezier ( None ) <EOL> path . moveto ( points [ <NUM_LIT:0> ] . x , points [ <NUM_LIT:0> ] . y ) <EOL> for i in range ( len ( points ) ) : <EOL> path . lineto ( points [ i ] . x , points [ i ] . y ) <EOL> return path <EOL> curvature = <NUM_LIT:4> + ( <NUM_LIT:1.0> - curvature ) * <NUM_LIT> <EOL> dx = { <NUM_LIT:0> : <NUM_LIT:0> , len ( points ) - <NUM_LIT:1> : <NUM_LIT:0> } <EOL> dy = { <NUM_LIT:0> : <NUM_LIT:0> , len ( points ) - <NUM_LIT:1> : <NUM_LIT:0> } <EOL> bi = { <NUM_LIT:1> : - <NUM_LIT> } <EOL> ax = { <NUM_LIT:1> : ( points [ <NUM_LIT:2> ] . x - points [ <NUM_LIT:0> ] . x - dx [ <NUM_LIT:0> ] ) / <NUM_LIT> } <EOL> ay = { <NUM_LIT:1> : ( points [ <NUM_LIT:2> ] . y - points [ <NUM_LIT:0> ] . y - dy [ <NUM_LIT:0> ] ) / <NUM_LIT> } <EOL> for i in range ( <NUM_LIT:2> , len ( points ) - <NUM_LIT:1> ) : <EOL> bi [ i ] = - <NUM_LIT:1.0> / ( curvature + bi [ i - <NUM_LIT:1> ] ) <EOL> ax [ i ] = - ( points [ i + <NUM_LIT:1> ] . x - points [ i - <NUM_LIT:1> ] . x - ax [ i - <NUM_LIT:1> ] ) * bi [ i ] <EOL> ay [ i ] = - ( points [ i + <NUM_LIT:1> ] . y - points [ i - <NUM_LIT:1> ] . y - ay [ i - <NUM_LIT:1> ] ) * bi [ i ] <EOL> r = range ( <NUM_LIT:1> , len ( points ) - <NUM_LIT:1> ) <EOL> r . reverse ( ) <EOL> for i in r : <EOL> dx [ i ] = ax [ i ] + dx [ i + <NUM_LIT:1> ] * bi [ i ] <EOL> dy [ i ] = ay [ i ] + dy [ i + <NUM_LIT:1> ] * bi [ i ] <EOL> path = Bezier ( None ) <EOL> path . moveto ( points [ <NUM_LIT:0> ] . x , points [ <NUM_LIT:0> ] . y ) <EOL> for i in range ( len ( points ) - <NUM_LIT:1> ) : <EOL> path . curveto ( points [ i ] . x + dx [ i ] , <EOL> points [ i ] . y + dy [ i ] , <EOL> points [ i + <NUM_LIT:1> ] . x - dx [ i + <NUM_LIT:1> ] , <EOL> points [ i + <NUM_LIT:1> ] . y - dy [ i + <NUM_LIT:1> ] , <EOL> points [ i + <NUM_LIT:1> ] . x , <EOL> points [ i + <NUM_LIT:1> ] . y ) <EOL> return path <EOL> def insert_point ( path , t ) : <EOL> """<STR_LIT>""" <EOL> i , t , closeto = _locate ( path , t ) <EOL> x0 = path [ i ] . x <EOL> y0 = path [ i ] . y <EOL> p1 = path [ i + <NUM_LIT:1> ] <EOL> p1cmd , x3 , y3 , x1 , y1 , x2 , y2 = p1 . cmd , p1 . x , p1 . y , p1 . ctrl1 . x , p1 . ctrl1 . y , p1 . ctrl2 . x , p1 . ctrl2 . y <EOL> if p1cmd == CLOSE : <EOL> pt_cmd = LINETO <EOL> pt_x , pt_y = linepoint ( t , x0 , y0 , closeto . x , closeto . y ) <EOL> elif p1cmd == LINETO : <EOL> pt_cmd = LINETO <EOL> pt_x , pt_y = linepoint ( t , x0 , y0 , x3 , y3 ) <EOL> elif p1cmd == CURVETO : <EOL> pt_cmd = CURVETO <EOL> pt_x , pt_y , pt_c1x , pt_c1y , pt_c2x , pt_c2y , pt_h1x , pt_h1y , pt_h2x , pt_h2y = curvepoint ( t , x0 , y0 , x1 , y1 , x2 , y2 , x3 , y3 , True ) <EOL> else : <EOL> raise DeviceError , "<STR_LIT>" <EOL> new_path = Bezier ( None ) <EOL> new_path . moveto ( path [ <NUM_LIT:0> ] . x , path [ <NUM_LIT:0> ] . y ) <EOL> for j in range ( <NUM_LIT:1> , len ( path ) ) : <EOL> if j == i + <NUM_LIT:1> : <EOL> if pt_cmd == CURVETO : <EOL> new_path . curveto ( pt_h1x , pt_h1y , <EOL> pt_c1x , pt_c1y , <EOL> pt_x , pt_y ) <EOL> new_path . curveto ( pt_c2x , pt_c2y , <EOL> pt_h2x , pt_h2y , <EOL> path [ j ] . x , path [ j ] . y ) <EOL> elif pt_cmd == LINETO : <EOL> new_path . lineto ( pt_x , pt_y ) <EOL> if path [ j ] . cmd != CLOSE : <EOL> new_path . lineto ( path [ j ] . x , path [ j ] . y ) <EOL> else : <EOL> new_path . closepath ( ) <EOL> else : <EOL> raise DeviceError , "<STR_LIT>" % pt_cmd <EOL> else : <EOL> if path [ j ] . cmd == MOVETO : <EOL> new_path . moveto ( path [ j ] . x , path [ j ] . y ) <EOL> if path [ j ] . cmd == LINETO : <EOL> new_path . lineto ( path [ j ] . x , path [ j ] . y ) <EOL> if path [ j ] . cmd == CURVETO : <EOL> new_path . curveto ( path [ j ] . ctrl1 . x , path [ j ] . ctrl1 . y , <EOL> path [ j ] . ctrl2 . x , path [ j ] . ctrl2 . y , <EOL> path [ j ] . x , path [ j ] . y ) <EOL> if path [ j ] . cmd == CLOSE : <EOL> new_path . closepath ( ) <EOL> return new_path </s>
