Point.cc
Go to the documentation of this file.00001
00002
00003 #include <math.h>
00004
00005 #include "Shared/Config.h"
00006 #include "Motion/Kinematics.h"
00007
00008 #include "Shared/Measures.h"
00009 #include "Point.h"
00010 #include "LineData.h"
00011 #include "ShapeTypes.h"
00012 #include "VRmixin.h"
00013 #include "SketchSpace.h"
00014
00015 #ifdef PLATFORM_APERIOS
00016
00017 template<typename T> static inline int signbit(T x) { return x<0; }
00018 #endif
00019
00020 using namespace std;
00021
00022 namespace DualCoding {
00023
00024 float Point::distanceFrom(const Point& otherPt) const {
00025 return (coords - otherPt.coords).norm();
00026 }
00027
00028 float Point::xyDistanceFrom(const Point& other) const {
00029 float dx = coordX() - other.coordX();
00030 float dy = coordY() - other.coordY();
00031 return sqrt(dx*dx + dy*dy);
00032 }
00033
00034 AngSignPi Point::atanYX() const {
00035 return atan2(coordY(), coordX());
00036 }
00037
00038 float Point::xyNorm() const { return sqrt(coordX()*coordX() + coordY()*coordY()); }
00039
00040 float Point::xyzNorm() const { return sqrt(coordX()*coordX() + coordY()*coordY() + coordZ()*coordZ()); }
00041
00042 Point Point::unitVector() const {
00043 return (*this) / xyzNorm();
00044 }
00045
00046
00047 bool Point::isLeftOf(const Point& other, float distance) const {
00048 switch ( refFrameType ) {
00049 case camcentric:
00050 return coordX()+distance < other.coordX();
00051 case egocentric:
00052 return coordY()-distance > other.coordY();
00053 case allocentric: {
00054
00055
00056 AngSignPi thisBearing = ((*this)-VRmixin::theAgent->getCentroid()).atanYX();
00057 AngSignPi otherBearing = (other-VRmixin::theAgent->getCentroid()).atanYX();
00058 AngSignPi diff = thisBearing - otherBearing;
00059 return diff > 0;
00060
00061
00062 }
00063 default:
00064 cout<<"Unspecified reference frame for Point::isLeftOf"<<endl;
00065 return false;
00066 }
00067 }
00068
00069 bool Point::isRightOf(const Point& other, float distance) const {
00070 return other.isLeftOf(*this,distance); }
00071
00072 bool Point::isAbove(const Point& other,float distance) const {
00073 switch ( refFrameType ) {
00074 case camcentric:
00075 return coordY()+distance < other.coordY();
00076 case egocentric:
00077 return coordX()-distance > other.coordX();
00078 case allocentric:
00079
00080 return coordX()-distance > other.coordX();
00081
00082
00083 default:
00084 cout<<"Unspecified reference frame for Point::isAbove"<<endl;
00085 return false;
00086 }
00087 }
00088
00089 bool Point::isBelow(const Point& other, float distance) const {
00090 return other.isAbove(*this,distance); }
00091
00092
00093
00094 void Point::applyTransform(const fmat::Transform& Tmat, const ReferenceFrameType_t newref) {
00095 fmat::Column<3> tmp = Tmat*fmat::SubVector<3>(&coords[0]);
00096 coords[0] = tmp[0];
00097 coords[1] = tmp[1];
00098 coords[2] = tmp[2];
00099 if ( newref != unspecified )
00100 refFrameType = newref;
00101 }
00102
00103 bool Point::projectToGround(const fmat::Transform& camToBase, const PlaneEquation& groundplane) {
00104 const float xres = VRmixin::camSkS.getWidth();
00105 const float yres = VRmixin::camSkS.getHeight();
00106 const float maxres = max(xres,yres);
00107 const float normX = float(2*coordX() - xres)/maxres;
00108 const float normY = float(2*coordY() - yres)/maxres;
00109 fmat::Column<3> camera_vector;
00110 config->vision.computeRay(normX, normY, camera_vector[0], camera_vector[1], camera_vector[2]);
00111
00112
00113
00114
00115
00116
00117 fmat::Column<3> ro_b = camToBase.translation();
00118 fmat::Column<3> rv_b = camToBase.rotation() * camera_vector;
00119
00120
00121 float dist = groundplane.getDisplacement() - fmat::dotProduct(ro_b, groundplane.getDirection());
00122
00123 float align = fmat::dotProduct(rv_b, groundplane.getDirection());
00124
00125
00126
00127 refFrameType = egocentric;
00128 if ( std::abs(align) > numeric_limits<float>::epsilon() ) {
00129 coords = rv_b * (dist/align) + ro_b;
00130
00131
00132
00133
00134
00135
00136 return true;
00137 } else if ( align!=0 && dist!=0 && signbit(align)!=signbit(dist) ) {
00138 coords = -rv_b * 1.0e6f;
00139 return false;
00140 } else {
00141 coords = rv_b * 1.0e6f;
00142 return false;
00143 }
00144 }
00145
00146 bool Point::projectToGround(int xres, int yres, const PlaneEquation& groundplane) {
00147 #ifdef TGT_HAS_CAMERA
00148
00149 const float normX = float(2*coordX() - xres)/xres;
00150 const float normY = float(2*coordY() - yres)/xres;
00151 fmat::Column<3> camera_vector;
00152 config->vision.computeRay(normX, normY, camera_vector[0],camera_vector[1],camera_vector[2]);
00153 fmat::Column<4> ground_point = kine->projectToPlane(CameraFrameOffset, camera_vector, BaseFrameOffset, groundplane, BaseFrameOffset);
00154 coords = fmat::SubVector<3>(ground_point);
00155 if(ground_point[3]!=1) {
00156
00157
00158 coords*=1.0e6f;
00159 return false;
00160 }
00161 return true;
00162
00163
00164
00165 #else
00166 return false;
00167 #endif
00168 }
00169
00170
00171
00172 float Point::getHeightAbovePoint(const Point& groundPoint, const PlaneEquation& groundplane) {
00173 #ifndef TGT_HAS_CAMERA
00174 return groundPoint.coordZ();
00175 #else
00176 fmat::Transform baseToCam = kine->linkToBase(CameraFrameOffset);
00177 fmat::Column<3> camOffset = baseToCam.translation();
00178
00179
00180
00181 camOffset -= groundplane.getDirection()*groundplane.getDisplacement();
00182
00183
00184 float dx = camOffset[0] - coords[0];
00185 float dy = camOffset[1] - coords[1];
00186 float dz = camOffset[2] - coords[2];
00187
00188 float dHorizCam = sqrt(dx*dx + dy*dy);
00189
00190 Point dP = groundPoint - *this;
00191 float dHorizPoint = sqrt(dP.coordX()*dP.coordX() + dP.coordY()*dP.coordY());
00192
00193 return dz*dHorizPoint/dHorizCam;
00194 #endif
00195 }
00196
00197
00198 Point Point::operator+ (const Point& b) const { return Point(*this) += b; }
00199
00200 Point& Point::operator+= (const Point& b) {
00201 coords += b.coords;
00202 makeRefFrameCompatible(b);
00203 return *this;
00204 }
00205
00206 Point Point::operator- (const Point& b) const { return Point(*this) -= b; }
00207
00208 Point& Point::operator-= (const Point& b) {
00209 coords -= b.coords;
00210 makeRefFrameCompatible(b);
00211 return *this;
00212 }
00213
00214 void Point::makeRefFrameCompatible(const Point &other) {
00215 refFrameType = ( refFrameType == unspecified || refFrameType == other.refFrameType ) ?
00216 other.refFrameType : unspecified;
00217 }
00218
00219 Point Point::operator* (float const b) const { return Point(coords*b,refFrameType); }
00220
00221 Point& Point::operator *= (float const b) {
00222 coords *= b;
00223 return *this;
00224 }
00225
00226
00227 Point Point::operator/ (float const b) const { return Point(coords/b,refFrameType); }
00228
00229 Point& Point::operator /= (float const b) {
00230 coords /= b;
00231 return *this;
00232 }
00233
00234 bool Point::operator== (const Point& b) const {
00235 return (coordX() == b.coordX()
00236 && coordY() == b.coordY()
00237 && coordZ() == b.coordZ());
00238 }
00239
00240 void Point::printData() const {
00241 cout<<"{"<<coordX()<<","<<coordY()<<","<<coordZ()<<"}";
00242 }
00243
00244 }