Homepage Demos Overview Downloads Tutorials Reference
Credits

Point.cc

Go to the documentation of this file.
00001 //-*-c++-*-
00002 
00003 #include <math.h>
00004 
00005 #include "Shared/Config.h"
00006 #include "Motion/Kinematics.h"
00007 
00008 #include "Measures.h"
00009 #include "Point.h"
00010 #include "LineData.h"
00011 #include "ShapeTypes.h"  // for ReferenceFrameType_t
00012 #include "VRmixin.h"
00013 
00014 namespace DualCoding {
00015 
00016   Point::Point(void) : coords(4), refFrameType(unspecified) {
00017   coords << 0 << 0 << 0 << 1;
00018   }
00019 
00020 Point::Point(coordinate_t const &xp, coordinate_t const &yp, coordinate_t zp, 
00021        ReferenceFrameType_t ref) : coords(4), refFrameType(ref) {
00022   coords << xp << yp << zp << 1;
00023 };
00024 
00025 Point::Point(const NEWMAT::ColumnVector& c, ReferenceFrameType_t ref) : 
00026   coords(4), refFrameType(ref) { coords = c; }
00027 
00028 //!Set Position
00029 //{
00030 void Point::setCoords(const Point& otherPt) {
00031   coords = otherPt.coords;
00032 }
00033 
00034 void Point::setCoords(coordinate_t x, coordinate_t y, coordinate_t z) {
00035   coords << x << y << z << 1;
00036 }
00037 //}
00038 
00039 float Point::distanceFrom(const Point& otherPt) const {
00040   return (coords - otherPt.coords).NormFrobenius();
00041 }
00042 
00043 float Point::xyDistanceFrom(const Point& other) const {
00044   float dx = coords(1)-other.coords(1);
00045   float dy = coords(2)-other.coords(2);
00046   return sqrt(dx*dx+dy*dy);
00047 }
00048 
00049 bool Point::isLeftOf(const Point& other, float distance) const {
00050   switch ( refFrameType ) {
00051   case camcentric:
00052     return coordX()+distance < other.coordX();
00053   case egocentric:  
00054     return coordY()-distance > other.coordY();
00055   case allocentric:
00056   default:
00057     cout << "Allocentric Point::isLeftOf fudged for now" << endl;
00058     return coordY()-distance > other.coordY();
00059     // Should really calculate bearings to both points from current
00060     // agent location and check sign of the difference
00061   }
00062 }
00063 
00064 bool Point::isRightOf(const Point& other, float distance) const {
00065   return other.isLeftOf(*this,distance); }
00066 
00067 bool Point::isAbove(const Point& other,float distance) const {
00068   switch ( refFrameType ) {
00069   case camcentric:
00070     return coordY()+distance < other.coordY();
00071   case egocentric:  
00072     return coordX()-distance > other.coordX();
00073   case allocentric:
00074   default:
00075     cout << "Allocentric Point::isLeftOf fudged for now" << endl;
00076     return coordX()-distance > other.coordX();
00077     // Should really calculate bearings to both points from current
00078     // agent location and check sign of the difference
00079   }
00080 }
00081 
00082 bool Point::isBelow(const Point& other, float distance) const {
00083   return other.isAbove(*this,distance); }
00084 
00085 
00086 //! Apply a transformation matrix to translate and/or rotate  the point.
00087 void Point::applyTransform(const NEWMAT::Matrix& Tmat) { coords = Tmat*coords; }
00088 
00089 void Point::projectToGround(const NEWMAT::Matrix& camToBase,
00090           const NEWMAT::ColumnVector& groundPlane) {
00091   NEWMAT::Matrix T2 = camToBase.i();
00092   T2.SubMatrix(4,4,1,3)=T2.SubMatrix(1,3,4,4).t()*T2.SubMatrix(1,3,1,3);
00093   T2.SubMatrix(1,3,4,4)=0;
00094   //cout << "Transform plane b->j:\n"<<T2;
00095 
00096   const float normX = 2*(coordX()/VRmixin::camSkS.getWidth()) - 1;
00097   const float normY = 2*(coordY()/VRmixin::camSkS.getHeight()) - 1;
00098   NEWMAT::ColumnVector camera_point(4), camPlane(4);
00099   config->vision.computeRay(normX, normY,
00100           camera_point(1),camera_point(2),camera_point(3));
00101   camera_point(4) = 1;
00102   camPlane = T2*groundPlane;
00103   
00104   float denom=0;
00105   for(unsigned int i=1; i<=3; i++)
00106     denom+=camera_point(i)*camPlane(i);
00107   NEWMAT::ColumnVector intersect=camera_point;
00108   if(denom==0)
00109     intersect(4)=0;
00110   else {
00111     float s=camPlane(4)/denom;
00112     for(unsigned int i=1; i<=3; i++)
00113       intersect(i)*=s;
00114     intersect(4)=1;
00115   }
00116   coords = camToBase*intersect;
00117 }
00118 
00119 void Point::projectToGround(int xres, int yres,
00120           const NEWMAT::ColumnVector& ground_plane) {
00121   // Normalize coordinate system to [-1,+1]
00122   const float normX = 2*(coordX()/xres) - 1;
00123   const float normY = 2*(coordY()/yres) - 1;
00124   NEWMAT::ColumnVector camera_point(4), ground_point(4);
00125   config->vision.computeRay(normX, normY,
00126           camera_point(1),camera_point(2),camera_point(3));
00127   camera_point(4) = 1;
00128   ground_point = 
00129     kine->projectToPlane(CameraFrameOffset, camera_point,
00130        BaseFrameOffset, ground_plane, BaseFrameOffset);
00131   //  std::cout << "Ground plane: " << NEWMAT::printmat(ground_plane) << 
00132   //    "  camera_point: " << NEWMAT::printmat(camera_point) << 
00133   //    "  ground_point: " << NEWMAT::printmat(ground_point) << std::endl;
00134   coords(1) = ground_point(1) / ground_point(4);
00135   coords(2) = ground_point(2) / ground_point(4);
00136   coords(3) = ground_point(3) / ground_point(4);
00137 }
00138   
00139 
00140 // Calling point and groundPoint must both have been projectToGround'ed already
00141 float Point::getHeightAbovePoint(const Point& groundPoint, const NEWMAT::ColumnVector& groundplane) {
00142   float camX, camY, camZ;
00143   NEWMAT::Matrix baseToCam = kine->jointToBase(CameraFrameOffset);
00144   NEWMAT::ColumnVector camOffset = baseToCam.Column(4);
00145   //std::cout<<std::endl;
00146   //std::cout<<"cam offset = "<<NEWMAT::printmat(camOffset)<<std::endl;
00147   //std::cout<<"groundPlane = "<<NEWMAT::printmat(groundplane)<<std::endl;
00148   camOffset = camOffset - groundplane;
00149   camOffset(4) = 1;
00150   
00151   Kinematics::unpack(camOffset, camX, camY, camZ);
00152   //std::cout<<"top pt coords = "<<NEWMAT::printmat(coords)<<std::endl;
00153   float dx = camX - coords(1);
00154   float dy = camY - coords(2);
00155   float dz = camZ - coords(3);
00156   //std::cout<<"Cam to point = "<<dx<<" "<<dy<<" "<<dz<<std::endl;
00157   float dHorizCam = sqrt(dx*dx + dy*dy);
00158 
00159   Point dP = groundPoint - *this;
00160   float dHorizPoint = sqrt(dP.coordX()*dP.coordX() + dP.coordY()*dP.coordY());
00161   
00162   return dz*dHorizPoint/dHorizCam;
00163 }
00164 
00165 
00166   Point Point::operator+ (const Point& b) const { return Point(coords+b.coords,refFrameType); }
00167 
00168 Point& Point::operator+= (const Point& b) {
00169   coords += b.coords;
00170   return *this;
00171 }
00172 
00173 
00174 Point Point::operator- (const Point& b) const { return Point(coords-b.coords,refFrameType); }
00175 
00176 Point& Point::operator-= (const Point& b) {
00177   coords -= b.coords;
00178   return *this;
00179 }
00180 
00181 
00182 Point Point::operator* (float const b) const { return Point(coords*b,refFrameType); }
00183 
00184 Point& Point::operator *= (float const b) {
00185   coords *= b;
00186   return *this;
00187 }
00188 
00189 
00190 Point Point::operator/ (float const b) const { return Point(coords/b,refFrameType); }
00191 
00192 Point& Point::operator /= (float const b) {
00193   coords /= b;
00194   return *this;
00195 }
00196 
00197 bool Point::operator ==(const Point& b) const {
00198   return (coordX() == b.coordX() 
00199     && coordY() == b.coordY() 
00200     && coordZ() == b.coordZ());
00201 }
00202 
00203 std::ostream& operator<< (std::ostream& out, const Point &p) {
00204   out << "(" << p.coordX() << ", " << p.coordY() 
00205       << ", " << p.coordZ() << ")";
00206   return out;
00207 }
00208 
00209 void Point::printData()
00210 {
00211   cout<<"{"<<coordX()<<","<<coordY()<<","<<coordZ()<<"}";
00212 }
00213 
00214 } // namespace

DualCoding 3.0beta
Generated Wed Oct 4 00:01:54 2006 by Doxygen 1.4.7