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