Jeff, this is fabulous, thank you so much! One remaining question: do you have any hints on how to calculate the arc center given only:
x1,y1 (start) x2,y2 (end) r (radius) winding direction I've been having trouble adapting the formulas Kim pointed to. While I'm ok with Python, algebra isn't my strong suit. thanks again! On Mon, Mar 21, 2011 at 9:30 AM, Jeff Epler <[email protected]> wrote: > Basically this boils down to finding the most extreme X and Y values of > the arc, then checking to see if the extremes are inside the working > area. > > The most extreme points of a circle are at the angles that are multiples > of π/2 (for instance, if you consider a circle as going from 0 to 2π > radians, then it's the angles 0, π/2, π, and 3π/2) > > The most extreme points of an arc are any of those 4 points that lie on > the arc, and also the start and end points of the arc. > > So first, test the start and end points. Next, convert the arc to the > representation > center > radius > start angle > end angle > using atan2 to convert the start and end points to radians. If > necessary, add or subtract 2π from the ending angle in order to make the > rotation go in the right direction. Because atan2 returns a value in > the range [-π..π], this means the possible angles after the addition or > subtraction of 2π are [-3π, 3π]. For each multiple of π/2 between the > angles, compute that point on the arc and test it against the working > area. > > The following lightly-tested Python code implements the method I've > described: > #!/usr/bin/python > from math import sin, cos, atan2, pi, hypot > > def arc_bounds(cx, cy, x0, y0, x1, y1, winding): > """Return the bounding box of an arc given center, first point, final > point, and winding direction (-1 means CW, +1 means CCW)""" > > rad = hypot(y0-cy, x0-cx) > theta1 = atan2(y0-cy, x0-cx) > theta2 = atan2(y1-cy, x1-cx) > > if winding < 0: > while theta2 - theta1 > -1e-12: theta2 -= 2*pi; > else: > while theta2 - theta1 < 1e-12: theta2 += 2*pi; > > if theta2 < theta1: theta1, theta2 = theta2, theta1 > > # xpts, ypts accumulate the points that could be the most extreme points of > # the arc -- the endpoints > xpts = [x0, x1] > ypts = [y0, y1] > > # .. as well as the quadrant points that are included in the arc > for j in range(-6, 7): > th = j * pi / 2 > if th < theta1: continue # before start of arc > if th > theta2: break # after end of arc > > x = cx + rad * cos(th) > y = cy + rad * sin(th) > > xpts.append(x) > ypts.append(y) > > return min(xpts), max(xpts), min(ypts), max(ypts) > > And here are the test cases I tried: > # Full radius-1 circle centered at origin >>>> print "% 4.1f % 4.1f % 4.1f % 4.1f" % arc_bounds(0, 0, 1, 0, 1, 0, 1) > -1.0 1.0 -1.0 1.0 > > # Full radius=sqrt(2) circle centered at origin >>>> print "% 4.1f % 4.1f % 4.1f % 4.1f" % arc_bounds(0, 0, 1, 1, 1, 1, 1) > -1.4 1.4 -1.4 1.4 > > # Partial radius=sqrt(2) circle centered at origin >>>> print "% 4.1f % 4.1f % 4.1f % 4.1f" % arc_bounds(0, 0, 1, 1, -1, 1, 1) > -1.0 1.0 1.0 1.4 > > Jeff > > ------------------------------------------------------------------------------ > Colocation vs. Managed Hosting > A question and answer guide to determining the best fit > for your organization - today and in the future. > http://p.sf.net/sfu/internap-sfd2d > _______________________________________________ > Emc-users mailing list > [email protected] > https://lists.sourceforge.net/lists/listinfo/emc-users > ------------------------------------------------------------------------------ Enable your software for Intel(R) Active Management Technology to meet the growing manageability and security demands of your customers. Businesses are taking advantage of Intel(R) vPro (TM) technology - will your software be a part of the solution? Download the Intel(R) Manageability Checker today! http://p.sf.net/sfu/intel-dev2devmar _______________________________________________ Emc-users mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/emc-users
