Thanks so much to everyone.  I found the arc code thanks to Chris and,
after combining it with code from Jeff now have a working function
that returns the bounding box of an arc given just
x0,y0,x1,y1,r,direction.  In case it's useful to anyone else, now or
in the future, I'm posting it below.  It is tailored to fit my code
(I'll probably adjust it more honestly), but should be adaptable to
anyone.

---

import math

TINY = 1e-12
M_PI_2l = 1.5707963267948966192313216916397514
G_2 = "cw"
G_3 = "ccw"

def getcenter(current_x,current_y,end_x,end_y,radius,move):
# gets the center point of an arc given the values needed to
# draw an arc in EMC2.  algorithm taken from arc_interp.cc

    abs_radius = math.fabs(radius)
    mid_x = (end_x + current_x) / 2.0
    mid_y = (end_y + current_y) / 2.0
    half_length = math.hypot((mid_x - end_x), (mid_y - end_y))

    # allow a small error for semicircle
    if ((half_length / abs_radius) > (1 - TINY)):
        half_length = abs_radius

    # check needed before calling asin
    if (((move == G_2) and (radius > 0)) or ((move == G_3) and (radius < 0))):
        theta = math.atan2((end_y - current_y), (end_x - current_x)) - M_PI_2l
    else:
        theta = math.atan2((end_y - current_y), (end_x - current_x)) + M_PI_2l

    turn2 = math.asin(half_length / abs_radius)
    offset = abs_radius * math.cos(turn2)
    center_x = mid_x + (offset * math.cos(theta))
    center_y = mid_y + (offset * math.sin(theta))

    #  *turn = (move == G_2) ? -1 : 1
    return (center_x,center_y)


def arcbounds(x0, y0, x1, y1, r, winding):
   """Return the bounding box of an arc given center, first point, final
   point, and winding direction"""

   center = getcenter(x0,y0,x1,y1,r,winding)
   cx = center[0]
   cy = center[1]

   rad = math.hypot(y0-cy, x0-cx)
   theta1 = math.atan2(y0-cy, x0-cx)
   theta2 = math.atan2(y1-cy, x1-cx)

   if winding == "cw":
       while theta2 - theta1 > -1e-12: theta2 -= 2*math.pi;
   else:
       while theta2 - theta1 < 1e-12: theta2 += 2*math.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 * math.pi / 2
       if th < theta1: continue  # before start of arc
       if th > theta2: break     # after end of arc

       x = cx + rad * math.cos(th)
       y = cy + rad * math.sin(th)

       xpts.append(x)
       ypts.append(y)

   return min(xpts), max(xpts), min(ypts), max(ypts)


print arc_bounds(-4.5,0,-4.5,4,2,"cw")

---

------------------------------------------------------------------------------
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

Reply via email to