Points&Forces (core)
Software tools facilitating the task of surveying architecture
a_coord.cxx
Go to the documentation of this file.
1 /*
2 Copyright 2011-12 Pierre SMARS (smars@yuntech.edu.tw)
3 This program is free software: you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation, either version 2 of the License, or
6 (at your option) any later version.
7 
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12 
13 You should have received a copy of the GNU General Public License
14 along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16 #include "a_coord.h"
17 #include <fstream>
18 #include <sstream>
19 #include <string.h>
20 // .PORTABILITY : ansi C++
21 
22 //***************************************************************************
23 const double a_coord::pi = 3.141592653589793238;
24 //member functions
25 //---------------------------------------------------------------------------
26 const std::string a_coord::help()
27 {
28  std::ostringstream o;
29  o << "*********" << std::endl;
30  o << "a_coord:" << std::endl;
31  o << "*********" << std::endl;
32  o << "This is a local coordinate system class" << std::endl;
33  o << std::endl;
34  o << "Create a local coordinate system:" << std::endl;
35  o << " a_coord c" << std::endl;
36  o << "name _name: give a name to the coordinate system" << std::endl;
37  o << "name: get the name of the coordinate system" << std::endl;
38  o << "reset: reset to the world coordinate system" << std::endl;
39  o << "translate _x _y _z: translate the coordinate system (translation in user coordinate)" << std::endl;
40  o << "translateW _x _y _z: translate the coordinate system (translation in world coordinates)" << std::endl;
41  o << "scale _x _y _z: scale the coordinate system" << std::endl;
42  o << "scale _f: scale the coordinate system" << std::endl;
43  o << "rad: set angle unit to radian (default)" << std::endl;
44  o << "deg: set angle unit to degrees" << std::endl;
45  o << "mode: get the angle mode" << std::endl;
46  o << "mode _val: set the angle mode" << std::endl;
47  o << "rotateX _val: rotate around local x axis" << std::endl;
48  o << "rotateY _val: rotate around local y axis" << std::endl;
49  o << "rotateZ _val: rotate around local z axis" << std::endl;
50  o << "rotateXW _val: rotate around world x axis" << std::endl;
51  o << "rotateYW _val: rotate around world y axis" << std::endl;
52  o << "rotateZW _val: rotate around world z axis" << std::endl;
53  o << "orient _origin _x _y: place the coordinate system with origin in _origin, x axis along _x and y axis in the plane defined by _x and _y" << std::endl;
54  o << "w2l _a_point: convert world to local coordinates" << std::endl;
55  o << "l2w _a_point: convert local to world coordinates" << std::endl;
56  o << std::endl;
57  o << a_coord_base::help();
58  return o.str();
59 }
60 //-a_coord------------------------------------------------------------------
61 a_coord::a_coord() : a_coord_base(), radian_(true), name_("no name")
62 {
63  for (int i=0; i<4; i++) (*this)(i,i) = 1;
64 }
65 //-a_coord------------------------------------------------------------------
66 a_coord::a_coord(const std::string& aname) : a_coord_base(), radian_(true), name_("no name")
67 {
68  for (int i=0; i<4; i++) (*this)(i,i) = 1;
69 }
70 //-a_coord------------------------------------------------------------------
71 a_coord::a_coord(const a_coord& c) : a_coord_base(c), radian_(c.mode()), name_(c.name())
72 {
73 }
74 //-~a_coord-----------------------------------------------------------------
76 {
77 // a_mat_sq::~a_mat_sq();
78 }
79 //---------------------------------------------------------------------------
81 {
82  this->settoI();
83 }
84 //---------------------------------------------------------------------------
85 void a_coord::mat(a_mat_sq& r) const
86 {
87  if (r.dim()!=4)
88  throw a_mat::range_error();
89  for (int i=0; i<4; i++)
90  {
91  for (int j=0; j<4; j++)
92  r(i,j) = (*this)(i,j);
93  }
94 }
95 //---------------------------------------------------------------------------
96 void a_coord::mat(const a_mat_sq& r)
97 {
98  if (r.dim()!=4)
99  throw a_mat::range_error();
100  for (UI i=0; i<4; i++)
101  {
102  for (UI j=0; j<4; j++)
103  (*this)(i,j) = r(i,j);
104  }
105 }
106 //---------------------------------------------------------------------------
107 void a_coord::R(a_mat_sq& r) const
108 {
109  if (r.dim()!=3)
110  throw a_mat::range_error();
111  r = this->sub_matrix(3,3);
112 }
113 //---------------------------------------------------------------------------
114 void a_coord::R(const a_mat_sq& r)
115 {
116  if (r.dim()!=3)
117  throw a_mat::range_error();
118  for (int i=0; i<3; i++)
119  {
120  for (int j=0; j<3; j++)
121  (*this)(i,j) = r(i,j);
122  }
123 }
124 //---------------------------------------------------------------------------
125 void a_coord::T(a_mat_c& t) const
126 {
127  if (t.maxi()!=3)
128  throw a_mat::range_error();
129  for (int i=0; i<3; i++)
130  t(i) = (*this)(i,3);
131 }
132 //---------------------------------------------------------------------------
133 void a_coord::T(const a_mat_c& t)
134 {
135  if (t.maxi()!=3)
136  throw a_mat::range_error();
137  for (int i=0; i<3; i++)
138  (*this)(i,3) = t(i);
139 }
140 //-translate-----------------------------------------------------------------
141 void a_coord::translate(double dx, double dy, double dz)
142 {
143  (*this)(0,3) -= dx;
144  (*this)(1,3) -= dy;
145  (*this)(2,3) -= dz;
146 }
147 //-translate-----------------------------------------------------------------
148 void a_coord::translateW(double dx, double dy, double dz)
149 {
150  double t[] = {dx,dy,dz};
151  for (int i=0; i<3; i++)
152  {
153  for (int j=0; j<3; j++)
154  (*this)(i,3) -= t[j]*(*this)(i,j);
155  }
156 }
157 //-scale---------------------------------------------------------------------
158 void a_coord::scale(double sx, double sy, double sz)
159 {
160  for (int i=0; i<3; i++) (*this)(i,0) /= sx;
161  for (int i=0; i<3; i++) (*this)(i,1) /= sy;
162  for (int i=0; i<3; i++) (*this)(i,2) /= sz;
163 }
164 //-scale---------------------------------------------------------------------
165 void a_coord::scale(double s)
166 {
167  a_coord::scale(s,s,s);
168 }
169 //-rotateX-------------------------------------------------------------------
170 void a_coord::rotateX(double t)
171 {
172  if (!radian_) t /= 180/a_coord::pi;
173  a_mat_sq r(4);
174  r(1,1) = cos(t);
175  r(1,2) = sin(t);
176  r(2,1) = -sin(t);
177  r(2,2) = cos(t);
178  r(0,0) = 1;
179  r(3,3) = 1;
180  this->mat(r*(*this));
181 }
182 //-rotateY-------------------------------------------------------------------
183 void a_coord::rotateY(double t)
184 {
185  if (!radian_) t /= 180/a_coord::pi;
186  a_mat_sq r(4);
187  r(0,0) = cos(t);
188  r(0,2) = -sin(t);
189  r(2,0) = sin(t);
190  r(2,2) = cos(t);
191  r(1,1) = 1;
192  r(3,3) = 1;
193  this->mat(r*(*this));
194 }
195 //-rotateZ-------------------------------------------------------------------
196 void a_coord::rotateZ(double t)
197 {
198  if (!radian_) t /= 180/a_coord::pi;
199  a_mat_sq r(4);
200  r(0,0) = cos(t);
201  r(0,1) = sin(t);
202  r(1,0) = -sin(t);
203  r(1,1) = cos(t);
204  r(2,2) = 1;
205  r(3,3) = 1;
206  this->mat(r*(*this));
207 }
208 //-rotateX-------------------------------------------------------------------
209 void a_coord::rotateXW(double t)
210 {
211  if (!radian_) t /= 180/a_coord::pi;
212  a_mat_sq r(4);
213  r(1,1) = cos(t);
214  r(1,2) = sin(t);
215  r(2,1) = -sin(t);
216  r(2,2) = cos(t);
217  r(0,0) = 1;
218  r(3,3) = 1;
219  this->mat((*this)*r);
220 }
221 //-rotateY-------------------------------------------------------------------
222 void a_coord::rotateYW(double t)
223 {
224  if (!radian_) t /= 180/a_coord::pi;
225  a_mat_sq r(4);
226  r(0,0) = cos(t);
227  r(0,2) = -sin(t);
228  r(2,0) = sin(t);
229  r(2,2) = cos(t);
230  r(1,1) = 1;
231  r(3,3) = 1;
232  this->mat((*this)*r);
233 }
234 //-rotateZ-------------------------------------------------------------------
235 void a_coord::rotateZW(double t)
236 {
237  if (!radian_) t /= 180/a_coord::pi;
238  a_mat_sq r(4);
239  r(0,0) = cos(t);
240  r(0,1) = sin(t);
241  r(1,0) = -sin(t);
242  r(1,1) = cos(t);
243  r(2,2) = 1;
244  r(3,3) = 1;
245  this->mat((*this)*r);
246 }
247 //-orient--------------------------------------------------------------------
248 void a_coord::orient(const a_mat_c& o0, const a_mat_c& x0, const a_mat_c& py0)
249 {
250  a_mat_c o(3);
251  o = o0;
252  a_mat_c x(3);
253  x = x0;
254  a_mat_c py(3);
255  py = py0;
256  if ((o.maxi()==3)&&(o.maxi()==3)&&(o.maxi()==3))
257  {
258  translate(o(0),o(1),o(2));
259  x -= o;
260  py -= o;
261  x.normalise();
262  a_mat_c z(3);
263  z = cross(x,py);
264  z.normalise();
265  a_mat_c y(3);
266  y = cross(z,x);
267  for (UI i = 0; i<3; i++) (*this)(0,i) = x(i);
268  for (UI i = 0; i<3; i++) (*this)(1,i) = y(i);
269  for (UI i = 0; i<3; i++) (*this)(2,i) = z(i);
270  }
271  else throw a_mat::compatibility_error();
272 }
273 //-orient--------------------------------------------------------------------
274 void a_coord::orient(const a_point& o, const a_point& x0, const a_point& py0)
275 {
276  a_point x = x0;
277  a_point py = py0;
278  this->translate(o);
279  x -= o;
280  x.normalise();
281  py -= o;
282  a_point z = cross(x,py);
283  z.normalise();
284  a_point y = cross(z,x);
285  for (UI i = 0; i<3; i++) (*this)(0,i) = x[i];
286  for (UI i = 0; i<3; i++) (*this)(1,i) = y[i];
287  for (UI i = 0; i<3; i++) (*this)(2,i) = z[i];
288 }
289 //***************************************************************************
290 //---------------------------------------------------------------------------
291 void a_coord::read(std::istream &in)
292 {
293  //skip blank lines
294  std::string s = "";
295  while (strcmp(s.c_str(),"")==0)
296  {
297  if (!in) return;
298  std::getline(in,s);
299  }
300  //skip spaces
301  std::string::size_type ii=s.find_first_not_of(" ");
302  std::string::size_type ie=s.find_last_not_of(" ");
303  name_ = s.substr(ii,ie);
304 
305  this->a_mat::read(in);
306 }
307 //---------------------------------------------------------------------------
308 void a_coord::write(std::ostream &o) const
309 {
310  o << this->name() << std::endl;
311  this->a_mat::write(o);
312 }
313 //---------------------------------------------------------------------------
315 {
316  a_coord out;
317  std::string name = this->name()+"-1";
318  out.name(name);
319  //translation = R^-1*T
320  for (UI i=0;i<3;i++)
321  {
322  for (UI j=0;j<3;j++)
323  out(i,3) -= (*this)(j,i)*(*this)(j,3);
324  }
325  //transpose the rotation matrix
326  for (UI i=0;i<3;i++)
327  {
328  for (UI j=0;j<3;j++)
329  out(i,j)=(*this)(j,i);
330  }
331  return out;
332 }
333 //---------------------------------------------------------------------------
334 a_point a_coord::w2l(const a_point& pt) const
335 {
336  a_mat_c pt0(4);
337  pt0(0) = pt.x();
338  pt0(1) = pt.y();
339  pt0(2) = pt.z();
340  pt0(3) = 1.;
341  a_mat_c ptn = (*this)*pt0;
342  ptn /= ptn(3);
343  a_point out(ptn(0),ptn(1),ptn(2));
344  return out;
345 }
346 //---------------------------------------------------------------------------
347 a_point a_coord::l2w(const a_point& pt) const
348 {
349  a_mat_c pt0(4);
350  pt0(0) = pt.x();
351  pt0(1) = pt.y();
352  pt0(2) = pt.z();
353  pt0(3) = 1.;
354  a_coord t = this->invert();
355  a_mat_c ptn = t*pt0;
356  ptn /= ptn(3);
357  a_point out(ptn(0),ptn(1),ptn(2));
358  return out;
359 }
360 //***************************************************************************
361 //-operator*-----------------------------------------------------------------
362 a_mat_c operator*(const a_coord & c, const a_mat_c & pt)
363 {
364  if (pt.maxi() == 3) //non-homogeneous coordinates
365  {
366  a_mat_c r(3);
367  a_mat_c r0(4);
368  for (UI i = 0; i<3; i++) r0(i) = pt(i);
369  r0(3) = 1;
370  double v;
371  for (UI i = 0; i < 4; i++)
372  {
373  v = 0;
374  for (UI j = 0; j < 4; j++)
375  v += c(i,j)*r0(j);
376  if (i != 3)
377  r(i) = v;
378  else
379  for (UI j = 0; j < 3; j++) r(j) /= v;
380  }
381  return r;
382  }
383  else if (pt.maxi() == 4) //homogeneous coordinates
384  {
385  a_mat_c r(4);
386  double v;
387  for (UI i = 0; i < 4; i++)
388  {
389  v = 0;
390  for (UI j = 0; j < 4; j++)
391  v += c(i,j)*pt(j);
392  if (i != 3)
393  r(i) = v;
394  else
395  {
396  for (UI j = 0; j < 3; j++) r(j) /= v;
397  r(3) = 1;
398  }
399  }
400  return r;
401  }
402  else throw a_mat::compatibility_error();
403 }
a_mat_c operator*(const a_coord &c, const a_mat_c &pt)
Definition: a_coord.cxx:362
unsigned int UI
Definition: a_mat.h:23
a_point cross(const a_point &a, const a_point &b)
Definition: a_point.cxx:284
static const std::string help()
a coordinate system in the Points&Forces file format
Definition: a_coord.h:33
void reset()
Definition: a_coord.cxx:80
static const double pi
Definition: a_coord.h:84
a_point l2w(const a_point &pt) const
convert coordinates from world to local
Definition: a_coord.cxx:347
void rotateYW(double)
Definition: a_coord.cxx:222
void mat(a_mat_sq &r) const
Definition: a_coord.cxx:85
void rotateXW(double)
Definition: a_coord.cxx:209
void rotateY(double)
Definition: a_coord.cxx:183
void T(a_mat_c &t) const
Definition: a_coord.cxx:125
void rotateX(double)
Definition: a_coord.cxx:170
~a_coord()
Definition: a_coord.cxx:75
void rotateZW(double)
Definition: a_coord.cxx:235
virtual void read(std::istream &i)
convert coordinates from local to world
Definition: a_coord.cxx:291
a_coord()
Definition: a_coord.cxx:61
std::string name_
Definition: a_coord.h:87
void translate(double, double, double)
reset to the world coordinate system
Definition: a_coord.cxx:141
std::string name() const
Definition: a_coord.h:42
void R(a_mat_sq &r) const
Definition: a_coord.cxx:107
a_point w2l(const a_point &pt) const
Definition: a_coord.cxx:334
void translateW(double, double, double)
Definition: a_coord.cxx:148
static const std::string help()
Definition: a_coord.cxx:26
void rotateZ(double)
Definition: a_coord.cxx:196
void scale(double, double, double)
Definition: a_coord.cxx:158
a_coord invert() const
Definition: a_coord.cxx:314
void orient(const a_mat_c &o, const a_mat_c &x, const a_mat_c &y)
Definition: a_coord.cxx:248
bool radian_
Definition: a_coord.h:88
virtual void write(std::ostream &o) const
Definition: a_coord.cxx:308
a column matrix unit
Definition: a_mat_c.h:29
void normalise()
Definition: a_mat_c.cxx:45
a square matrix unit
Definition: a_mat_sq.h:29
UI dim() const
Definition: a_mat_sq.h:36
void settoI()
Definition: a_mat_sq.cxx:41
std::valarray< double > & x() const
Definition: a_mat.h:53
a_mat sub_matrix(const UI i, const UI j) const
Definition: a_mat.cxx:162
virtual void read(std::istream &i)
Definition: a_mat.cxx:211
UI maxi() const
Definition: a_mat.h:49
virtual void write(std::ostream &o) const
Definition: a_mat.cxx:224
a_point & normalise()
Definition: a_point.cxx:190
double z() const
Definition: a_point.h:56
double y() const
Definition: a_point.h:55
double x() const
Definition: a_point.h:54
std::cin getline(buf, 256)