1
from reportlab.lib import colors
2
from reportlab.lib.attrmap import *
3
from reportlab.pdfgen.canvas import Canvas
4
from reportlab.graphics.shapes import Group, Drawing, Ellipse, Wedge, String, STATE_DEFAULTS, Polygon, Line
6
def _getShaded(col,shd=None,shading=0.1):
8
from reportlab.lib.colors import Blacker
9
if col: shd = Blacker(col,1-shading)
12
def _getLit(col,shd=None,lighting=0.1):
14
from reportlab.lib.colors import Whiter
15
if col: shd = Whiter(col,1-lighting)
19
def _draw_3d_bar(G, x1, x2, y0, yhigh, xdepth, ydepth,
20
fillColor=None, fillColorShaded=None,
21
strokeColor=None, strokeWidth=1, shading=0.1):
22
fillColorShaded = _getShaded(fillColor,None,shading)
23
fillColorShadedTop = _getShaded(fillColor,None,shading/2.0)
25
def _add_3d_bar(x1, x2, y1, y2, xoff, yoff,
26
G=G,strokeColor=strokeColor, strokeWidth=strokeWidth, fillColor=fillColor):
27
G.add(Polygon((x1,y1, x1+xoff,y1+yoff, x2+xoff,y2+yoff, x2,y2),
28
strokeWidth=strokeWidth, strokeColor=strokeColor, fillColor=fillColor,strokeLineJoin=1))
32
if y0!=yhigh: #non-zero height
33
_add_3d_bar( x2, x2, y0, yhigh, xdepth, ydepth, fillColor=fillColorShaded) #side
35
_add_3d_bar(x1, x2, usd, usd, xdepth, ydepth, fillColor=fillColorShadedTop) #top
37
G.add(Polygon((x1,y0,x2,y0,x2,yhigh,x1,yhigh),
38
strokeColor=strokeColor, strokeWidth=strokeWidth, fillColor=fillColor,strokeLineJoin=1)) #front
41
G.add(Line( x1, usd, x2, usd, strokeWidth=strokeWidth, strokeColor=strokeColor or fillColorShaded))
44
def __init__(self,y0,y1, slope, fillColor, fillColorShaded, shading=0.1):
48
self.fillColor = fillColor
49
self.fillColorShaded = _getShaded(fillColor,fillColorShaded,shading)
51
def _ystrip_poly( x0, x1, y0, y1, xoff, yoff):
52
return [x0,y0,x0+xoff,y0+yoff,x1+xoff,y1+yoff,x1,y1]
55
def _make_3d_line_info( G, x0, x1, y0, y1, z0, z1,
57
fillColor, fillColorShaded=None, tileWidth=1,
58
strokeColor=None, strokeWidth=None, strokeDashArray=None,
61
xdepth = zwidth*theta_x
62
ydepth = zwidth*theta_y
63
depth_slope = xdepth==0 and 1e150 or -ydepth/float(xdepth)
66
slope = x==0 and 1e150 or (y1-y0)/x
68
c = slope>depth_slope and _getShaded(fillColor,fillColorShaded,shading) or fillColor
76
T = ((y1-y0)**2+(x1-x0)**2)**0.5
77
tileStrokeWidth *= tileWidth
81
n = int(T/float(tileWidth))+1
95
P = Polygon(_ystrip_poly(x_0, x_1, y_0, y_1, xdepth, ydepth),
96
fillColor = c, strokeColor=c, strokeWidth=tileStrokeWidth)
97
a((0,z0,z1,x_0,y_0,P))
101
from math import pi, sin, cos
107
return (angle*pi)/180
109
def mod_2pi(radians):
110
radians = radians % _2pi
111
if radians<-1e-6: radians += _2pi
125
def __init__(self,s,i,data):
132
x0,y0,x1,y1 = x1,y1,x0,y0
133
# (y-y0)*(x1-x0) = (y1-y0)*(x-x0)
134
# (x1-x0)*y + (y0-y1)*x = y0*(x1-x0)+x0*(y0-y1)
136
self.a = float(x1-x0)
137
self.b = float(y1-y0)
147
return '[(%s,%s),(%s,%s)]' % (self.x0,self.y0,self.x1,self.y1)
151
def intersect(self,o,I):
152
'''try to find an intersection with _Segment o
157
if ox0>self.x1: return 1
158
if o.s==self.s and o.i in (self.i-1,self.i+1): return
164
if -1e-8<det<1e-8: return
167
u = (oa*dy - ob*dx)/det
168
ou = (a*dy - b*dx)/det
169
if u<0 or u>1 or ou<0 or ou>1: return
173
t = self.s,self.i,x,y
174
if t not in I: I.append(t)
177
if t not in I: I.append(t)
180
return cmp((a.x0,a.x1,a.y0,a.y1,a.s,a.i),(b.x0,b.x1,b.y0,b.y1,b.s,b.i))
182
def find_intersections(data,small=0):
184
data is a sequence of series
185
each series is a list of (x,y) coordinates
186
where x & y are ints or floats
188
find_intersections returns a sequence of 4-tuples
191
where i is a data index j is an insertion position for data[i]
192
and x, y are coordinates of an intersection of series data[i]
193
with some other series. If correctly implemented we get all such
194
intersections. We don't count endpoint intersections and consider
195
parallel lines as non intersecting (even when coincident).
196
We ignore segments that have an estimated size less than small.
199
#find all line segments
202
for s in xrange(len(data)):
207
for i in xrange(1,n):
208
seg = _Segment(s,i,data)
209
if seg.a+abs(seg.b)>=small: a(seg)
213
for i in xrange(0,n-1):
215
for j in xrange(i+1,n):
216
if s.intersect(S[j],I)==1: break
220
if __name__=='__main__':
221
from reportlab.graphics.shapes import Drawing
222
from reportlab.lib.colors import lightgrey, pink
224
_draw_3d_bar(D, 10, 20, 10, 50, 5, 5, fillColor=lightgrey, strokeColor=pink)
225
_draw_3d_bar(D, 30, 40, 10, 45, 5, 5, fillColor=lightgrey, strokeColor=pink)
227
D.save(formats=['pdf'],outDir='.',fnRoot='_draw_3d_bar')
229
print find_intersections([[(0,0.5),(1,0.5),(0.5,0),(0.5,1)],[(.2666666667,0.4),(0.1,0.4),(0.1,0.2),(0,0),(1,1)],[(0,1),(0.4,0.1),(1,0.1)]])
230
print find_intersections([[(0.1, 0.2), (0.1, 0.4)], [(0, 1), (0.4, 0.1)]])
231
print find_intersections([[(0.2, 0.4), (0.1, 0.4)], [(0.1, 0.8), (0.4, 0.1)]])
232
print find_intersections([[(0,0),(1,1)],[(0.4,0.1),(1,0.1)]])
233
print find_intersections([[(0,0.5),(1,0.5),(0.5,0),(0.5,1)],[(0,0),(1,1)],[(0.1,0.8),(0.4,0.1),(1,0.1)]])