1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156
|
// Copyright (c) 1997 Philip A. Hardin (pahardin@cs.utexas.edu)
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License v2 or later.
#include <math.h>
#include "pt3d.h"
/*-------------------------------------------------------------------------*/
pt3d pt3d::operator>>(const ang3d& ang) const
{ double sinAng,
cosAng;
coord tempx;
pt3d newPt;
sinAng= sinTbl[(ang.yz)&(2*MA_PI-1)];
cosAng= cosTbl[(ang.yz)&(2*MA_PI-1)];
newPt.y= (coord)(cosAng*y - sinAng*z);
newPt.z= (coord)(cosAng*z + sinAng*y);
sinAng= sinTbl[(ang.xz)&(2*MA_PI-1)];
cosAng= cosTbl[(ang.xz)&(2*MA_PI-1)];
tempx= (coord)(cosAng*x - sinAng*newPt.z);
newPt.z= (coord)(cosAng*newPt.z + sinAng*x);
sinAng= sinTbl[(ang.xy)&(2*MA_PI-1)];
cosAng= cosTbl[(ang.xy)&(2*MA_PI-1)];
newPt.x= (coord)(cosAng*tempx - sinAng*newPt.y);
newPt.y= (coord)(cosAng*newPt.y + sinAng*tempx);
return newPt;
}
/*-------------------------------------------------------------------------*/
pt3d pt3d::operator<<(const ang3d& ang) const
{ double sinAng,
cosAng;
coord tempz;
pt3d newPt;
sinAng= sinTbl[(-(ang.xy))&(2*MA_PI-1)];
cosAng= cosTbl[(-(ang.xy))&(2*MA_PI-1)];
newPt.x= (coord)(cosAng*x - sinAng*y);
newPt.y= (coord)(cosAng*y + sinAng*x);
sinAng= sinTbl[(-(ang.xz))&(2*MA_PI-1)];
cosAng= cosTbl[(-(ang.xz))&(2*MA_PI-1)];
tempz = (coord)(cosAng*z + sinAng*newPt.x);
newPt.x= (coord)(cosAng*newPt.x - sinAng*z);
sinAng= sinTbl[(-ang.yz)&(2*MA_PI-1)];
cosAng= cosTbl[(-ang.yz)&(2*MA_PI-1)];
newPt.z= (coord)(cosAng*tempz + sinAng*newPt.y);
newPt.y= (coord)(cosAng*newPt.y - sinAng*tempz);
return newPt;
}
/*-------------------------------------------------------------------------*/
pt3d pt3d::operator>>(const double m[3][3]) const {
return pt3d((coord)(m[0][0]*x +m[0][1]*y +m[0][2]*z),
(coord)(m[1][0]*x +m[1][1]*y +m[1][2]*z),
(coord)(m[2][0]*x +m[2][1]*y +m[2][2]*z) );
}
/*-------------------------------------------------------------------------*/
/* To rotate in reverse, we take the inverse of the rotation mtrx
(i.e. take its transpose and divide by its determinant) and multiply
the mtrx against the point. Actually we don't do exactly that; we do
compute the determinant and divide each mtrx element by the determinant,
but we simulate taking the transpose by changing which elements are
multiplied against the point vector.
*/
pt3d pt3d::operator<<(const double m[3][3]) const {
double det= m[0][0]*(m[1][1]*m[2][2] - m[1][2]*m[2][1])
-m[0][1]*(m[1][0]*m[2][2] - m[1][2]*m[2][0])
+m[0][2]*(m[1][0]*m[2][1] - m[1][1]*m[2][0]);
if (det==0.0) {cerr << "determinant is 0.\n"; return *this;};
double r= 1.0/det; // reciprocal
pt3d pt;
pt.x= (coord)((m[0][0]*x +m[1][0]*y +m[2][0]*z)*r);
pt.y= (coord)((m[0][1]*x +m[1][1]*y +m[2][1]*z)*r);
pt.z= (coord)((m[0][2]*x +m[1][2]*y +m[2][2]*z)*r);
return pt;
}
/*-------------------------------------------------------------------------*/
pt3d pt3d::operator>>(const xformMtrx m) const {
return pt3d(m[0][0]*x +m[1][0]*y +m[2][0]*z +m[3][0],
m[0][1]*x +m[1][1]*y +m[2][1]*z +m[3][1],
m[0][2]*x +m[1][2]*y +m[2][2]*z +m[3][2]);
}
/*-------------------------------------------------------------------------*/
/* To untransform, we subtract the translational part of the transform
from the point and then multiply by the inverse of the 3x3 part of the
transform.
*/
pt3d pt3d::operator<<(const xformMtrx m) const {
double det= m[0][0]*(m[1][1]*m[2][2] - m[1][2]*m[2][1])
-m[0][1]*(m[1][0]*m[2][2] - m[1][2]*m[2][0])
+m[0][2]*(m[1][0]*m[2][1] - m[1][1]*m[2][0]);
if (det==0.0) {cerr << "determinant is 0.\n"; return *this;};
pt3d p(x-m[3][0],y-m[3][1],z-m[3][2]);
return pt3d(m[0][0]*p.x +m[0][1]*p.y +m[0][2]*p.z,
m[1][0]*p.x +m[1][1]*p.y +m[1][2]*p.z,
m[2][0]*p.x +m[2][1]*p.y +m[2][2]*p.z) / det;
}
/*-------------------------------------------------------------------------*/
pt3d pt3d::operator>>(double ang) const
{ double sinAng= sin(ang),
cosAng= cos(ang);
pt3d newPt;
newPt.x= (coord)(cosAng*x - sinAng*y);
newPt.y= (coord)(cosAng*y + sinAng*x);
newPt.z= z;
return newPt;
}
/*-------------------------------------------------------------------------*/
void pt3d::Interpolate(const pt3d& firstPt, const pt3d& lastPt, int i,
int range)
{ if (range==0) return;
x= firstPt.x + i*(lastPt.x -firstPt.x)/range;
y= firstPt.y + i*(lastPt.y -firstPt.y)/range;
z= firstPt.z + i*(lastPt.z -firstPt.z)/range;
}
/*-------------------------------------------------------------------------*/
pt3d pt3d::Normalized(coord len) const
// Treating this pt as a vector, normalize so that vector length= len
{ return (*this) * (len/Dist());
}
/*-------------------------------------------------------------------------*/
void pt3d::Normalize(coord len)
// Treating this pt as a vector, normalize so that vector length= len
{ *this *= len/Dist();
}
/*-------------------------------------------------------------------------*/
void pt3d::FastNormalize(coord len)
// Treating this pt as a vector, normalize so that vector length= len
{ *this *= len/FastDist();
}
|