0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022"""drawing and graphics related routines to use as mixin classes with objects of the
0023complex plane"""
0024
0025
0026from pygeo.base.support.pygeoconstants import DIAMOND, FILL, LINES
0027from pygeo.base.analytics.pygeomath import *
0028from pygeoprimitives import *
0029from pygeo.base.analytics._position3 import Position3
0030from pygeo.base.support.pygeoopts import EPS, COMPLEX_MAX, TEST_MAX
0031
0032def constrain_draw(pos):
0033 """for constraining the drawing position of points where largs values
0034 relative to the scene scale can cause display prblems. The option to
0035 turn off drawing constraints and the 'MAX' constant is by editing the
0036 pygeoopts.py file"""
0037
0038 if TEST_MAX:
0039 try:
0040 m=max(absolute(pos))
0041 if m > COMPLEX_MAX:
0042 return (pos/m)*COMPLEX_MAX
0043 else:
0044 return pos
0045 except OverflowError:
0046 return (COMPLEX_MAX,COMPLEX_MAX,COMPLEX_MAX)
0047 else:
0048 return pos
0049
0050class zdrawPoint:
0051 """drawing back-end for objects derived from the _zPoint class"""
0052
0053 def _redraw(self):
0054 """send current position in scene to render object, and render
0055 in accordance with style sttribute"""
0056
0057 if self.init_draw:
0058 if self.style==DIAMOND:
0059
0060 self.f.pos=constrain_draw(self.pos)
0061 else:
0062 self.rend[0].pos =constrain_draw(self.pos)
0063 if self.label:
0064 self.lab.pos= constrain_draw(self.pos)
0065
0066 def do_trace(self):
0067 """
0068 If on update, traced point has moved within limits defined by
0069 'mintrace' and 'maxtrace' append its new position to the trace
0070 curve
0071 """
0072
0073 delta= self.distance(self.tmparray)
0074 if (self.mintrace < delta < self.maxtrace):
0075 from pygeo.base.geometry_complex.z_points import zFixedPoint
0076 self.rtrace.append(zFixedPoint(self.real,self.imag,pointsize=self.pointsize,color=self.tracecolor,
0077 level=self.level))
0078 if self.tracecurve:
0079 self.ntrace.append(pos=constrain_draw(self.pos))
0080 self.tmparray.set(self)
0081
0082 def reset_trace(self):
0083 """Re-intialize list of loci points to None"""
0084
0085 if self.trace:
0086 for r in self.rtrace:
0087 r.show=False
0088 r.setshow()
0089 self.rtrace=[]
0090 self.tmparrayset(self)
0091
0092 def reset_trace_curves(self):
0093 """Re-intialize list of traced curves to None"""
0094
0095 if self.trace:
0096 self.ntrace.pos=[]
0097
0098 def draw(self):
0099 """For consistency in iterating Element's rendering objects, all elements
0100 rendering information is in a list called self.rend. In the case of Points,
0101 it is either a single element list, containing a cvisual sphere object, or a
0102 2 element list with each element an oriented cvisual pyramid object, which together
0103 form a diamond shape representing the point"""
0104
0105 if self.style==DIAMOND:
0106 self.f=frame()
0107 self.f.rotate(angle=PI/4.,axis=(1,0,0),pos=(0,0,0))
0108 ps=self.pointsize
0109 self.rend.append(pyramid(frame=self.f,size=(ps,sqrt(2)*ps,sqrt(2)*ps)))
0110 self.rend.append(pyramid(frame=self.f,size=(-ps,sqrt(2)*ps,sqrt(2)*ps)))
0111 for r in self.rend:
0112 r.color=r.initcolor=self.color
0113 else:
0114 self.rend.append(sphere(radius=self.pointsize))
0115 self.rend[0].color=self.rend[0].initcolor=self.color
0116 if self.label:
0117 self.lab=label(box=False, opacity=0.,
0118 color=self.fontcolor,text=self.label,
0119 xoffset=self.fontXoffset,yoffset= self.fontYoffset,
0120 space=.5, height=self.fontsize, border=2)
0121 if self.trace:
0122 if self.tracecurve:
0123 self.ntrace = curve(radius=self.tracewidth,
0124 color=self.tracecolor)
0125 self.init_draw=True
0126
0127 def povout(self,buf):
0128 """ export the scene's points to PovRay SDL"""
0129
0130 color=self.color
0131 size=self.pointsize
0132 print >>buf,"//POINT"
0133 if hasattr(self,'complex'):
0134 x=self.real
0135 y=self.imag
0136 z=0
0137 else:
0138 x=self.x
0139 y=self.y
0140 z=self.z
0141 if not self.style==DIAMOND:
0142 print >>buf,"""
0143sphere {
0144 <%f, %f, %f> , %f
0145 pigment {
0146 color rgb <%f, %f, %f> filter 0 transmit 0.0 }}
0147 """ %(x,y,z,
0148 size,color[0],color[1],color[2])
0149 if self.trace:
0150 print >>buf,"//POINT TRACE"
0151 for trace in self.rtrace:
0152 trace.povout(buf)
0153 i=0
0154 while i < len(self.ntrace.pos)-1:
0155 p1=self.ntrace.pos[i]
0156 p2=self.ntrace.pos[i+1]
0157 print >> buf, """
0158cylinder{
0159 <%f, %f, %f> , <%f, %f, %f>, %f
0160 pigment {color rgb <%f, %f, %f> filter 0 transmit 0.0}}
0161 """ %(p1[0],p1[1],p1[2],
0162 p2[0],p2[1],p2[2],
0163 self.tracewidth,self.tracecolor[0],
0164 self.tracecolor[1],self.tracecolor[2])
0165 print >>buf,"""
0166sphere {
0167 <%f, %f, %f> , %f
0168 pigment {color rgb <%f, %f, %f> filter 0 transmit 0.0 }}
0169 """ %(p1[0],p1[1],p1[2],
0170 self.tracewidth,self.tracecolor[0],
0171 self.tracecolor[1],self.tracecolor[2])
0172 i+=1
0173 else:
0174 print >>buf,"""
0175union{
0176 prism {
0177 conic_sweep
0178 linear_spline
0179 0, // height 1
0180 1, // height 2
0181 5, // the number of points making up the shape...
0182 <1,0>,<0,1>,<-1,0>,<0,-1>,<1,0>
0183 translate <0, -1, 0>
0184 pigment { color rgb <%f, %f, %f> filter 0 transmit 0.0}
0185 }
0186
0187 prism {
0188 conic_sweep
0189 linear_spline
0190 0, // height 1
0191 1, // height 2
0192 5, // the number of points making up the shape...
0193 <1,0>,<0,1>,<-1,0>,<0,-1>,<1,0>
0194 rotate <180, 0, 0>
0195 translate <0, 1, 0>
0196 pigment { color rgb <%f, %f, %f> filter 0 transmit 0.0 }
0197
0198 }
0199 scale <%f,%f,%f>
0200 translate <%f, %f, %f>
0201
0202}
0203 """ %(color[0],color[1],color[2],color[0],color[1],color[2],
0204 size,size,size,x,y,z)
0205
0206class zdrawLine:
0207 """drawing back-end for objects derived from the _zLine class"""
0208
0209 def _redraw(self):
0210 """send current position of line frame's axis and position based on the line's current
0211 defining Hermitian matrix"""
0212
0213 h=self._hermitian
0214 b = h.C*1j
0215 c= -h.D/(2*h.B)
0216 self.f.axis=vector(b.real,b.imag,0)
0217 self.f.pos=vector(c.real,c.imag,0)
0218 self.rend[0].pos=self.m
0219 if self.label:
0220 self.setlabel()
0221
0222 def setlabel(self):
0223 """set position of line's lab, if any"""
0224
0225 labelpos=add(multiply(1-self.lratio,self.p1),
0226 multiply(self.lratio,self.p2))
0227 self.lab.pos=labelpos
0228
0229 def draw(self):
0230 """for consistency in iterating Element's rendering objects, all elements
0231 rendering information is in a list called self.rend. In the case of zLines,
0232 it is a single element list containing a cvisual curve object"""
0233
0234 self.f=frame()
0235 self.m = array([[COMPLEX_MAX,0.,0.],[-COMPLEX_MAX,0,0]])
0236 self.rend=[curve(frame=self.f,color=self.color,
0237 radius=self.linewidth)]
0238 if self.label:
0239 self.lab=label(frame=self.f,box=False, opacity=0.,
0240 color=self.fontcolor,text=self.label,
0241 xoffset=self.fontXoffset,yoffset= self.fontYoffset,
0242 space=.5, height=self.fontsize, border=2)
0243
0244 self.init_draw=True
0245
0246 def povout(self,buf):
0247 """ export the scene's lines to PovRay SDL"""
0248
0249 print >> buf, "//LINE"
0250 p1=self.rend[0].pos[0]
0251 p2=self.rend[0].pos[1]
0252 pos=self.f.pos
0253 theta,phi=Position3(self.f.axis).polar()
0254 d_convert=180/PI
0255 theta*=d_convert
0256 phi*=d_convert
0257 rotate = "rotate<%f,%f,%f>" %(0.,90.+theta,phi)
0258 translate="translate<%f,%f,%f>" %(pos.x,pos.y,0.)
0259 if max(absolute(p1-p2)) > EPS:
0260 print >> buf, """
0261cylinder{
0262<%f, %f, %f> , <%f, %f, %f>, %f
0263%s
0264%s
0265pigment {color rgb <%f, %f, %f> filter 0 transmit 0.0
0266}
0267}""" %(p1[0],p1[1],p1[2],
0268 p2[0],p2[1],p2[2],self.linewidth,
0269 rotate,
0270 translate,
0271 self.color[0],self.color[1],self.color[2])
0272
0273class zdrawCircle:
0274 """drawing back-end for objects derived from the _zCircle class"""
0275
0276 def _redraw(self):
0277 """send current position of circle's center position and radius based of the circle's
0278 defining Hermitian matrix"""
0279
0280 try:
0281 h= self._hermitian
0282 except AttributeError:
0283 return
0284 if absolute(h.A) > .001:
0285 if self._radius > COMPLEX_MAX:
0286 radius= COMPLEX_MAX
0287 else:
0288 radius=self._radius
0289 self.f.pos=constrain_draw(self._center.pos)
0290 self.rend[0].pos=constrain_draw((self.c*radius))
0291
0292 else:
0293 b = h.C*1j
0294 try:
0295 c= -h.D/(2*h.B)
0296 except ZeroDivisionError:
0297 c=COMPLEX_MAX
0298 self.f.axis=vector(b.real,b.imag,0)
0299 self.f.pos=vector(c.real,c.imag,0)
0300 self.rend[0].pos=self.m
0301
0302 def draw(self):
0303 """the circle object is represented either by a convex polygon or as curve -
0304 we take advantage of the cvisual frame object, assigning the drawing primitives to one
0305 frame, so that further manipulation is of the frame, not the primtives themselves"""
0306
0307 self.f = frame()
0308 div=2*PI/self.precision
0309 t = arrayrange(div,2*PI+2*div,div)
0310 self.m = array([[COMPLEX_MAX,0.,0.],[-COMPLEX_MAX,0,0]])
0311 self.c = transpose( (sin(t), cos(t),0*t) )
0312 if self.style==FILL:
0313 self.rend=[convex(frame=self.f,color=self.color)]
0314 else:
0315 self.rend=[curve(frame=self.f,color=self.color,
0316 radius=self.linewidth)]
0317 if self.show_normal:
0318 self.nrend=arrow(pos=(0,0,0),shaftwidth=self.normal_width,
0319 color=self.color)
0320 self.init_draw=True
0321
0322 def povout(self,buf):
0323 """ export the scene's circles to PovRay SDL"""
0324
0325 print >> buf, "//CIRCLE"
0326 center=self._center
0327 if hasattr(self._radius,'real'):
0328 radius=self._radius.real
0329 else:
0330 radius = self._radius
0331 color=self.color
0332 translate="translate<%f,%f,%f>" %(center.x,center.y,0.)
0333 if self._hermitian.A <> 0:
0334 if self.style==LINES:
0335 print >> buf,"""
0336torus {
0337 %f, %f
0338 rotate <90,0,00>
0339 %s
0340 pigment {color rgb <%f, %f, %f> filter 0 transmit 0.0
0341}
0342}""" %(radius,self.linewidth,translate,
0343 color[0],color[1],color[2])
0344 else:
0345 poly=""
0346 for pos in self.rend[0].pos:
0347 poly = poly + "<%f,%f,%f>" %(pos[0],pos[1],pos[2])
0348 print >> buf,"""
0349polygon{
0350 %i,
0351 %s
0352 %s
0353 pigment {color rgb <%f, %f, %f> filter 0 transmit 0.0
0354 }
0355}""" %(len(self.rend[0].pos),poly,translate,
0356 self.color[0],self.color[1],self.color[2])
0357 else:
0358 print >> buf, "//LINE"
0359 p1=self.rend[0].pos[0]
0360 p2=self.rend[0].pos[1]
0361 pos=self.f.pos
0362 theta,phi=Position3(self.f.axis).polar()
0363 d_convert=180/PI
0364 theta*=d_convert
0365 phi*=d_convert
0366 rotate = "rotate<%f,%f,%f>" %(0.,90.+theta,phi)
0367 translate="translate<%f,%f,%f>" %(pos.x,pos.y,0.)
0368 if max(absolute(p1-p2)) > EPS:
0369 print >> buf, """
0370cylinder{
0371<%f, %f, %f> , <%f, %f, %f>, %f
0372%s
0373%s
0374pigment {color rgb <%f, %f, %f> filter 0 transmit 0.0
0375}
0376}""" %(p1[0],p1[1],p1[2],
0377 p2[0],p2[1],p2[2],self.linewidth,
0378 rotate,
0379 translate,
0380 self.color[0],self.color[1],self.color[2])
0381
0382class zdrawArray:
0383 """generalized drawing back-end for array objects, i.e. _zLineArray, _zCirclePencil ,etc. """
0384
0385 def _redraw(self):
0386 """iterate through the objects of the array and call the objects _redraw routine to redraw
0387 at its current position"""
0388
0389 for object in self:
0390 object._redraw()
0391
0392 def draw(self):
0393 """the objects of the array get initialized on creation by the array's init() method - this is only
0394 to mark the array itself as initialized """
0395
0396 self.init_draw=True
0397
0398 def povout(self,buf):
0399 """ export the objects of the scene's arrays to PovRay SDL"""
0400 if hasattr(self,'zpoints'):
0401 objects=self.zpoints
0402 if hasattr(self,'zcircles'):
0403 objects=self.zcircles
0404 if hasattr(self,'zlines'):
0405 objects=self.zlines
0406
0407 print >> buf,"//BEGIN ARRAY//"
0408 for object in self:
0409 object.povout(buf)
0410
0411
0412__author__ = "Arthur Siegel <ajsiegel@optonline.com>"
0413__date__ = "Date: 2006-02-02 "
0414__revision__ = "Revision: a1"
0415__url__ = "URL: http://source.net/projects/pygeo"
0416__copyright__ ="GPL <http://www.opensource.org/licenses/gpl-license.php>"