File: pt3d.C

package info (click to toggle)
battleball 2.0-13
  • links: PTS
  • area: main
  • in suites: woody
  • size: 1,016 kB
  • ctags: 3,097
  • sloc: cpp: 15,310; makefile: 48; csh: 34
file content (156 lines) | stat: -rw-r--r-- 5,285 bytes parent folder | download | duplicates (5)
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();
}