//Vector Maths//////////////////////////////////////////////////////////////////////////////////
struct SVector
{
double X, Y, Z;
};
SVector unit(SVector v)
{
SVector RetVector = v;
double mag = pow( pow( RetVector.X, 2) + pow( RetVector.Y, 2) + pow( RetVector.Z, 2), 0.5);
RetVector.X /= mag;
RetVector.Y /= mag;
RetVector.Z /= mag;
return RetVector;
}
SVector cross(SVector v1, SVector v2)
{
SVector RetVector;
RetVector.X = v1.Y * v2.Z - v1.Z * v2.Y;
RetVector.Y = v1.Z * v2.X - v1.X * v2.Z;
RetVector.Z = v1.X * v2.Y - v1.Y * v2.X;
return RetVector;
}
SVector rotVector(SVector rotVector, SVector abtVector, double deg)
{
//When vector Q is rotated, @ Vector P, thru angle t;
//the resultant vector R is given by:
//
// R = [P /|P|]sin(t) x [Q] + [Q]cos(t)
////////////////////////////////////////////////////////
SVector RetVector;
//add 2nd part
RetVector.X = rotVector.X * cos(deg * DEG_TO_RAD);
RetVector.Y = rotVector.Y * cos(deg * DEG_TO_RAD);
RetVector.Z = rotVector.Z * cos(deg * DEG_TO_RAD);
//calculate 1st part accumulating in abtVector
double factor = sin(deg * DEG_TO_RAD) /
pow( pow( abtVector.X, 2) + pow( abtVector.Y, 2) + pow( abtVector.Z, 2), 0.5);
abtVector.X *= factor;
abtVector.Y *= factor;
abtVector.Z *= factor;
abtVector = cross(abtVector, rotVector);
//add 1st part
RetVector.X += abtVector.X;
RetVector.Y += abtVector.Y;
RetVector.Z += abtVector.Z;
return RetVector;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////
//Camera/////////////////////////////////////////////////////
struct SCamera
{
//opengl parameters
double X, Y, Z;
double AtX, AtY, AtZ;
double UpX, UpY, UpZ;
// double FrontPlane, BackPlane;
// double Vfov;
// double Aspect;
//other parameters
// double ViewPlane;
// double WinW ~ Aspect, WinH ~ Vfov;
//extra param
// int ViewPlaneFlag; // 1 = +ve, 0 = 0, -1 = -ve;
// bool ZeroVfovFlag;
void rotate(char axis, double deg);
void translate(char axis, double dist);
};
void SCamera :: translate(char axis, double dist)
{
SVector negN, Up, unitTransAxis;
negN.X = AtX - X; negN.Y = AtY - Y; negN.Z = AtZ - Z;
Up.X = UpX; Up.Y = UpY; Up.Z = UpZ;
switch (axis)
{
case ‘X’:
unitTransAxis = cross(negN, Up); //U
break;
case 'Y':
unitTransAxis = cross(cross(negN, Up), negN); //V
break;
case 'Z':
unitTransAxis = negN;
}
//make unit actual unit vector
double mag = pow( pow( unitTransAxis.X, 2) + pow( unitTransAxis.Y, 2) +
pow( unitTransAxis.Z, 2), 0.5);
unitTransAxis.X /= mag;
unitTransAxis.Y /= mag;
unitTransAxis.Z /= mag;
//scale with dist
unitTransAxis.X *= dist;
unitTransAxis.Y *= dist;
unitTransAxis.Z *= dist;
//add to two cam points
X += unitTransAxis.X;
Y += unitTransAxis.Y;
Z += unitTransAxis.Z;
AtX += unitTransAxis.X;
AtY += unitTransAxis.Y;
AtZ += unitTransAxis.Z;
}
void SCamera :: rotate(char axis, double deg)
{
SVector negN, Up, RotAxis;
negN.X = AtX - X; negN.Y = AtY - Y; negN.Z = AtZ - Z;
Up.X = UpX; Up.Y = UpY; Up.Z = UpZ;
switch (axis)
{
case ‘X’: RotAxis = cross(negN, Up); //U
break;
case 'Y': RotAxis = cross(cross(negN, Up), negN); //V
break;
case 'Z': RotAxis = negN;
}
if (axis != ‘Z’)
{
negN = rotVector(negN, RotAxis, deg);
AtX = negN.X + X;
AtY = negN.Y + Y;
AtZ = negN.Z + Z;
}
//actually needed only when nefN becomes equal to Up
Up = rotVector(Up, RotAxis, deg);
UpX = Up.X;
UpY = Up.Y;
UpZ = Up.Z;
}
///////////////////////////////////////////////////////////////////////