Blender V2.61 - r43446

frames.inl

Go to the documentation of this file.
00001 /***************************************************************************
00002                         frames.inl -  description
00003                        -------------------------
00004     begin                : June 2006
00005     copyright            : (C) 2006 Erwin Aertbelien
00006     email                : firstname.lastname@mech.kuleuven.ac.be
00007 
00008  History (only major changes)( AUTHOR-Description ) :
00009  
00010  ***************************************************************************
00011  *   This library is free software; you can redistribute it and/or         *
00012  *   modify it under the terms of the GNU Lesser General Public            *
00013  *   License as published by the Free Software Foundation; either          *
00014  *   version 2.1 of the License, or (at your option) any later version.    *
00015  *                                                                         *
00016  *   This library is distributed in the hope that it will be useful,       *
00017  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00018  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU     *
00019  *   Lesser General Public License for more details.                       *
00020  *                                                                         *
00021  *   You should have received a copy of the GNU Lesser General Public      *
00022  *   License along with this library; if not, write to the Free Software   *
00023  *   Foundation, Inc., 51 Franklin Street,                                    *
00024  *   Fifth Floor, Boston, MA 02110-1301, USA.                               *
00025  *                                                                         *
00026  ***************************************************************************/
00027 
00028 
00029 IMETHOD Vector::Vector(const Vector & arg)
00030 {
00031     data[0] = arg.data[0];
00032     data[1] = arg.data[1];
00033     data[2] = arg.data[2];
00034 }
00035 
00036 IMETHOD Vector::Vector(double x,double y, double z)
00037 {
00038         data[0]=x;data[1]=y;data[2]=z;
00039 }
00040 
00041 IMETHOD Vector::Vector(double* xyz)
00042 {
00043         data[0]=xyz[0];data[1]=xyz[1];data[2]=xyz[2];
00044 }
00045 
00046 IMETHOD Vector::Vector(float* xyz)
00047 {
00048         data[0]=xyz[0];data[1]=xyz[1];data[2]=xyz[2];
00049 }
00050 
00051 IMETHOD void Vector::GetValue(double* xyz) const
00052 {
00053         xyz[0]=data[0];xyz[1]=data[1];xyz[2]=data[2];
00054 }
00055 
00056 
00057 IMETHOD Vector& Vector::operator =(const Vector & arg)
00058 {
00059     data[0] = arg.data[0];
00060     data[1] = arg.data[1];
00061     data[2] = arg.data[2];
00062     return *this;
00063 }
00064 
00065 IMETHOD Vector operator +(const Vector & lhs,const Vector& rhs)
00066 {
00067     Vector tmp;
00068     tmp.data[0] = lhs.data[0]+rhs.data[0];
00069     tmp.data[1] = lhs.data[1]+rhs.data[1];
00070     tmp.data[2] = lhs.data[2]+rhs.data[2];
00071     return tmp;
00072 }
00073 
00074 IMETHOD Vector operator -(const Vector & lhs,const Vector& rhs)
00075 {
00076     Vector tmp;
00077     tmp.data[0] = lhs.data[0]-rhs.data[0];
00078     tmp.data[1] = lhs.data[1]-rhs.data[1];
00079     tmp.data[2] = lhs.data[2]-rhs.data[2];
00080     return tmp;
00081 }
00082 
00083 IMETHOD double Vector::x() const { return data[0]; }
00084 IMETHOD double Vector::y() const { return data[1]; }
00085 IMETHOD double Vector::z() const { return data[2]; }
00086 
00087 IMETHOD void Vector::x( double _x ) { data[0] = _x; }
00088 IMETHOD void Vector::y( double _y ) { data[1] = _y; }
00089 IMETHOD void Vector::z( double _z ) { data[2] = _z; }
00090 
00091 Vector operator *(const Vector& lhs,double rhs) 
00092 {
00093     Vector tmp;
00094     tmp.data[0] = lhs.data[0]*rhs;
00095     tmp.data[1] = lhs.data[1]*rhs;
00096     tmp.data[2] = lhs.data[2]*rhs;
00097     return tmp;
00098 }
00099 
00100 Vector operator *(double lhs,const Vector& rhs) 
00101 {
00102     Vector tmp;
00103     tmp.data[0] = lhs*rhs.data[0];
00104     tmp.data[1] = lhs*rhs.data[1];
00105     tmp.data[2] = lhs*rhs.data[2];
00106     return tmp;
00107 }
00108 
00109 Vector operator /(const Vector& lhs,double rhs) 
00110 {
00111     Vector tmp;
00112     tmp.data[0] = lhs.data[0]/rhs;
00113     tmp.data[1] = lhs.data[1]/rhs;
00114     tmp.data[2] = lhs.data[2]/rhs;
00115     return tmp;
00116 }
00117 
00118 Vector operator *(const Vector & lhs,const Vector& rhs)
00119 // Complexity : 6M+3A
00120 {
00121     Vector tmp;
00122     tmp.data[0] = lhs.data[1]*rhs.data[2]-lhs.data[2]*rhs.data[1];
00123     tmp.data[1] = lhs.data[2]*rhs.data[0]-lhs.data[0]*rhs.data[2];
00124     tmp.data[2] = lhs.data[0]*rhs.data[1]-lhs.data[1]*rhs.data[0];
00125     return tmp;
00126 }
00127 
00128 Vector& Vector::operator +=(const Vector & arg)
00129 // Complexity : 3A
00130 {
00131     data[0]+=arg.data[0];
00132     data[1]+=arg.data[1];
00133     data[2]+=arg.data[2];
00134     return *this;
00135 }
00136 
00137 Vector& Vector::operator -=(const Vector & arg)
00138 // Complexity : 3A
00139 {
00140     data[0]-=arg.data[0];
00141     data[1]-=arg.data[1];
00142     data[2]-=arg.data[2];
00143     return *this;
00144 }
00145 
00146 Vector Vector::Zero()
00147 {
00148     return Vector(0,0,0);
00149 }
00150 
00151 double Vector::operator()(int index) const {
00152     FRAMES_CHECKI((0<=index)&&(index<=2));
00153     return data[index];
00154 }
00155 
00156 double& Vector::operator () (int index)
00157 {
00158     FRAMES_CHECKI((0<=index)&&(index<=2));
00159     return data[index];
00160 }
00161 
00162 IMETHOD Vector Normalize(const Vector& a, double eps)
00163 {
00164     double l=a.Norm();
00165     return (l<eps) ? Vector(0.0,0.0,0.0) : a/l;
00166 }
00167 
00168 Wrench Frame::operator * (const Wrench& arg) const
00169 // Complexity : 24M+18A
00170 {
00171     Wrench tmp;
00172     tmp.force  = M*arg.force;
00173     tmp.torque = M*arg.torque + p*tmp.force;
00174     return tmp;
00175 }
00176 
00177 Wrench Frame::Inverse(const Wrench& arg) const
00178 {
00179     Wrench tmp;
00180     tmp.force =  M.Inverse(arg.force);
00181     tmp.torque = M.Inverse(arg.torque-p*arg.force);
00182     return tmp;
00183 }
00184 
00185 
00186 
00187 Wrench Rotation::Inverse(const Wrench& arg) const
00188 {
00189     return Wrench(Inverse(arg.force),Inverse(arg.torque));
00190 }
00191 
00192 Twist Rotation::Inverse(const Twist& arg) const
00193 {
00194     return Twist(Inverse(arg.vel),Inverse(arg.rot));
00195 }
00196 
00197 Wrench Wrench::Zero()
00198 {
00199     return Wrench(Vector::Zero(),Vector::Zero());
00200 }
00201 
00202 
00203 void Wrench::ReverseSign()
00204 {   
00205     torque.ReverseSign();
00206     force.ReverseSign();
00207 }
00208 
00209 Wrench Wrench::RefPoint(const Vector& v_base_AB) const
00210      // Changes the reference point of the Wrench.
00211      // The vector v_base_AB is expressed in the same base as the twist
00212      // The vector v_base_AB is a vector from the old point to
00213      // the new point.
00214 {
00215     return Wrench(this->force,
00216                   this->torque+this->force*v_base_AB
00217                   );
00218 }
00219 
00220 
00221 Wrench& Wrench::operator-=(const Wrench& arg)
00222 {
00223     torque-=arg.torque;
00224     force -=arg.force;
00225     return *this;
00226 }
00227 
00228 Wrench& Wrench::operator+=(const Wrench& arg)
00229 {
00230     torque+=arg.torque;
00231     force +=arg.force;
00232     return *this;
00233 }
00234 
00235 double& Wrench::operator()(int i)
00236 {
00237     // assert((0<=i)&&(i<6)); done by underlying routines
00238     if (i<3) 
00239         return force(i);
00240     else
00241         return torque(i-3);
00242 }
00243 
00244 double Wrench::operator()(int i) const
00245 {
00246     // assert((0<=i)&&(i<6)); done by underlying routines
00247     if (i<3) 
00248         return force(i);
00249     else
00250         return torque(i-3);
00251 }
00252 
00253 
00254 Wrench operator*(const Wrench& lhs,double rhs)
00255 {
00256     return Wrench(lhs.force*rhs,lhs.torque*rhs);
00257 }
00258 
00259 Wrench operator*(double lhs,const Wrench& rhs)
00260 {
00261     return Wrench(lhs*rhs.force,lhs*rhs.torque);
00262 }
00263 
00264 Wrench operator/(const Wrench& lhs,double rhs)
00265 {
00266     return Wrench(lhs.force/rhs,lhs.torque/rhs);
00267 }
00268 
00269 // addition of Wrench's
00270 Wrench operator+(const Wrench& lhs,const Wrench& rhs)
00271 {
00272     return Wrench(lhs.force+rhs.force,lhs.torque+rhs.torque);
00273 }
00274 
00275 Wrench operator-(const Wrench& lhs,const Wrench& rhs)
00276 {
00277     return Wrench(lhs.force-rhs.force,lhs.torque-rhs.torque);
00278 }
00279 
00280 // unary -
00281 Wrench operator-(const Wrench& arg) 
00282 {
00283     return Wrench(-arg.force,-arg.torque);
00284 }
00285 
00286 Twist Frame::operator * (const Twist& arg) const
00287 // Complexity : 24M+18A
00288 {
00289     Twist tmp;
00290     tmp.rot = M*arg.rot;
00291     tmp.vel = M*arg.vel+p*tmp.rot;
00292     return tmp;
00293 }
00294 Twist Frame::Inverse(const Twist& arg) const
00295 {
00296     Twist tmp;
00297     tmp.rot =  M.Inverse(arg.rot);
00298     tmp.vel = M.Inverse(arg.vel-p*arg.rot);
00299     return tmp;
00300 }
00301 
00302 Twist Twist::Zero()
00303 {
00304     return Twist(Vector::Zero(),Vector::Zero());
00305 }
00306 
00307 
00308 void Twist::ReverseSign()
00309 {   
00310     vel.ReverseSign();
00311     rot.ReverseSign();
00312 }
00313 
00314 Twist Twist::RefPoint(const Vector& v_base_AB) const
00315      // Changes the reference point of the twist.
00316      // The vector v_base_AB is expressed in the same base as the twist
00317      // The vector v_base_AB is a vector from the old point to
00318      // the new point.
00319      // Complexity : 6M+6A
00320 {
00321     return Twist(this->vel+this->rot*v_base_AB,this->rot);
00322 }
00323 
00324 Twist& Twist::operator-=(const Twist& arg)
00325 {
00326     vel-=arg.vel;
00327     rot -=arg.rot;
00328     return *this;
00329 }
00330 
00331 Twist& Twist::operator+=(const Twist& arg)
00332 {
00333     vel+=arg.vel;
00334     rot +=arg.rot;
00335     return *this;
00336 }
00337 
00338 double& Twist::operator()(int i)
00339 {
00340     // assert((0<=i)&&(i<6)); done by underlying routines
00341     if (i<3) 
00342         return vel(i);
00343     else
00344         return rot(i-3);
00345 }
00346 
00347 double Twist::operator()(int i) const
00348 {
00349     // assert((0<=i)&&(i<6)); done by underlying routines
00350     if (i<3) 
00351         return vel(i);
00352     else
00353         return rot(i-3);
00354 }
00355 
00356 
00357 Twist operator*(const Twist& lhs,double rhs)
00358 {
00359     return Twist(lhs.vel*rhs,lhs.rot*rhs);
00360 }
00361 
00362 Twist operator*(double lhs,const Twist& rhs)
00363 {
00364     return Twist(lhs*rhs.vel,lhs*rhs.rot);
00365 }
00366 
00367 Twist operator/(const Twist& lhs,double rhs)
00368 {
00369     return Twist(lhs.vel/rhs,lhs.rot/rhs);
00370 }
00371 
00372 // addition of Twist's
00373 Twist operator+(const Twist& lhs,const Twist& rhs)
00374 {
00375     return Twist(lhs.vel+rhs.vel,lhs.rot+rhs.rot);
00376 }
00377 
00378 Twist operator-(const Twist& lhs,const Twist& rhs)
00379 {
00380     return Twist(lhs.vel-rhs.vel,lhs.rot-rhs.rot);
00381 }
00382 
00383 // unary -
00384 Twist operator-(const Twist& arg) 
00385 {
00386     return Twist(-arg.vel,-arg.rot);
00387 }
00388 
00389 Frame::Frame(const Rotation & R)
00390 {
00391     M=R;
00392     p=Vector::Zero();
00393 }
00394 
00395 Frame::Frame(const Vector & V)
00396 {
00397     M = Rotation::Identity();
00398     p = V;
00399 }
00400 
00401 Frame::Frame(const Rotation & R, const Vector & V)
00402 {
00403     M = R;
00404     p = V;
00405 }
00406 
00407  Frame operator *(const Frame& lhs,const Frame& rhs)
00408 // Complexity : 36M+36A
00409 {
00410     return Frame(lhs.M*rhs.M,lhs.M*rhs.p+lhs.p);
00411 }
00412 
00413 Vector Frame::operator *(const Vector & arg) const
00414 {
00415     return M*arg+p;
00416 }
00417 
00418 Vector Frame::Inverse(const Vector& arg) const
00419 {
00420     return M.Inverse(arg-p);
00421 }
00422 
00423 Frame Frame::Inverse() const
00424 {
00425     return Frame(M.Inverse(),-M.Inverse(p));
00426 }
00427 
00428 
00429 Frame& Frame::operator =(const Frame & arg)
00430 { 
00431     M = arg.M;
00432     p = arg.p;
00433     return *this;
00434 }
00435 
00436 Frame::Frame(const Frame & arg) :
00437     p(arg.p),M(arg.M)
00438 {}
00439 
00440 
00441 void Vector::ReverseSign()
00442 {
00443     data[0] = -data[0];
00444     data[1] = -data[1];
00445     data[2] = -data[2];
00446 }
00447 
00448 
00449 
00450 Vector operator-(const Vector & arg)
00451 {
00452     Vector tmp;
00453     tmp.data[0]=-arg.data[0];
00454     tmp.data[1]=-arg.data[1];
00455     tmp.data[2]=-arg.data[2];
00456     return tmp;
00457 }
00458 
00459 void Vector::Set2DXY(const Vector2& v)
00460 // a 3D vector where the 2D vector v is put in the XY plane
00461 {
00462     data[0]=v(0);
00463     data[1]=v(1);
00464     data[2]=0;
00465 
00466 }
00467 void Vector::Set2DYZ(const Vector2& v)
00468 // a 3D vector where the 2D vector v is put in the YZ plane
00469 {
00470     data[1]=v(0);
00471     data[2]=v(1);
00472     data[0]=0;
00473 
00474 }
00475 
00476 void Vector::Set2DZX(const Vector2& v)
00477 // a 3D vector where the 2D vector v is put in the ZX plane
00478 {
00479     data[2]=v(0);
00480     data[0]=v(1);
00481     data[1]=0;
00482 
00483 }
00484 
00485 
00486 
00487 
00488 
00489 double& Rotation::operator()(int i,int j) {
00490     FRAMES_CHECKI((0<=i)&&(i<=2)&&(0<=j)&&(j<=2));
00491     return data[i*3+j];
00492 }
00493 
00494 double Rotation::operator()(int i,int j) const {
00495     FRAMES_CHECKI((0<=i)&&(i<=2)&&(0<=j)&&(j<=2));
00496     return data[i*3+j];
00497 }
00498 
00499 Rotation::Rotation( double Xx,double Yx,double Zx,
00500                             double Xy,double Yy,double Zy,
00501                             double Xz,double Yz,double Zz)
00502 {
00503     data[0] = Xx;data[1]=Yx;data[2]=Zx;
00504     data[3] = Xy;data[4]=Yy;data[5]=Zy;
00505     data[6] = Xz;data[7]=Yz;data[8]=Zz;
00506 }
00507 
00508 
00509 Rotation::Rotation(const Vector& x,const Vector& y,const Vector& z) 
00510 {
00511     data[0] = x.data[0];data[3] = x.data[1];data[6] = x.data[2];
00512     data[1] = y.data[0];data[4] = y.data[1];data[7] = y.data[2];
00513     data[2] = z.data[0];data[5] = z.data[1];data[8] = z.data[2];
00514 }
00515 
00516 Rotation& Rotation::operator=(const Rotation& arg) {
00517     int count=9;
00518     while (count--) data[count] = arg.data[count];
00519     return *this;
00520 }
00521 
00522 Vector Rotation::operator*(const Vector& v) const {
00523 // Complexity : 9M+6A
00524     return Vector(
00525      data[0]*v.data[0] + data[1]*v.data[1] + data[2]*v.data[2],
00526      data[3]*v.data[0] + data[4]*v.data[1] + data[5]*v.data[2],
00527      data[6]*v.data[0] + data[7]*v.data[1] + data[8]*v.data[2] 
00528     );
00529 }
00530 
00531 Twist Rotation::operator * (const Twist& arg) const
00532      // Transformation of the base to which the twist is expressed.
00533      // look at Frame*Twist for a transformation that also transforms
00534      // the velocity reference point.
00535      // Complexity : 18M+12A
00536 {
00537     return Twist((*this)*arg.vel,(*this)*arg.rot);
00538 }
00539 
00540 Wrench Rotation::operator * (const Wrench& arg) const
00541      // Transformation of the base to which the wrench is expressed.
00542      // look at Frame*Twist for a transformation that also transforms
00543      // the force reference point.
00544 {
00545     return Wrench((*this)*arg.force,(*this)*arg.torque);
00546 }
00547 
00548 Rotation Rotation::Identity() {
00549         return Rotation(1,0,0,0,1,0,0,0,1);
00550 }
00551 // *this = *this * ROT(X,angle)
00552 void Rotation::DoRotX(double angle)
00553 {
00554     double cs = cos(angle);
00555     double sn = sin(angle);
00556     double x1,x2,x3;
00557     x1  = cs* (*this)(0,1) + sn* (*this)(0,2);
00558     x2  = cs* (*this)(1,1) + sn* (*this)(1,2);
00559     x3  = cs* (*this)(2,1) + sn* (*this)(2,2);
00560     (*this)(0,2) = -sn* (*this)(0,1) + cs* (*this)(0,2);
00561     (*this)(1,2) = -sn* (*this)(1,1) + cs* (*this)(1,2);
00562     (*this)(2,2) = -sn* (*this)(2,1) + cs* (*this)(2,2);
00563     (*this)(0,1) = x1;
00564     (*this)(1,1) = x2;
00565     (*this)(2,1) = x3;
00566 }
00567 
00568 void Rotation::DoRotY(double angle)
00569 {
00570     double cs = cos(angle);
00571     double sn = sin(angle);
00572     double x1,x2,x3;
00573     x1  = cs* (*this)(0,0) - sn* (*this)(0,2);
00574     x2  = cs* (*this)(1,0) - sn* (*this)(1,2);
00575     x3  = cs* (*this)(2,0) - sn* (*this)(2,2);
00576     (*this)(0,2) = sn* (*this)(0,0) + cs* (*this)(0,2);
00577     (*this)(1,2) = sn* (*this)(1,0) + cs* (*this)(1,2);
00578     (*this)(2,2) = sn* (*this)(2,0) + cs* (*this)(2,2);
00579     (*this)(0,0) = x1;
00580     (*this)(1,0) = x2;
00581     (*this)(2,0) = x3;
00582 }
00583 
00584 void Rotation::DoRotZ(double angle)
00585 {
00586     double cs = cos(angle);
00587     double sn = sin(angle);
00588     double x1,x2,x3;
00589     x1  = cs* (*this)(0,0) + sn* (*this)(0,1);
00590     x2  = cs* (*this)(1,0) + sn* (*this)(1,1);
00591     x3  = cs* (*this)(2,0) + sn* (*this)(2,1);
00592     (*this)(0,1) = -sn* (*this)(0,0) + cs* (*this)(0,1);
00593     (*this)(1,1) = -sn* (*this)(1,0) + cs* (*this)(1,1);
00594     (*this)(2,1) = -sn* (*this)(2,0) + cs* (*this)(2,1);
00595     (*this)(0,0) = x1;
00596     (*this)(1,0) = x2;
00597     (*this)(2,0) = x3;
00598 }
00599 
00600 
00601 Rotation Rotation::RotX(double angle) {
00602     double cs=cos(angle);
00603     double sn=sin(angle);
00604     return Rotation(1,0,0,0,cs,-sn,0,sn,cs);
00605 }
00606 Rotation Rotation::RotY(double angle) {
00607     double cs=cos(angle);
00608     double sn=sin(angle);
00609     return Rotation(cs,0,sn,0,1,0,-sn,0,cs);
00610 }
00611 Rotation Rotation::RotZ(double angle) {
00612     double cs=cos(angle);
00613     double sn=sin(angle);
00614     return Rotation(cs,-sn,0,sn,cs,0,0,0,1);
00615 }
00616 
00617 
00618 
00619 
00620 void Frame::Integrate(const Twist& t_this,double samplefrequency)
00621 {
00622     double n = t_this.rot.Norm()/samplefrequency;
00623     if (n<epsilon) {
00624         p += M*(t_this.vel/samplefrequency);
00625     } else {
00626         (*this) = (*this) * 
00627             Frame ( Rotation::Rot( t_this.rot, n ),
00628                     t_this.vel/samplefrequency
00629                 );
00630     }
00631 }
00632 
00633 Rotation Rotation::Inverse() const
00634 {
00635     Rotation tmp(*this);
00636     tmp.SetInverse();
00637     return tmp;
00638 }
00639 
00640 Vector Rotation::Inverse(const Vector& v) const {
00641     return Vector(
00642      data[0]*v.data[0] + data[3]*v.data[1] + data[6]*v.data[2],
00643      data[1]*v.data[0] + data[4]*v.data[1] + data[7]*v.data[2],
00644      data[2]*v.data[0] + data[5]*v.data[1] + data[8]*v.data[2] 
00645     );
00646 }
00647 
00648 void Rotation::setValue(float* oglmat)
00649 {
00650     data[0] = *oglmat++; data[3] = *oglmat++; data[6] = *oglmat++; oglmat++;
00651     data[1] = *oglmat++; data[4] = *oglmat++; data[7] = *oglmat++; oglmat++;
00652     data[2] = *oglmat++; data[5] = *oglmat++; data[8] = *oglmat;
00653     Ortho();
00654 }
00655 
00656 void Rotation::getValue(float* oglmat) const
00657 {
00658     *oglmat++ = (float)data[0]; *oglmat++ = (float)data[3]; *oglmat++ = (float)data[6]; *oglmat++ = 0.f;
00659     *oglmat++ = (float)data[1]; *oglmat++ = (float)data[4]; *oglmat++ = (float)data[7]; *oglmat++ = 0.f;
00660     *oglmat++ = (float)data[2]; *oglmat++ = (float)data[5]; *oglmat++ = (float)data[8]; *oglmat++ = 0.f;
00661     *oglmat++ = 0.f;            *oglmat++ = 0.f;            *oglmat++ = 0.f;            *oglmat   = 1.f;
00662 }
00663 
00664 void Rotation::SetInverse()
00665 {
00666     double tmp;
00667     tmp = data[1];data[1]=data[3];data[3]=tmp;
00668     tmp = data[2];data[2]=data[6];data[6]=tmp;
00669     tmp = data[5];data[5]=data[7];data[7]=tmp;
00670 }
00671 
00672 
00673 
00674 
00675 
00676 
00677 
00678 double Frame::operator()(int i,int j) {
00679     FRAMES_CHECKI((0<=i)&&(i<=3)&&(0<=j)&&(j<=3));
00680     if (i==3) {
00681         if (j==3)
00682             return 1.0;
00683         else
00684             return 0.0;
00685     } else {
00686         if (j==3) 
00687             return p(i);
00688         else
00689             return M(i,j);
00690 
00691     }
00692 }
00693 
00694 double Frame::operator()(int i,int j) const {
00695     FRAMES_CHECKI((0<=i)&&(i<=3)&&(0<=j)&&(j<=3));
00696         if (i==3) {
00697         if (j==3)
00698             return 1;
00699         else
00700             return 0;
00701     } else {
00702         if (j==3) 
00703             return p(i);
00704         else
00705             return M(i,j);
00706 
00707     }
00708 }
00709 
00710 
00711 Frame Frame::Identity() {
00712     return Frame(Rotation::Identity(),Vector::Zero());
00713 }
00714 
00715 
00716 void Frame::setValue(float* oglmat)
00717 {
00718     M.setValue(oglmat);
00719     p.data[0] = oglmat[12];
00720     p.data[1] = oglmat[13];
00721     p.data[2] = oglmat[14];
00722 }
00723 
00724 void Frame::getValue(float* oglmat) const
00725 {
00726     M.getValue(oglmat);
00727     oglmat[12] = (float)p.data[0];
00728     oglmat[13] = (float)p.data[1];
00729     oglmat[14] = (float)p.data[2];
00730 }
00731 
00732 void Vector::Set2DPlane(const Frame& F_someframe_XY,const Vector2& v_XY)
00733 // a 3D vector where the 2D vector v is put in the XY plane of the frame
00734 // F_someframe_XY.
00735 {
00736 Vector tmp_XY;
00737 tmp_XY.Set2DXY(v_XY);
00738 tmp_XY = F_someframe_XY*(tmp_XY);
00739 }
00740 
00741 
00742 
00743 
00744 
00745 
00746 
00747 
00748 
00749 //============ 2 dimensional version of the frames objects =============
00750 IMETHOD Vector2::Vector2(const Vector2 & arg)
00751 {
00752     data[0] = arg.data[0];
00753     data[1] = arg.data[1];
00754 }
00755 
00756 IMETHOD Vector2::Vector2(double x,double y)
00757 {
00758         data[0]=x;data[1]=y;
00759 }
00760 
00761 IMETHOD Vector2::Vector2(double* xy)
00762 {
00763         data[0]=xy[0];data[1]=xy[1];
00764 }
00765 
00766 IMETHOD Vector2::Vector2(float* xy)
00767 {
00768         data[0]=xy[0];data[1]=xy[1];
00769 }
00770 
00771 IMETHOD Vector2& Vector2::operator =(const Vector2 & arg)
00772 {
00773     data[0] = arg.data[0];
00774     data[1] = arg.data[1];
00775     return *this;
00776 }
00777 
00778 IMETHOD void Vector2::GetValue(double* xy) const
00779 {
00780         xy[0]=data[0];xy[1]=data[1];
00781 }
00782 
00783 IMETHOD Vector2 operator +(const Vector2 & lhs,const Vector2& rhs)
00784 {
00785     return Vector2(lhs.data[0]+rhs.data[0],lhs.data[1]+rhs.data[1]);
00786 }
00787 
00788 IMETHOD Vector2 operator -(const Vector2 & lhs,const Vector2& rhs)
00789 {
00790     return Vector2(lhs.data[0]-rhs.data[0],lhs.data[1]-rhs.data[1]);
00791 }
00792 
00793 IMETHOD Vector2 operator *(const Vector2& lhs,double rhs) 
00794 {
00795     return Vector2(lhs.data[0]*rhs,lhs.data[1]*rhs);
00796 }
00797 
00798 IMETHOD Vector2 operator *(double lhs,const Vector2& rhs) 
00799 {
00800     return Vector2(lhs*rhs.data[0],lhs*rhs.data[1]);
00801 }
00802 
00803 IMETHOD Vector2 operator /(const Vector2& lhs,double rhs) 
00804 {
00805     return Vector2(lhs.data[0]/rhs,lhs.data[1]/rhs);
00806 }
00807 
00808 IMETHOD Vector2& Vector2::operator +=(const Vector2 & arg)
00809 {
00810     data[0]+=arg.data[0];
00811     data[1]+=arg.data[1];
00812     return *this;
00813 }
00814 
00815 IMETHOD Vector2& Vector2::operator -=(const Vector2 & arg)
00816 {
00817     data[0]-=arg.data[0];
00818     data[1]-=arg.data[1];
00819     return *this;
00820 }
00821 
00822 IMETHOD Vector2 Vector2::Zero() {
00823     return Vector2(0,0);
00824 }
00825 
00826 IMETHOD double Vector2::operator()(int index) const {
00827     FRAMES_CHECKI((0<=index)&&(index<=1));
00828     return data[index];
00829 }
00830 
00831 IMETHOD double& Vector2::operator () (int index)
00832 {
00833     FRAMES_CHECKI((0<=index)&&(index<=1));
00834     return data[index];
00835 }
00836 IMETHOD void Vector2::ReverseSign()
00837 {
00838     data[0] = -data[0];
00839     data[1] = -data[1];
00840 }
00841 
00842 
00843 IMETHOD Vector2 operator-(const Vector2 & arg)
00844 {
00845     return Vector2(-arg.data[0],-arg.data[1]);
00846 }
00847 
00848 
00849 IMETHOD void Vector2::Set3DXY(const Vector& v)
00850 // projects v in its XY plane, and sets *this to these values
00851 {
00852     data[0]=v(0);
00853     data[1]=v(1);
00854 }
00855 IMETHOD void Vector2::Set3DYZ(const Vector& v)
00856 // projects v in its XY plane, and sets *this to these values
00857 {
00858     data[0]=v(1);
00859     data[1]=v(2);
00860 }
00861 IMETHOD void Vector2::Set3DZX(const Vector& v)
00862 // projects v in its XY plane, and and sets *this to these values
00863 {
00864     data[0]=v(2);
00865     data[1]=v(0);
00866 }
00867 
00868 IMETHOD void Vector2::Set3DPlane(const Frame& F_someframe_XY,const Vector& v_someframe) 
00869 // projects v in the XY plane of F_someframe_XY, and sets *this to these values
00870 // expressed wrt someframe.
00871 {
00872     Vector tmp = F_someframe_XY.Inverse(v_someframe);
00873     data[0]=tmp(0);
00874     data[1]=tmp(1);
00875 }
00876 
00877 
00878 
00879 IMETHOD Rotation2& Rotation2::operator=(const Rotation2& arg) {
00880     c=arg.c;s=arg.s;
00881     return *this;
00882 }
00883 
00884 IMETHOD Vector2 Rotation2::operator*(const Vector2& v) const {
00885     return Vector2(v.data[0]*c-v.data[1]*s,v.data[0]*s+v.data[1]*c);
00886 }
00887 
00888 IMETHOD double Rotation2::operator()(int i,int j) const {
00889     FRAMES_CHECKI((0<=i)&&(i<=1)&&(0<=j)&&(j<=1));
00890     if (i==j) return c;
00891     if (i==0) 
00892         return s;
00893     else
00894         return -s;
00895 }
00896 
00897 
00898 IMETHOD Rotation2 operator *(const Rotation2& lhs,const Rotation2& rhs) {
00899     return Rotation2(lhs.c*rhs.c-lhs.s*rhs.s,lhs.s*rhs.c+lhs.c*rhs.s);
00900 }
00901 
00902 IMETHOD void Rotation2::SetInverse() {
00903     s=-s;
00904 }
00905 
00906 IMETHOD Rotation2 Rotation2::Inverse() const {
00907     return Rotation2(c,-s);
00908 }
00909 
00910 IMETHOD Vector2 Rotation2::Inverse(const Vector2& v) const {
00911     return Vector2(v.data[0]*c+v.data[1]*s,-v.data[0]*s+v.data[1]*c);
00912 }
00913 
00914 IMETHOD Rotation2 Rotation2::Identity() {
00915     return Rotation2(1,0);
00916 }
00917      
00918 IMETHOD void Rotation2::SetIdentity()
00919 {
00920     c = 1;
00921     s = 0;
00922 }
00923 
00924 IMETHOD void Rotation2::SetRot(double angle) {
00925     c=cos(angle);s=sin(angle);
00926 }
00927 
00928 IMETHOD Rotation2 Rotation2::Rot(double angle) {
00929     return Rotation2(cos(angle),sin(angle));
00930 }
00931 
00932 IMETHOD double Rotation2::GetRot() const {
00933     return atan2(s,c);
00934 }
00935 
00936 
00937 IMETHOD Frame2::Frame2() {
00938 }
00939 
00940 IMETHOD Frame2::Frame2(const Rotation2 & R)
00941 {
00942     M=R;
00943     p=Vector2::Zero();
00944 }
00945 
00946 IMETHOD Frame2::Frame2(const Vector2 & V)
00947 {
00948     M = Rotation2::Identity();
00949     p = V;
00950 }
00951 
00952 IMETHOD Frame2::Frame2(const Rotation2 & R, const Vector2 & V)
00953 {
00954     M = R;
00955     p = V;
00956 }
00957 
00958 IMETHOD Frame2 operator *(const Frame2& lhs,const Frame2& rhs)
00959 {
00960     return Frame2(lhs.M*rhs.M,lhs.M*rhs.p+lhs.p);
00961 }
00962 
00963 IMETHOD Vector2 Frame2::operator *(const Vector2 & arg)
00964 {
00965     return M*arg+p;
00966 }
00967 
00968 IMETHOD Vector2 Frame2::Inverse(const Vector2& arg) const
00969 {
00970     return M.Inverse(arg-p);
00971 }
00972 
00973 IMETHOD void Frame2::SetIdentity()
00974 {
00975     M.SetIdentity();
00976     p = Vector2::Zero();
00977 }
00978 
00979 IMETHOD void Frame2::SetInverse()
00980 {
00981     M.SetInverse();
00982     p = M*p;
00983     p.ReverseSign();
00984 }
00985 
00986 
00987 IMETHOD Frame2 Frame2::Inverse() const
00988 {
00989     Frame2 tmp(*this);
00990     tmp.SetInverse();
00991     return tmp;
00992 }
00993 
00994 IMETHOD Frame2& Frame2::operator =(const Frame2 & arg)
00995 { 
00996     M = arg.M;
00997     p = arg.p;
00998     return *this;
00999 }
01000 
01001 IMETHOD Frame2::Frame2(const Frame2 & arg) :
01002     p(arg.p), M(arg.M)
01003 {}
01004 
01005 
01006 IMETHOD double Frame2::operator()(int i,int j) {
01007     FRAMES_CHECKI((0<=i)&&(i<=2)&&(0<=j)&&(j<=2));
01008     if (i==2) {
01009         if (j==2)
01010             return 1;
01011         else
01012             return 0;
01013     } else {
01014         if (j==2) 
01015             return p(i);
01016         else
01017             return M(i,j);
01018 
01019     }
01020 }
01021 
01022 IMETHOD double Frame2::operator()(int i,int j) const {
01023     FRAMES_CHECKI((0<=i)&&(i<=2)&&(0<=j)&&(j<=2));
01024     if (i==2) {
01025         if (j==2)
01026             return 1;
01027         else
01028             return 0;
01029     } else {
01030         if (j==2) 
01031             return p(i);
01032         else
01033             return M(i,j);
01034 
01035     }
01036 }
01037 
01038 // Scalar products.
01039 
01040 IMETHOD double dot(const Vector& lhs,const Vector& rhs) {
01041     return rhs(0)*lhs(0)+rhs(1)*lhs(1)+rhs(2)*lhs(2);
01042 }
01043 
01044 IMETHOD double dot(const Twist& lhs,const Wrench& rhs) {
01045     return dot(lhs.vel,rhs.force)+dot(lhs.rot,rhs.torque);
01046 }
01047 
01048 IMETHOD double dot(const Wrench& rhs,const Twist& lhs) {
01049     return dot(lhs.vel,rhs.force)+dot(lhs.rot,rhs.torque);
01050 }
01051 
01052 
01053 
01054 
01055 
01056 // Equality operators
01057 
01058 
01059 
01060 IMETHOD bool Equal(const Vector& a,const Vector& b,double eps) {
01061         return (Equal(a.data[0],b.data[0],eps)&&
01062                 Equal(a.data[1],b.data[1],eps)&&
01063                 Equal(a.data[2],b.data[2],eps)   );
01064      }
01065      
01066 
01067 IMETHOD bool Equal(const Frame& a,const Frame& b,double eps) {
01068         return (Equal(a.p,b.p,eps)&&
01069                 Equal(a.M,b.M,eps)   );
01070 }
01071 
01072 IMETHOD bool Equal(const Wrench& a,const Wrench& b,double eps) {
01073         return (Equal(a.force,b.force,eps)&&
01074                 Equal(a.torque,b.torque,eps)  );
01075 }
01076 
01077 IMETHOD bool Equal(const Twist& a,const Twist& b,double eps) {
01078         return (Equal(a.rot,b.rot,eps)&&
01079                 Equal(a.vel,b.vel,eps)  );
01080 }
01081 
01082 IMETHOD bool Equal(const Vector2& a,const Vector2& b,double eps) {
01083         return (Equal(a.data[0],b.data[0],eps)&&
01084                 Equal(a.data[1],b.data[1],eps)   );
01085      }
01086      
01087 IMETHOD bool Equal(const Rotation2& a,const Rotation2& b,double eps) {
01088     return ( Equal(a.c,b.c,eps) && Equal(a.s,b.s,eps) );
01089 }
01090 
01091 IMETHOD bool Equal(const Frame2& a,const Frame2& b,double eps) {
01092         return (Equal(a.p,b.p,eps)&&
01093                 Equal(a.M,b.M,eps)   );
01094 }
01095 
01096 IMETHOD void SetToZero(Vector& v) {
01097     v=Vector::Zero();
01098 }
01099 IMETHOD void SetToZero(Twist& v) {
01100     SetToZero(v.rot);
01101     SetToZero(v.vel);
01102 }
01103 IMETHOD void SetToZero(Wrench& v) {
01104     SetToZero(v.force);
01105     SetToZero(v.torque);
01106 }
01107 
01108 IMETHOD void SetToZero(Vector2& v) {
01109     v = Vector2::Zero();
01110 }
01111 
01112 
01114 // The following defines the operations
01115 //   diff
01116 //   addDelta
01117 //   random
01118 //   posrandom
01119 // on all the types defined in this library.
01120 // (mostly for uniform integration, differentiation and testing).
01121 // Defined as functions because double is not a class and a method
01122 // would brake uniformity when defined for a double.
01124 
01125 
01126 
01127 
01128 
01129 
01135 IMETHOD Rotation Rot(const Vector& axis_a_b) {
01136     // The formula is 
01137     // V.(V.tr) + st*[V x] + ct*(I-V.(V.tr))
01138     // can be found by multiplying it with an arbitrary vector p
01139     // and noting that this vector is rotated.
01140     Vector rotvec = axis_a_b;
01141     double angle = rotvec.Normalize(1E-10);
01142     double ct = ::cos(angle);
01143     double st = ::sin(angle);
01144     double vt = 1-ct;
01145     return Rotation(
01146         ct            +  vt*rotvec(0)*rotvec(0), 
01147         -rotvec(2)*st +  vt*rotvec(0)*rotvec(1), 
01148         rotvec(1)*st  +  vt*rotvec(0)*rotvec(2),
01149         rotvec(2)*st  +  vt*rotvec(1)*rotvec(0),
01150         ct            +  vt*rotvec(1)*rotvec(1),
01151         -rotvec(0)*st +  vt*rotvec(1)*rotvec(2),
01152         -rotvec(1)*st +  vt*rotvec(2)*rotvec(0),
01153         rotvec(0)*st  +  vt*rotvec(2)*rotvec(1),
01154         ct            +  vt*rotvec(2)*rotvec(2)
01155         );
01156     }
01157 
01158 IMETHOD Vector diff(const Vector& a,const Vector& b,double dt) {
01159     return (b-a)/dt;
01160 }
01161 
01194 IMETHOD Vector diff(const Rotation& R_a_b1,const Rotation& R_a_b2,double dt) {
01195     Rotation R_b1_b2(R_a_b1.Inverse()*R_a_b2);
01196     return R_a_b1 * R_b1_b2.GetRot() / dt;
01197 }
01198 IMETHOD Twist diff(const Frame& F_a_b1,const Frame& F_a_b2,double dt) {
01199     return Twist(
01200             diff(F_a_b1.p,F_a_b2.p,dt),
01201             diff(F_a_b1.M,F_a_b2.M,dt)
01202             );
01203 }
01204 IMETHOD Twist diff(const Twist& a,const Twist& b,double dt) {
01205     return Twist(diff(a.vel,b.vel,dt),diff(a.rot,b.rot,dt));
01206 }
01207 
01208 IMETHOD Wrench diff(const Wrench& a,const Wrench& b,double dt) {
01209     return Wrench(
01210             diff(a.force,b.force,dt),
01211             diff(a.torque,b.torque,dt)
01212             );
01213 }
01214 
01215 
01216 IMETHOD Vector addDelta(const Vector& a,const Vector&da,double dt) {
01217     return a+da*dt;
01218 }
01219 
01220 IMETHOD Rotation addDelta(const Rotation& a,const Vector&da,double dt) {
01221     return a*Rot(a.Inverse(da)*dt);
01222 }
01223 IMETHOD Frame addDelta(const Frame& a,const Twist& da,double dt) {
01224     return Frame(
01225             addDelta(a.M,da.rot,dt),
01226             addDelta(a.p,da.vel,dt)
01227            );
01228 }
01229 IMETHOD Twist addDelta(const Twist& a,const Twist&da,double dt) {
01230     return Twist(addDelta(a.vel,da.vel,dt),addDelta(a.rot,da.rot,dt));
01231 }
01232 IMETHOD Wrench addDelta(const Wrench& a,const Wrench&da,double dt) {
01233     return Wrench(addDelta(a.force,da.force,dt),addDelta(a.torque,da.torque,dt));
01234 }
01235 
01236 
01274 IMETHOD void random(Vector& a) {
01275     random(a[0]);
01276     random(a[1]);
01277     random(a[2]);
01278 }
01279 IMETHOD void random(Twist& a) {
01280     random(a.rot);
01281     random(a.vel);
01282 }
01283 IMETHOD void random(Wrench& a) {
01284     random(a.torque);
01285     random(a.force);
01286 }
01287 
01288 IMETHOD void random(Rotation& R) {
01289     double alfa;
01290     double beta;
01291     double gamma;
01292     random(alfa);
01293     random(beta);
01294     random(gamma);
01295     R = Rotation::EulerZYX(alfa,beta,gamma);
01296 }
01297 
01298 IMETHOD void random(Frame& F) {
01299     random(F.M);
01300     random(F.p);
01301 }
01302 
01303 IMETHOD void posrandom(Vector& a) {
01304     posrandom(a[0]);
01305     posrandom(a[1]);
01306     posrandom(a[2]);
01307 }
01308 IMETHOD void posrandom(Twist& a) {
01309     posrandom(a.rot);
01310     posrandom(a.vel);
01311 }
01312 IMETHOD void posrandom(Wrench& a) {
01313     posrandom(a.torque);
01314     posrandom(a.force);
01315 }
01316 
01317 IMETHOD void posrandom(Rotation& R) {
01318     double alfa;
01319     double beta;
01320     double gamma;
01321     posrandom(alfa);
01322     posrandom(beta);
01323     posrandom(gamma);
01324     R = Rotation::EulerZYX(alfa,beta,gamma);
01325 }
01326 
01327 IMETHOD void posrandom(Frame& F) {
01328     random(F.M);
01329     random(F.p);
01330 }
01331 
01332 
01333 
01334 
01335 IMETHOD bool operator==(const Frame& a,const Frame& b ) {
01336 #ifdef KDL_USE_EQUAL
01337     return Equal(a,b);
01338 #else
01339         return (a.p == b.p &&
01340                 a.M == b.M );
01341 #endif
01342 }
01343 
01344 IMETHOD bool operator!=(const Frame& a,const Frame& b) {
01345     return !operator==(a,b);
01346 }
01347 
01348 IMETHOD bool operator==(const Vector& a,const Vector& b) {
01349 #ifdef KDL_USE_EQUAL
01350     return Equal(a,b);
01351 #else
01352         return (a.data[0]==b.data[0]&&
01353                 a.data[1]==b.data[1]&&
01354                 a.data[2]==b.data[2] );
01355 #endif
01356      }
01357 
01358 IMETHOD bool operator!=(const Vector& a,const Vector& b) {
01359     return !operator==(a,b);
01360 }
01361 
01362 IMETHOD bool operator==(const Twist& a,const Twist& b) {
01363 #ifdef KDL_USE_EQUAL
01364     return Equal(a,b);
01365 #else
01366         return (a.rot==b.rot &&
01367                 a.vel==b.vel  );
01368 #endif
01369 }
01370 
01371 IMETHOD bool operator!=(const Twist& a,const Twist& b) {
01372     return !operator==(a,b);
01373 }
01374 
01375 IMETHOD bool operator==(const Wrench& a,const Wrench& b ) {
01376 #ifdef KDL_USE_EQUAL
01377     return Equal(a,b);
01378 #else
01379     return (a.force==b.force &&
01380             a.torque==b.torque );
01381 #endif
01382 }
01383 
01384 IMETHOD bool operator!=(const Wrench& a,const Wrench& b) {
01385     return !operator==(a,b);
01386 }
01387 IMETHOD bool operator!=(const Rotation& a,const Rotation& b) {
01388     return !operator==(a,b);
01389 }
01390