494
|
1 |
#copyright ReportLab Inc. 2000
|
|
2 |
#see license.txt for license details
|
|
3 |
#history http://cvs.sourceforge.net/cgi-bin/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 counter-clockwise. The arc extends from startAng
|
|
24 |
to startAng+extent. I.e. startAng=0 and extent=180 yields an openside-down
|
|
25 |
semi-circle.
|
|
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 = (x2-x1)/2.
|
|
45 |
ry = (y2-y1)/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
|