* 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