494

1 
#copyright ReportLab Inc. 2000


2 
#see license.txt for license details


3 
#history http://cvs.sourceforge.net/cgibin/cvsweb.cgi/reportlab/pdfgen/pdfgeom.py?cvsroot=reportlab


4 
#$Header: /tmp/reportlab/reportlab/pdfgen/pdfgeom.py,v 1.6 2000/10/25 08:57:45 rgbecker Exp $


5 
__version__=''' $Id: pdfgeom.py,v 1.6 2000/10/25 08:57:45 rgbecker Exp $ '''

16

6 
__doc__="""

0

7 
This module includes any mathematical methods needed for PIDDLE.


8 
It should have no dependencies beyond the Python library.


9 


10 
So far, just Robert Kern's bezierArc.


11 


12 
"""


13 


14 
from math import sin, cos, pi, ceil


15 


16 
def bezierArc(x1,y1, x2,y2, startAng=0, extent=90):

47

17 
"""bezierArc(x1,y1, x2,y2, startAng=0, extent=90) > List of Bezier

0

18 
curve control points.


19 


20 
(x1, y1) and (x2, y2) are the corners of the enclosing rectangle. The


21 
coordinate system has coordinates that increase to the right and down.


22 
Angles, measured in degress, start with 0 to the right (the positive X


23 
axis) and increase counterclockwise. The arc extends from startAng


24 
to startAng+extent. I.e. startAng=0 and extent=180 yields an opensidedown


25 
semicircle.


26 


27 
The resulting coordinates are of the form (x1,y1, x2,y2, x3,y3, x4,y4)


28 
such that the curve goes from (x1, y1) to (x4, y4) with (x2, y2) and

47

29 
(x3, y3) as their respective Bezier control points."""

0

30 


31 
x1,y1, x2,y2 = min(x1,x2), max(y1,y2), max(x1,x2), min(y1,y2)


32 


33 
if abs(extent) <= 90:


34 
arcList = [startAng]


35 
fragAngle = float(extent)


36 
Nfrag = 1


37 
else:


38 
arcList = []


39 
Nfrag = int(ceil(abs(extent)/90.))


40 
fragAngle = float(extent) / Nfrag


41 


42 
x_cen = (x1+x2)/2.


43 
y_cen = (y1+y2)/2.


44 
rx = (x2x1)/2.


45 
ry = (y2y1)/2.


46 
halfAng = fragAngle * pi / 360.


47 
kappa = abs(4. / 3. * (1.  cos(halfAng)) / sin(halfAng))


48 


49 
if fragAngle < 0:


50 
sign = 1


51 
else:


52 
sign = 1


53 


54 
pointList = []


55 


56 
for i in range(Nfrag):


57 
theta0 = (startAng + i*fragAngle) * pi / 180.


58 
theta1 = (startAng + (i+1)*fragAngle) *pi / 180.


59 
if fragAngle > 0:


60 
pointList.append((x_cen + rx * cos(theta0),


61 
y_cen  ry * sin(theta0),


62 
x_cen + rx * (cos(theta0)  kappa * sin(theta0)),


63 
y_cen  ry * (sin(theta0) + kappa * cos(theta0)),


64 
x_cen + rx * (cos(theta1) + kappa * sin(theta1)),


65 
y_cen  ry * (sin(theta1)  kappa * cos(theta1)),


66 
x_cen + rx * cos(theta1),


67 
y_cen  ry * sin(theta1)))


68 
else:


69 
pointList.append((x_cen + rx * cos(theta0),


70 
y_cen  ry * sin(theta0),


71 
x_cen + rx * (cos(theta0) + kappa * sin(theta0)),


72 
y_cen  ry * (sin(theta0)  kappa * cos(theta0)),


73 
x_cen + rx * (cos(theta1)  kappa * sin(theta1)),


74 
y_cen  ry * (sin(theta1) + kappa * cos(theta1)),


75 
x_cen + rx * cos(theta1),


76 
y_cen  ry * sin(theta1)))


77 


78 
return pointList
