Points&Forces (core)
Software tools facilitating the task of surveying architecture
a_point.cxx
Go to the documentation of this file.
1 /*
2  Copyright 2010-17 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 <math.h>
17 #include <sstream>
18 
19 #include "a_point.h"
20 
21 //---------------------------------------------------------------------------
22 const std::string a_point::help()
23 {
24  std::ostringstream o;
25  o << "********" << std::endl;
26  o << "a_point:" << std::endl;
27  o << "********" << std::endl;
28  o << "This is a 3D 'point' or 'vector' class" << std::endl;
29  o << std::endl;
30  o << "Create a point:" << std::endl;
31  o << " a_point a" << std::endl;
32  o << " a_point b 1. 2.5 0." << std::endl;
33  o << std::endl;
34  o << "Commands:" << std::endl;
35  o << "+, -: add or subtract points." << std::endl;
36  o << "*: scalar product (or multiply by a scalar)." << std::endl;
37  o << "cross: cross product." << std::endl;
38  o << "/: divide by a scalar." << std::endl;
39  o << "x, y, z, x _x, y _y, z _z: get or set coordinates." << std::endl;
40  o << "set _x _y _z: set coordinates." << std::endl;
41  o << "set_cylindrical _r _phi _h: set coordinates (using cylindrical coordinate input)." << std::endl;
42  o << "set_spherical _r _theta _phi: set coordinates (using spherical coordinate input)." << std::endl;
43  o << "clear: set to (0,0,0)." << std::endl;
44  o << "translate _x _y _z: translate." << std::endl;
45  o << "rotate _xaxis _yaxis _zaxis: rotate." << std::endl;
46  o << "rotate _axis _angle: rotate around an axis of a given angle _angle." << std::endl;
47  o << "sumsq: sum of the square of the coordinates." << std::endl;
48  o << "norm: returns norm." << std::endl;
49  o << "normalise: normalise point." << std::endl;
50  o << "norm1: taxi cab norm." << std::endl;
51  o << "norm2: euclidian norm." << std::endl;
52  o << "normI: maximum norm." << std::endl;
53  o << "dist _pt: returns distance to _pt." << std::endl;
54  o << "max: set maximum abs value of component to 1." << std::endl;
55  o << "_pt1 angle _pt2: returns angle between 2 points." << std::endl;
56  o << "average _pt1 _pt2 _f: returns intermediate point; average coordinates; proportion is given by _f." << std::endl;
57  o << "average_rot _pt1 _pt2 _pos: returns intermediate point; average norm and average orientation; proportion is given by _f." << std::endl;
58  o << std::endl;
59  o << "Examples:" << std::endl;
60  o << " puts \"a: [a print]\"" << std::endl;
61  o << " puts \"a-b: [ [a - b ] print]\"" << std::endl;
62  o << " puts \"a*b: [ a * b]\"" << std::endl;
63  o << " puts \"||a||: [a norm]\"" << std::endl;
64  o << " a normalise" << std::endl;
65  o << " puts \"distance ab: [a dist b]\"" << std::endl;
66  o << "..." << std::endl;
67  o << a_geom_base::help();
68  return o.str();
69 }
70 //---------------------------------------------------------------------------
72 {
73  x_ = -x_;
74  y_ = -y_;
75  z_ = -z_;
76  return *this;
77 }
78 //---------------------------------------------------------------------------
80 {
81  a_point p2 = *this;
82  return p2 += p;
83 }
84 //---------------------------------------------------------------------------
86 {
87  a_point p2 = *this;
88  return p2 -= p;
89 }
90 //---------------------------------------------------------------------------
91 double a_point::operator*(const a_point& p)
92 {
93  return x_*p.x()+y_*p.y()+z_*p.z();
94 }
95 //---------------------------------------------------------------------------
97 {
98  a_point r;
99  r.x(y_*p.z()-z_*p.y());
100  r.y(z_*p.x()-x_*p.z());
101  r.z(x_*p.y()-y_*p.x());
102  return r;
103 }
104 //---------------------------------------------------------------------------
105 /*
106  a_point a_point::operator*(double v)
107  {
108  a_point p2 = *this;
109  return p2*v;
110  }
111  */
112 //---------------------------------------------------------------------------
114 {
115  x_ += p.x();
116  y_ += p.y();
117  z_ += p.z();
118  return *this;
119 }
120 //---------------------------------------------------------------------------
122 {
123  x_ -= p.x();
124  y_ -= p.y();
125  z_ -= p.z();
126  return *this;
127 }
128 //---------------------------------------------------------------------------
129 double a_point::operator*=(const a_point& p)
130 {
131  return x_*p.x()+y_*p.y()+z_*p.z();
132 }
133 //---------------------------------------------------------------------------
134 bool a_point::operator==(const a_point& p) const
135 {
136  return ((x_ == p.x())&&(y_ == p.y())&&(z_ == p.z()));
137 }
138 //---------------------------------------------------------------------------
140 {
141  x_ = p.x();
142  y_ = p.y();
143  z_ = p.z();
144  return *this;
145 }
146 //-operator*=----------------------------------------------------------------
148 {
149  x_ *= v;
150  y_ *= v;
151  z_ *= v;
152  return *this;
153 }
154 //-operator/=----------------------------------------------------------------
156 {
157  x_ /= v;
158  y_ /= v;
159  z_ /= v;
160  return *this;
161 }
162 //-sumsq---------------------------------------------------------------------
163 double a_point::sumsq() const
164 {
165  return x_*x_+y_*y_+z_*z_;
166 }
167 //-norm----------------------------------------------------------------------
168 double a_point::norm() const
169 {
170  return sqrt(sumsq());
171 }
172 double a_point::norm1() const
173 {
174  return fabs(x_)+fabs(y_)+fabs(z_);
175 }
176 double a_point::norm2() const
177 {
178  return sqrt(sumsq());
179 }
180 double a_point::normI() const
181 {
182  double max(fabs(x_));
183  if (fabs(y_) > max)
184  max = fabs(y_);
185  if (fabs(z_) > max)
186  max = fabs(z_);
187  return max;
188 }
189 //-normalise-----------------------------------------------------------------
191 {
192  double n = norm();
193  if (n != 0) operator/=(n);
194  return *this;
195 }
196 //---------------------------------------------------------------------------
198 {
199  a_mat_sq a(3);
200  for (short i=0; i<3; i++)
201  {
202  double xi = (*this)[i];
203  for (short j=0; j<=i; j++)
204  {
205  double xj = (*this)[j];
206  double v = xi*xj;
207  a(i,j) = v;
208  a(j,i) = v;
209  }
210  }
211  return a;
212 }
213 //---------------------------------------------------------------------------
215 {
216  double max = fabs(x_);
217  if (fabs(y_)>max)
218  max = fabs(y_);
219  if (fabs(z_)>max)
220  max = fabs(z_);
221  if (max != 0) operator/=(max);
222  return *this;
223 }
224 //-rotate--------------------------------------------------------------------
225 a_point& a_point::rotate(const a_point& x_axis, const a_point& y_axis, const a_point& z_axis)
226 {
227  double xn = (*this)*x_axis;
228  double yn = (*this)*y_axis;
229  double zn = (*this)*z_axis;
230  x_ = xn; y_ = yn; z_ = zn;
231  return *this;
232 }
233 //-rotate--------------------------------------------------------------------
234 a_point& a_point::rotate(const a_point& axis, const double angle)
235 {
236  const a_point r = *this;
237  a_point v = (r*axis)*axis;
238  a_point x = r-v;
239  a_point y = axis.cross(r);
240  a_point rn = v+cos(angle)*x+sin(angle)*y;
241  x_ = rn.x();
242  y_ = rn.y();
243  z_ = rn.z();
244  return *this;
245 }
246 //***************************************************************************
247 //-operator+-----------------------------------------------------------------
248 a_point operator+(const a_point& a, const a_point& b)
249 {
250  a_point r = a;
251  return r += b;
252 }
253 //-operator------------------------------------------------------------------
254 a_point operator-(const a_point& a, const a_point& b)
255 {
256  a_point r = a;
257  return r -= b;
258 }
259 //-operator*-----------------------------------------------------------------
260 double operator*(const a_point& a, const a_point& b)
261 {
262  a_point r = a;
263  return r *= b;
264 }
265 //-operator*-----------------------------------------------------------------
266 a_point operator*(const double v, const a_point& a)
267 {
268  a_point r = a;
269  return r *= v;
270 }
271 //-operator*-----------------------------------------------------------------
272 a_point operator*(const a_point& a, double v)
273 {
274  a_point r = a;
275  return r *= v;
276 }
277 //-operator/-----------------------------------------------------------------
278 a_point operator/(const a_point& a, double v)
279 {
280  a_point r = a;
281  return r /= v;
282 }
283 //-cross---------------------------------------------------------------------
284 a_point cross(const a_point& a, const a_point& b)
285 {
286  a_point r;
287  r.x(a.y()*b.z()-a.z()*b.y());
288  r.y(a.z()*b.x()-a.x()*b.z());
289  r.z(a.x()*b.y()-a.y()*b.x());
290  return r;
291 }
292 //---------------------------------------------------------------------------
293 a_point circle_centre(const a_point& p1, const a_point& p2, const a_point& p3)
294 {
295  a_point dp1 = p2-p1;//segments between points
296  a_point dp2 = p3-p2;
297  a_point n = cross(dp1,dp2).normalise();//normal to the plane
298  a_point n1 = cross(dp1,n).normalise();//normal to the segments
299  a_point n2 = cross(dp2,n).normalise();
300  a_point pm1 = (p1+p2)/2.;//mid points of the segments
301  a_point pm2 = (p2+p3)/2.;
302  a_point dpp = pm2-pm1;//side of triangle
303  double d = dpp.norm();
304  double a1 = acos(n1*n2);
305  double a2 = acos(dpp*n2/d);
306  double r;
307  if (a1 != 0)
308  r = d*sin(a2)/sin(a1);//sine law
309  else
310  r = 1.e10;//something big
311  return pm1-n1*r;
312 }
313 //***************************************************************************
314 //---------------------------------------------------------------------------
315 void a_point::read(std::istream &in)
316 {
317  in >> x_;
318  in >> y_;
319  in >> z_;
320 }
321 //---------------------------------------------------------------------------
322 void a_point::write(std::ostream &o) const
323 {
324  o << this->x() << " ";
325  o << this->y() << " ";
326  o << this->z() << " ";
327 }
328 //---------------------------------------------------------------------------
329 double angle(a_point a, a_point b)
330 {
331  double pi = 3.141592653589793238;
332  a.normalise();
333  b.normalise();
334  double c = a*b;
335  double s = cross(a,b).norm();
336  if (c<0)
337  {
338  if (s<0)
339  return acos(-c)+pi;
340  else
341  return pi-acos(-c);
342  }
343  else
344  {
345  if (s<0)
346  return -acos(c);
347  else
348  return acos(c);
349  }
350 }
351 //---------------------------------------------------------------------------
352 a_point average_rot(const a_point& a, const a_point& b, double f)
353 {
354  double l1 = a.norm();
355  double l2 = b.norm();
356  double l = l1+f*(l2-l1);
357  a_point axis = cross(a,b).normalise();
358  double phi = angle(a,b)*f;
359  a_point inter = a;
360  a_point pn = l*inter.rotate(axis,phi).normalise();
361  return pn;
362 }
const double pi
a circle
Definition: a_circle.h:29
a_point operator-(const a_point &a, const a_point &b)
Definition: a_point.cxx:254
a_point operator+(const a_point &a, const a_point &b)
Definition: a_point.cxx:248
double angle(a_point a, a_point b)
Definition: a_point.cxx:329
a_point cross(const a_point &a, const a_point &b)
Definition: a_point.cxx:284
a_point average_rot(const a_point &a, const a_point &b, double f)
Definition: a_point.cxx:352
a_point circle_centre(const a_point &p1, const a_point &p2, const a_point &p3)
Definition: a_point.cxx:293
a_point operator/(const a_point &a, double v)
Definition: a_point.cxx:278
double operator*(const a_point &a, const a_point &b)
Definition: a_point.cxx:260
a_quaternion sqrt(const a_quaternion &x)
static const std::string help()
Definition: a_geom_base.cxx:21
a square matrix unit
Definition: a_mat_sq.h:29
a_point & operator-=(const a_point &)
Definition: a_point.cxx:121
double norm1() const
Definition: a_point.cxx:172
a_point operator+(const a_point &)
Definition: a_point.cxx:79
a_point & operator+=(const a_point &)
Definition: a_point.cxx:113
double normI() const
Definition: a_point.cxx:180
a_point & operator=(const a_point &p)
Definition: a_point.cxx:139
double x_
Definition: a_point.h:106
double y_
Definition: a_point.h:107
bool operator==(const a_point &p) const
Definition: a_point.cxx:134
a_point & rotate(const a_point &x_axis, const a_point &y_axis, const a_point &z_axis)
Definition: a_point.cxx:225
a_point cross(const a_point &) const
Definition: a_point.cxx:96
double sumsq() const
Definition: a_point.cxx:163
a_point & normalise()
Definition: a_point.cxx:190
static const std::string help()
Definition: a_point.cxx:22
a_point & operator/=(double v)
Definition: a_point.cxx:155
double z() const
Definition: a_point.h:56
double y() const
Definition: a_point.h:55
double norm2() const
Definition: a_point.cxx:176
double z_
Definition: a_point.h:108
double x() const
Definition: a_point.h:54
virtual void write(std::ostream &o) const
Definition: a_point.cxx:322
double operator*=(const a_point &)
Definition: a_point.cxx:129
a_mat_sq inertia() const
Definition: a_point.cxx:197
double operator*(const a_point &)
Definition: a_point.cxx:91
virtual void read(std::istream &i)
Definition: a_point.cxx:315
a_point & operator-()
Definition: a_point.cxx:71
a_point & max()
set maximum abs value of component to 1.
Definition: a_point.cxx:214
double norm() const
Definition: a_point.cxx:168