00001
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"
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
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
00060
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
00078
00079 }
00080 }
00081
00082 bool Point::isBelow(const Point& other, float distance) const {
00083 return other.isAbove(*this,distance); }
00084
00085
00086
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
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
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
00132
00133
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
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
00146
00147
00148 camOffset = camOffset - groundplane;
00149 camOffset(4) = 1;
00150
00151 Kinematics::unpack(camOffset, camX, camY, camZ);
00152
00153 float dx = camX - coords(1);
00154 float dy = camY - coords(2);
00155 float dz = camZ - coords(3);
00156
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 }