Points&Forces (survey)
Software tools facilitating the task of surveying architecture
a_twist.cxx
Go to the documentation of this file.
1 /*
2 Copyright 2009-2014 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 "a_debug.h"
18 #include "a_twist.h"
19 
20 void a_twist::set(const a_point& p, a_point d, double t, double r)
21 {
22  //d cannot be null, it is a direction
23  if (d.norm()==0)
24  return;
25  d.normalise();
26  p1_ = d*r;//rotation is the same
27  a_point d0 =d*t;
28  double lp = p.norm();
29  if (lp==0.)//point of application is at origin
30  {
31  p2_ = d0;
32  return;
33  }
34  //compute transformation of origin
35  //(is also opposite of transformation of p around origin)
36  //angle between p and d
37  //component of p along d (not affected by rotation)
38  a_point pl = (p*d)*d;
39  //component of p perpendicular to d (affected by rotation)
40  a_point pp = p-pl;
41  //length of pp
42  double spp=pp.norm();
43  //unit vector // to pp
44  a_point u = pp/spp;
45  //unit vector normal to p and pp
46  a_point v = cross(d,u);
47  //new (rotated) pp
48  a_point ppn=(u*cos(r)+v*sin(r))*spp;
49  //translation of p
50  a_point tp = pp-ppn;
51  //translation is opposite
52  p2_ = tp+d0;
53 //VE(p2_)
54  return;
55 }
56 //---------------------------------------------------------------------------
57 void a_twist::set(double x, double y, double z, double dx, double dy, double dz, double t, double r)
58 {
59  a_point p(x,y,z);
60  a_point d(dx,dy,dz);
61  this->set(p,d,t,r);
62 }
63 //---------------------------------------------------------------------------
64 // d:(dx, dy, dz) is a screw applied at point p:(x, y, z) (length is not important)
65 // t is displacement along d
66 // r is a rotation around d applied at p (radian)
67 // p_1 is the equivalent rotation centered at the origin: applied first
68 // p_2 is the equivalent displacement: applied second
69 //---------------------------------------------------------------------------
70 a_twist::a_twist(double x, double y, double z, double dx, double dy, double dz, double t, double r)
71 {
72  a_point p(x,y,z);
73  a_point d(dx,dy,dz);
74  this->set(p,d,t,r);
75 }
76 //---------------------------------------------------------------------------
78 {
79  a_point p(0.,0.,0.);
80  a_point d(1.,0.,0.);
81  this->set(p,d,0.,0.);
82 }
83 //---------------------------------------------------------------------------
84 a_twist::a_twist(const a_point& p, a_point d, double t, double r)
85 {
86  this->set(p,d,t,r);
87 }
88 //---------------------------------------------------------------------------
89 a_point a_twist::operator* (a_point p) const
90 {
91  a_point p1 = p1_;
92  a_point p2 = p2_;
93  double a = p1.norm(); //angle of rotation
94  //if no rotation, it is just a translation
95  if (a==0)
96  return p+p2;
97  a_point ar = p1_/a; //axis of rotation
98  a_point pl = ar*(ar*p);//part of p not affected by rotation
99  a_point pr = p-pl;//part of p affected by rotation
100  double lpr = pr.norm();//radius to be rotated
101  //if point on the axis of rotation, just a translation
102  if (lpr==0.)
103  return p+p2;
104  a_point prx = pr/lpr;//x axis perp. to axis of rot.
105  a_point pry = cross(ar,pr).normalise();//y axis perp. to axis of rot.
106  prx *= lpr*cos(a);
107  pry *= lpr*sin(a);
108  a_point prn = prx+pry;//radius rotated
109  return p2+pl+prn;
110 }
111 //---------------------------------------------------------------------------
112 const std::string a_twist::help()
113 {
114  std::ostringstream o;
115  o << "*********" << std::endl;
116  o << "a_twist:" << std::endl;
117  o << "*********" << std::endl;
118  o << "This class is used to model a twist: rotation + translation" << std::endl;
119  o << "Commands:" << std::endl;
120  o << "--------" << std::endl;
121  o << "a_twist T: creates the identity twist" << std::endl;
122  o << "a_twist T 'p' 'd' 't' 'r': creates a twist applied at 'p', translating 't' and rotating of angle 'r' along direction 'd'" << std::endl;
123  o << "a_twist T 'x' 'y' 'z' 'dx' 'dy' 'dz' ('r'): creates a twist applied at 'x,y,z', translating 'dx,dy,dz' while, possibly, rotating of angle 'r'" << std::endl;
124  o << "" << std::endl;
125  o << "set 'p' 'd' 't' 'r': set twist applied at 'p', translating 't' and rotating of angle 'r' along direction 'd'" << std::endl;
126  o << "set 'x' 'y' 'z' 'dx' 'dy' 'dz' ('r'): set twist applied at 'x,y,z', translating 'dx,dy,dz' while, possibly, rotating of angle 'r'" << std::endl;
127  o << "reset: reset to an identity twist" << std::endl;
128  o << "dx: gets translation along x" << std::endl;
129  o << "dy: gets translation along y" << std::endl;
130  o << "dz: gets translation along z" << std::endl;
131  o << "d: gets translation norm" << std::endl;
132  o << "rx: gets rotation about x" << std::endl;
133  o << "ry: gets rotation about y" << std::endl;
134  o << "rz: gets rotation about z" << std::endl;
135  o << "r: gets rotation norm" << std::endl;
136  o << "quaternion: gets quaternion of transformation (a_quaternion)" << std::endl;
137  o << "matrix: gets matrix of transformation (a_mat_sq)" << std::endl;
138  o << "translate 'p': translates of 'p'" << std::endl;
139  o << "translate 'x' 'y' 'z': idem" << std::endl;
140  o << "rotate 'p' 'dir' 'v': rotate of an angle 'v' around an axe of rotation passing by 'p' and with direction 'dir'" << std::endl;
141  o << "'twist' * 'p': gets a new point, transforming point 'p' using the twist 'twist'" << std::endl;
142  return o.str();
143 }
144 //---------------------------------------------------------------------------
146 {
147  p1_.set(0.,0.,0.);
148  p2_.set(0.,0.,0.);
149 }
150 //---------------------------------------------------------------------------
151 void a_twist::translate(const a_point& d)
152 {
153  p2_ += d;
154 }
155 //---------------------------------------------------------------------------
156 a_quaternion a_twist::quaternion() const
157 {
158  a_point n = this->p1();
159  double r = n.norm();
160  n.normalise();
161  double c = cos(r/2.);
162  double s = sin(r/2.);
163  a_quaternion q(c,n.x()*s,n.y()*s,n.z()*s);
164  return q;
165 }
166 //---------------------------------------------------------------------------
167 void a_twist::quaternion(a_quaternion q)
168 {
169  a_point n(q.i(),q.j(),q.k());
170  n.normalise();
171  double a=q.r();
172  if (a<-1.) a=-1.;
173  else if (a>1.) a=1.;
174  double r = 2*acos(a);
175  p1_ = r*n;
176 }
177 //---------------------------------------------------------------------------
178 a_mat_sq a_twist::matrix() const
179 {
180 //method not yet checked !!
181  a_point n = this->p1();
182  double r = n.norm();
183  double c = cos(r);
184  double s = sin(r);
185  double cc= 1-c;
186  double x = n.x();
187  double y = n.y();
188  double z = n.z();
189  a_mat_sq m(3);
190  m(0,0) = x*x*cc+c; m(0,1) = y*x*cc-z*s; m(0,2) = z*x*cc+y*s;
191  m(1,0) = x*y*cc+z*s; m(1,1) = y*y*cc+c; m(1,2) = z*y*cc-x*s;
192  m(2,0) = x*z*cc-y*s; m(2,1) = y*z*cc+x*s; m(2,2) = z*z*cc+c;
193 VE(m)
194  return m;
195 }
196 //---------------------------------------------------------------------------
197 void a_twist::matrix(const a_mat_sq& mat)
198 {
199 //method not yet checked !!
200  double r = acos((mat(0,0)+mat(1,1)+mat(2,2)-1)/2.);
201  double x = mat(2,1)-mat(1,2);
202  double y = mat(0,2)-mat(2,0);
203  double z = mat(1,0)-mat(0,1);
204  a_point p(x,y,z);
205  p.normalise();
206  p1_ = p;
207 }
208 //---------------------------------------------------------------------------
209 void a_twist::rotate(const a_point& pt, const a_point& dir, double r)
210 {
211  //technique: add the rotation + be sure than pt does not move
212  //1. add rotations
213  a_quaternion q1 = this->quaternion();
214  a_point o(0.,0.,0.);
215  a_twist t(o,dir,0.,r);
216  a_quaternion q2 = t.quaternion();
217  a_quaternion q3 = q2*q1;
218  this->quaternion(q3);
219  //2. calculate new translation
220  a_point dp = pt-p2_; //effect of first rotation on pt
221  a_quaternion q4(0.,dp.x(),dp.y(),dp.z());
222  a_quaternion q2i = q2;
223  q2i.invert();
224  a_quaternion q5 = q2*q4*q2i;
225  p2_.x(pt.x()-q5.i());
226  p2_.y(pt.y()-q5.j());
227  p2_.z(pt.z()-q5.k());
228 }
229 //***************************************************************************
230 //---------------------------------------------------------------------------
231 a_point operator* (a_point p, const a_twist& t)
232 {
233  return t*p;
234 }
235 
a_point operator*(a_point p, const a_twist &t)
Definition: a_twist.cxx:231
a_point p1_
Definition: a_plucker.h:63
a_point p2_
Definition: a_plucker.h:64
a_point p2() const
Definition: a_plucker.h:42
a_point p1() const
Definition: a_plucker.h:41
a twist class
Definition: a_twist.h:31
double dy() const
Definition: a_twist.h:51
a_point operator*(a_point p) const
transform a point using the screw
Definition: a_twist.cxx:89
double dz() const
Definition: a_twist.h:52
a_quaternion quaternion() const
conversion routines
Definition: a_twist.cxx:156
double d() const
Definition: a_twist.h:57
a_twist()
Definition: a_twist.cxx:77
a_mat_sq matrix() const
Definition: a_twist.cxx:178
void rotate(const a_point &pt, const a_point &dir, double v)
Definition: a_twist.cxx:209
void reset()
Definition: a_twist.cxx:145
void set(const a_point &p, a_point d, double t, double r)
Definition: a_twist.cxx:20
void translate(const a_point &d)
iterative transformation
Definition: a_twist.cxx:151
double dx() const
p2_ : translation
Definition: a_twist.h:50
static const std::string help()
get information about the class
Definition: a_twist.cxx:112
double r() const
Definition: a_twist.h:58