#include <TVout.h>
#include "stdlib.h"
#include "math.h"
#include "lib3d.h"
Line3D::Line3D()
{
Line3D(0,0,0,0,0,0);
}
Line3D::Line3D(short x1, short y1, short z1, short x2, short y2, short z2)
{
p1.x = x1;
p1.y = y1;
p1.z = z1;
p2.x = x2;
p2.y = y2;
p2.z = z2;
}
Scene3D::Scene3D()
{
pTV = (TVout*)0;
iNumLines = 0;
mv = 0; // middle vertically
mh = 0; // the horizontal middle
h = 0;
v = 0;
UpdateConsts();
}
void Scene3D::CreateScene(short resX, short resY, TVout* pTVout)
{
pTV = pTVout;
iNumLines = 0;
mv = resX / 2; // middle vertically
mh = resY / 2; // the horizontal middle
h = 0;
v = 0;
UpdateConsts();
}
void Scene3D::SetVAngle(float vNew)
{
v = vNew;
UpdateConsts();
}
void Scene3D::SetHAngle(float hNew)
{
h = hNew;
UpdateConsts();
}
void Scene3D::UpdateConsts()
{
cosh = cos(h);
sinh = sin(h);
cosv = cos(v);
sinv = sin(v);
}
int Scene3D::xyztox(short x, short y, short z)
{
return mh + round(x*cosh+z*sinh);
}
int Scene3D::xyztoy(short x, short y, short z)
{
return mv + round(y*cosv+(-x*sinh+z*cosh)*sinv);
}
void Scene3D::AddLine(Line3D line)
{
if (iNumLines < MAX_LINES)
{
lines[iNumLines] = line;
iNumLines++;
}
}
void Scene3D::AddCube(short cX, short cY, short cZ, short edgeLen)
{
Line3D l;
short iOffs = edgeLen - 1;
// top square first
l.p1.z = cZ + iOffs; l.p2.z = cZ + iOffs;
l.p1.x = cX - iOffs; l.p1.y = cY + iOffs;
l.p2.x = cX - iOffs; l.p2.y = cY - iOffs;
AddLine(l);
l.p1.x = cX + iOffs; l.p1.y = cY - iOffs;
AddLine(l);
l.p1.x = cX + iOffs; l.p1.y = cY + iOffs;
l.p2.x = cX + iOffs; l.p2.y = cY - iOffs;
AddLine(l);
l.p2.x = cX - iOffs; l.p2.y = cY + iOffs;
AddLine(l);
// bottom square second
l.p1.z = cZ - iOffs; l.p2.z = cZ - iOffs;
l.p1.x = cX - iOffs; l.p1.y = cY + iOffs;
l.p2.x = cX - iOffs; l.p2.y = cY - iOffs;
AddLine(l);
l.p1.x = cX + iOffs; l.p1.y = cY - iOffs;
AddLine(l);
l.p1.x = cX + iOffs; l.p1.y = cY + iOffs;
l.p2.x = cX + iOffs; l.p2.y = cY - iOffs;
AddLine(l);
l.p2.x = cX - iOffs; l.p2.y = cY + iOffs;
AddLine(l);
// 4 corner lines
l.p1.z = cZ - iOffs; l.p2.z = cZ + iOffs;
l.p1.x = cX + iOffs; l.p1.y = cY + iOffs;
l.p2.x = cX + iOffs; l.p2.y = cY + iOffs;
AddLine(l);
l.p1.x = cX - iOffs;
l.p2.x = cX - iOffs;
AddLine(l);
l.p1.y = cY - iOffs;
l.p2.y = cY - iOffs;
AddLine(l);
l.p1.x = cX + iOffs;
l.p2.x = cX + iOffs;
AddLine(l);
}
void Scene3D::UpdateDisplay()
{
int x;
if (pTV)
{
for(x = 0; x< iNumLines; x++)
{
pTV->draw_line(xyztox(lines[x].p1.x,lines[x].p1.y,lines[x].p1.z),
xyztoy(lines[x].p1.x,lines[x].p1.y,lines[x].p1.z),
xyztox(lines[x].p2.x,lines[x].p2.y,lines[x].p2.z),
xyztoy(lines[x].p2.x,lines[x].p2.y,lines[x].p2.z),
1);
}
}
}
void Scene3D::AddSphere(float r, Point3D c)
{
// r = the radius of the sphere
// c = the centre point of the sphere
Line3D ln1;
int x;
int y;
float flat;
float flong;
float cr; // the radius of a circle inside the
float pi = 3.1416259;
for(y=-3; y<= 3; y++) // draw lines in circles parallel to the equator
{
flat = y*pi/6;
ln1.p1.y = r*sin(flat)+c.y;
ln1.p2.y = ln1.p1.y;
// calculated the y coordinate of a circle in the sphere
for(x=0; x <= 12; x++)
{
flong = x*pi/6;
cr = r*cos(flat);
ln1.p1 = ln1.p2;
ln1.p2.x = cr*cos(flong) + c.x;
ln1.p2.z = cr*sin(flong) + c.z;
if (x != 0)
{
AddLine(ln1);
}
}
for(x=0; x <= 12; x++) // reverse the wire pattern so it looks like a grid
{
// draw the pattern parallel to the meridians
flong = x*pi/6;
for(y=-3; y<= 3; y++)
{
flat = y*pi/6;
ln1.p1 = ln1.p2;
cr = r*cos(flat);
ln1.p2.x = cr*cos(flong)+c.x;
ln1.p2.z = cr*sin(flong)+c.z;
ln1.p2.y = r*sin(flat)+c.y;
// calculated the y coordinate of a circle in the sphere
if (y != -3)
{
AddLine(ln1);
}
}
}
}
}
One thought on “lib3d.cpp”