def elliptical_arc_to(x1, y1, rx, ry, phi, large_arc_flag, sweep_flag, x2, y2):
<EOL>rx = abs(rx)<EOL>ry = abs(ry)<EOL>phi = phi % <NUM_LIT><EOL>if x1==x2 and y1==y2:<EOL><INDENT>return []<EOL><DEDENT>if rx == <NUM_LIT:0> or ry == <NUM_LIT:0>:<EOL><INDENT>return [(x2,y2)]<EOL><DEDENT>rphi = radians(phi)<EOL>cphi = cos(rphi)<EOL>sphi = sin(rphi)<EOL>dx = <NUM_LIT:0.5>*(x1 - x2)<EOL>dy = <NUM_LIT:0.5>*(y1 - y2)<EOL>x1p =  cphi * dx + sphi * dy<EOL>y1p = -sphi * dx + cphi * dy<EOL>lam = (x1p/rx)**<NUM_LIT:2> + (y1p/ry)**<NUM_LIT:2><EOL>if lam > <NUM_LIT:1.0>:<EOL><INDENT>scale = sqrt(lam)<EOL>rx *= scale<EOL>ry *= scale<EOL><DEDENT>num = max((rx*ry)**<NUM_LIT:2> - (rx*y1p)**<NUM_LIT:2> - (ry*x1p)**<NUM_LIT:2>, <NUM_LIT:0.0>)<EOL>den = ((rx*y1p)**<NUM_LIT:2> + (ry*x1p)**<NUM_LIT:2>)<EOL>a = sqrt(num / den)<EOL>cxp = a * rx*y1p/ry<EOL>cyp = -a * ry*x1p/rx<EOL>if large_arc_flag == sweep_flag:<EOL><INDENT>cxp = -cxp<EOL>cyp = -cyp<EOL><DEDENT>mx = <NUM_LIT:0.5>*(x1+x2)<EOL>my = <NUM_LIT:0.5>*(y1+y2)<EOL>dx = (x1p-cxp) / rx<EOL>dy = (y1p-cyp) / ry<EOL>dx2 = (-x1p-cxp) / rx<EOL>dy2 = (-y1p-cyp) / ry<EOL>theta1 = angle(<NUM_LIT:1>,<NUM_LIT:0>,dx,dy)<EOL>dtheta = angle(dx,dy,dx2,dy2)<EOL>if not sweep_flag and dtheta > <NUM_LIT:0>:<EOL><INDENT>dtheta -= <NUM_LIT><EOL><DEDENT>elif sweep_flag and dtheta < <NUM_LIT:0>:<EOL><INDENT>dtheta += <NUM_LIT><EOL><DEDENT>p = []<EOL>control_points = bezier_arc(cxp-rx,cyp-ry,cxp+rx,cyp+ry, theta1, dtheta)<EOL>for x1p,y1p, x2p,y2p, x3p,y3p, x4p,y4p in control_points:<EOL><INDENT>p.append((<EOL>transform_from_local(x2p,y2p,cphi,sphi,mx,my) +<EOL>transform_from_local(x3p,y3p,cphi,sphi,mx,my) +<EOL>transform_from_local(x4p,y4p,cphi,sphi,mx,my)<EOL>))<EOL><DEDENT>return p<EOL>
An elliptical arc approximated with Bezier curves or a line segment.
Algorithm taken from the SVG 1.1 Implementation Notes:
http://www.w3.org/TR/SVG/implnote.html#ArcImplementationNotes