* Main sequence -- instantiates objects, sets properties, * triggers methods. close tables otetra = createobject("tetrahedron") otetra.setcolor("Orange") otetra.writeoutput() otetra.setcolor("Black") otetra.rotate(90,"X") otetra.writeoutput() otetra.rotate(-90,"X") && set the data table back how it was release otetra return * The class definitions below are what define the properties * and behaviors of the instantiated objects. define class tetrahedron as polyhedron procedure init(ptable,etable) if parameters()=0 this.setpoints("tetpoints.dbf") this.setedges("tetedges.dbf") else this.setpoints(ptable) this.setedges(etable) endif * the parent class has code for opening both tables, no * matter what their names (always the same aliases), so * invoke the parent version of this init() method too polyhedron::init() endproc enddefine define class polyhedron as custom add object oWritePOV as WritePOV add object oMatrixOps as MatrixOps color = "" degrees = 0 && default rotation angle axis = "X" && default axis of rotation procedure init(ptable,etable) if parameters()>0 this.setpoints(ptable) && inform imported objects this.setedges(etable) && inform imported objects endif if not used("points") select select(1) * open the Points table (alias points) use (this.owritepov.pointstable) alias points order pointid endif if not used("edges") * open the Edges table (alias edges) select select(1) use (this.owritepov.edgestable) alias edges endif endproc procedure setpoints(dbname) this.omatrixops.pointstable = dbname this.owritepov.pointstable = dbname endproc procedure setedges(dbname) this.owritepov.edgestable = dbname endproc procedure setcolor(cname) this.owritepov.shapecolor = cname endproc procedure setrotate(deg,axis) this.degrees = deg * pi()/180 this.omatrixops.setdegrees(this.degrees) this.axis = axis this.omatrixops.axis = this.axis endproc procedure writeoutput this.owritepov.writeoutput() endproc procedure rotate(degrees, axis) if parameters()>0 this.setrotate(degrees, axis) endif if not used("points") select select(1) use (this.omatrixops.pointstable) alias points order pointid endif select points go top do case case this.axis="X" this.omatrixops.xrotate() case this.axis="Y" this.omatrixops.yrotate() case this.axis="Z" this.omatrixops.zrotate() endcase return endproc procedure destroy close tables return endproc enddefine define class writepov as custom pointstable = "" edgestable = "" cyldiam = "0.04" drawaxes = .T. axlength = 2.5 axdiam = "0.02" shapecolor = "Blue" axcolor = "Green" hnd = 0 outputfile = "myfile.pov" procedure init() local temp this.startpov() if this.drawaxes this.makeaxes() endif return endproc procedure startpov() with this local filename filename=this.outputfile if file(filename) erase (filename) endif .hnd=fcreate(filename) if .hnd>0 =fopen(filename) endif =fputs(.hnd, "//POV-Ray script") =fputs(.hnd, '#version 3.1') =fputs(.hnd, 'global_settings { assumed_gamma 2.2 }') =fputs(.hnd, '#include "colors.inc"') =fputs(.hnd, '#include "shapes.inc"') =fputs(.hnd, '#include "glass.inc"') =fputs(.hnd, '#include "woods.inc"') =fputs(.hnd, '#include "metals.inc"') =fputs(.hnd, '#include "textures.inc"') =fputs(.hnd, '#default {texture{pigment{color White}'+; 'finish{phong 0.01 ambient 0.2 diffuse 0.6}}}') =fputs(.hnd, '#declare T1 = texture{Gold_Metal}') =fputs(.hnd, '#declare T2 = texture{T_Wood1} // Oak ') =fputs(.hnd, '#declare T3 = texture{T_Copper_3A}') =fputs(.hnd, "") =fputs(.hnd, "#declare Cam_factor = 8") =fputs(.hnd, "#declare Camera_X = 1 * Cam_factor") =fputs(.hnd, "#declare Camera_Y = 0.5 * Cam_factor") =fputs(.hnd, "#declare Camera_Z = -0.9 * Cam_factor") =fputs(.hnd, "<Camera_X, Camera_Y, Camera_Z>camera { location ") =fputs(.hnd, " up <0, 1.0, 0> right <-4/3, 0, 0>") =fputs(.hnd, " direction <0, 0, 3> look_at <0, 0, 0> ") =fputs(.hnd, " rotate <0,0,0>}") =fputs(.hnd, "") =fputs(.hnd, "<Camera_X - 2, Camera_Y + 5 , Camera_Z + 5>light_source { color White }") =fputs(.hnd, "<Camera_X - 2, Camera_Y + 5 , Camera_Z - 3>light_source { color White }") =fputs(.hnd, "") =fputs(.hnd, "// Background:") =fputs(.hnd, "background {color White}") endwith endproc procedure makeaxes local tempshape, tempdiam tempshape = this.shapecolor tempdiam = this.cyldiam this.shapecolor = this.axcolor this.cyldiam = this.axdiam this.writecylinder(this.axlength,0,0,-this.axlength,0,0) this.writecylinder(0,this.axlength,0,0,-this.axlength,0) this.writecylinder(0,0,this.axlength,0,0,-this.axlength) this.shapecolor = tempshape this.cyldiam = tempdiam return endproc procedure writepoint(a,b,c) with this =fputs(.hnd, "sphere{<"; +str(a,10,7)+","; +str(b,10,7)+","; +str(c,10,7)+">," + .cyldiam; +" pigment {color "+ .shapecolor + "} no_shadow}") endwith endproc procedure writecylinder(a,b,c,d,e,f) * write a line in the POV file defining a cylinder w/ spherical nibs with this =fputs(.hnd, "cylinder{<"; +str(a,10,7)+","; +str(b,10,7)+","; +str(c,10,7)+">,<"; +str(d,10,7)+","; +str(e,10,7)+","; +str(f,10,7)+">," + this.cyldiam; +" pigment {color "+this.shapecolor+"} no_shadow}") endwith endproc procedure destroy() =fclose(this.hnd) return endproc procedure writeoutput local x1,y1,z1,x2,y2,z2 select edges && select the Edges table go top scan while not eof() && scan to the end =seek(vert1,"points") && get first vertex x1=points.xcoord y1=points.ycoord z1=points.zcoord =seek(vert2,"points") && get second vertex x2=points.xcoord y2=points.ycoord z2=points.zcoord this.writepoint(x1,y1,z1) && nub this.writecylinder(x1,y1,z1,x2,y2,z2) && edge this.writepoint(x2,y2,z2) && nub endscan return endproc enddefine define class matrixops as custom pointstable = "" theta=0 axis="" cos_theta=0 sin_theta=0 procedure setdegrees(deg) this.theta = deg this.cos_theta = cos(this.theta) this.sin_theta = sin(this.theta) return endproc procedure xrotate local newx, newy, newz ? "Rotate around X by " + str(this.theta,5,2) + " degrees using " + this.pointstable * / 1 0 0 \ * X AXIS | 0 cos(a) -sin(a) | * \ 0 sin(a) cos(a) / scan while not eof() newx = xcoord newy = this.cos_theta*ycoord - this.sin_theta*zcoord newz = this.sin_theta*ycoord + this.cos_theta*zcoord replace xcoord with newx, ycoord with newy, zcoord with newz endscan return endproc procedure yrotate local newx, newy, newz ? "Rotate around Y by " + str(this.theta,5,2) + " degrees using " + this.pointstable * / cos(a) 0 -sin(a) \ * Y AXIS | 0 1 0 | * \ sin(a) 0 cos(a) / scan while not eof() newx = this.cos_theta*xcoord - this.sin_theta*zcoord newy = ycoord newz = this.sin_theta*xcoord + this.cos_theta*zcoord replace xcoord with newx, ycoord with newy, zcoord with newz endscan return endproc procedure zrotate local newx, newy, newz ? "Rotate around Z by " + str(this.theta,5,2) + " degrees using " + this.pointstable * / cos(a) -sin(a) 0 \ * Z AXIS | sin(a) cos(a) 0 | * \ 0 0 1 / scan while not eof() newx = this.cos_theta*xcoord - this.sin_theta*ycoord newy = this.sin_theta*xcoord + this.cos_theta*ycoord newz = zcoord replace xcoord with newx, ycoord with newy, zcoord with newz endscan return endproc enddefine