PointCoordinates.cpp
Go to the documentation of this file.
00001 /****************************************************************************
00002 **
00003 ** Copyright (c) 2009-2011 C.B. Barber. All rights reserved.
00004 ** $Id: //main/2011/qhull/src/libqhullcpp/PointCoordinates.cpp#5 $$Change: 1382 $
00005 ** $DateTime: 2011/05/14 10:45:42 $$Author: bbarber $
00006 **
00007 ****************************************************************************/
00008 
00009 #include "QhullError.h"
00010 #include "QhullPoint.h"
00011 #include "PointCoordinates.h"
00012 
00013 #include <iterator>
00014 #include <iostream>
00015 
00016 using std::istream;
00017 using std::string;
00018 using std::ws;
00019 
00020 #ifdef _MSC_VER  // Microsoft Visual C++ -- warning level 4
00021 #pragma warning( disable : 4996)  // function was declared deprecated(strcpy, localtime, etc.)
00022 #endif
00023 
00024 namespace orgQhull {
00025 
00026 #//! PointCoordinates -- vector of PointCoordinates
00027 
00028 #//Construct
00029 PointCoordinates::
00030 PointCoordinates()
00031 : QhullPoints()
00032 , point_coordinates()
00033 , point_comment()
00034 {
00035     makeValid();
00036 }
00037 
00038 #//Construct
00039 PointCoordinates::
00040 PointCoordinates(int pointDimension)
00041 : QhullPoints(pointDimension)
00042 , point_coordinates()
00043 , point_comment()
00044 {
00045     makeValid();
00046 }
00047 
00048 PointCoordinates::
00049 PointCoordinates(const std::string &aComment)
00050 : QhullPoints()
00051 , point_coordinates()
00052 , point_comment(aComment)
00053 {
00054     makeValid();
00055 }
00056 
00057 PointCoordinates::
00058 PointCoordinates(int pointDimension, const std::string &aComment)
00059 : QhullPoints(pointDimension)
00060 , point_coordinates()
00061 , point_comment(aComment)
00062 {
00063     makeValid();
00064 }
00065 
00066 PointCoordinates::
00067 PointCoordinates(int pointDimension, const std::string &aComment, int coordinatesCount, const coordT *c)
00068 : QhullPoints(pointDimension)
00069 , point_coordinates()
00070 , point_comment(aComment)
00071 {
00072     append(coordinatesCount, c);
00073 }
00074 
00075 PointCoordinates::
00076 PointCoordinates(const PointCoordinates &other)
00077 : QhullPoints(other)
00078 , point_coordinates(other.point_coordinates)
00079 , point_comment(other.point_comment)
00080 {
00081     makeValid();
00082 }
00083 
00084 PointCoordinates & PointCoordinates::
00085 operator=(const PointCoordinates &other)
00086 {
00087     point_coordinates= other.point_coordinates;
00088     point_comment= other.point_comment;
00089     makeValid();
00090     return *this;
00091 }//operator=
00092 
00093 PointCoordinates::
00094 ~PointCoordinates()
00095 { }
00096 
00097 #//GetSet
00098 
00099 void PointCoordinates::
00100 checkValid() const
00101 {
00102     if(getCoordinates().data()!=data()
00103     || getCoordinates().count()!=coordinateCount()){
00104         throw QhullError(10060, "Qhull error: first point (%x) is not PointCoordinates.data() or count (%d) is not PointCoordinates.count (%d)", coordinateCount(), getCoordinates().count(), 0.0, data());
00105     }
00106 }//checkValid
00107 
00108 void PointCoordinates::
00109 setDimension(int i)
00110 {
00111     if(i<0){
00112         throw QhullError(10062, "Qhull error: can not set PointCoordinates dimension to %d", i);
00113     }
00114     int currentDimension=QhullPoints::dimension();
00115     if(currentDimension!=0 && i!=currentDimension){
00116         throw QhullError(10063, "Qhull error: can not change PointCoordinates dimension (from %d to %d)", currentDimension, i);
00117     }
00118     QhullPoints::setDimension(i);
00119 }//setDimension
00120 
00121 //#Foreach
00122 
00123 Coordinates::ConstIterator PointCoordinates::
00124 beginCoordinates(int pointIndex) const
00125 {
00126     return point_coordinates.begin()+indexOffset(pointIndex);
00127 }
00128 
00129 Coordinates::Iterator PointCoordinates::
00130 beginCoordinates(int pointIndex)
00131 {
00132     return point_coordinates.begin()+indexOffset(pointIndex);
00133 }
00134 
00135 #//Modify
00136 
00137 void PointCoordinates::
00138 append(int coordinatesCount, const coordT *c)
00139 {
00140     if(coordinatesCount<=0){
00141         return;
00142     }
00143     if(includesCoordinates(c)){
00144         throw QhullError(10065, "Qhull error: can not append a subset of PointCoordinates to itself.  The coordinates for point %d may move.", indexOf(c, QhullError::NOthrow));
00145     }
00146     reserveCoordinates(coordinatesCount);
00147     std::copy(c, c+coordinatesCount, std::back_inserter(point_coordinates));
00148     makeValid();
00149 }//append coordT
00150 
00151 void PointCoordinates::
00152 append(const PointCoordinates &other)
00153 {
00154     setDimension(other.dimension());
00155     append(other.coordinateCount(), other.data());
00156 }//append PointCoordinates
00157 
00158 void PointCoordinates::
00159 append(const QhullPoint &p)
00160 {
00161     setDimension(p.dimension());
00162     append(p.dimension(), p.coordinates());
00163 }//append QhullPoint
00164 
00165 void PointCoordinates::
00166 appendComment(const std::string &s){
00167     if(char c= s[0] && point_comment.empty()){
00168         if(c=='-' || isdigit(c)){
00169             throw QhullError(10028, "Qhull argument error: comments can not start with a number or minus, %s", 0, 0, 0.0, s.c_str());
00170         }
00171     }
00172     point_comment += s;
00173 }//appendComment
00174 
00177 void PointCoordinates::
00178 appendPoints(istream &in)
00179 {
00180     int inDimension, inCount;
00181     in >> ws >> inDimension >> ws;
00182     if(!in.good()){
00183         in.clear();
00184         string remainder;
00185         getline(in, remainder);
00186         throw QhullError(10005, "Qhull error: input did not start with dimension or count -- %s", 0, 0, 0, remainder.c_str());
00187     }
00188     char c= (char)in.peek();
00189     if(c!='-' && !isdigit(c)){         // Comments start with a non-digit
00190         getline(in, point_comment);
00191         in >> ws;
00192     }
00193     in >> inCount >> ws;
00194     if(!in.good()){
00195         in.clear();
00196         string remainder;
00197         getline(in, remainder);
00198         throw QhullError(10009, "Qhull error: input did not start with dimension and count -- %d %s", inDimension, 0, 0, remainder.c_str());
00199     }
00200     c= (char)in.peek();
00201     if(c!='-' && !isdigit(c)){         // Comments start with a non-digit
00202         getline(in, point_comment);
00203         in >> ws;
00204     }
00205     if(inCount<inDimension){           // Count may precede dimension
00206         std::swap(inCount, inDimension);
00207     }
00208     setDimension(inDimension);
00209     reserveCoordinates(inCount*inDimension);
00210     int coordinatesCount= 0;
00211     while(!in.eof()){
00212         realT p;
00213         in >> p >> ws;
00214         if(in.fail()){
00215             in.clear();
00216             string remainder;
00217             getline(in, remainder);
00218             throw QhullError(10008, "Qhull error: failed to read coordinate %d  of point %d\n   %s", coordinatesCount % inDimension, coordinatesCount/inDimension, 0, remainder.c_str());
00219         }else{
00220             point_coordinates.push_back(p);
00221             coordinatesCount++;
00222         }
00223     }
00224     if(coordinatesCount != inCount*inDimension){
00225         if(coordinatesCount%inDimension==0){
00226             throw QhullError(10006, "Qhull error: expected %d %d-d PointCoordinates but read %i PointCoordinates", int(inCount), inDimension, 0.0, int(coordinatesCount/inDimension));
00227         }else{
00228             throw QhullError(10012, "Qhull error: expected %d %d-d PointCoordinates but read %i PointCoordinates plus %f extra coordinates", inCount, inDimension, float(coordinatesCount%inDimension), coordinatesCount/inDimension);
00229         }
00230     }
00231     makeValid();
00232 }//appendPoints istream
00233 
00234 PointCoordinates PointCoordinates::
00235 operator+(const PointCoordinates &other) const
00236 {
00237     PointCoordinates pc= *this;
00238     pc << other;
00239     return pc;
00240 }//operator+
00241 
00242 void PointCoordinates::
00243 reserveCoordinates(int newCoordinates)
00244 {
00245     // vector::reserve is not const
00246     point_coordinates.reserve((int)point_coordinates.size()+newCoordinates); // WARN64
00247     makeValid();
00248 }//reserveCoordinates
00249 
00250 #//Helpers
00251 
00252 int PointCoordinates::
00253 indexOffset(int i) const {
00254     int n= i*dimension();
00255     int coordinatesCount= point_coordinates.count();
00256     if(i<0 || n>coordinatesCount){
00257         throw QhullError(10061, "Qhull error: point_coordinates is too short (%d) for point %d", coordinatesCount, i);
00258     }
00259     return n;
00260 }
00261 
00262 }//namespace orgQhull
00263 
00264 #//Global functions
00265 
00266 using std::endl;
00267 using std::ostream;
00268 
00269 using orgQhull::Coordinates;
00270 using orgQhull::PointCoordinates;
00271 
00272 ostream&
00273 operator<<(ostream &os, const PointCoordinates &p)
00274 {
00275     p.checkValid();
00276     int count= p.count();
00277     int dimension= p.dimension();
00278     string comment= p.comment();
00279     if(comment.empty()){
00280         os << dimension << endl;
00281     }else{
00282         os << dimension << " " << comment << endl;
00283     }
00284     os << count << endl;
00285     Coordinates::ConstIterator c= p.beginCoordinates();
00286     for(int i=0; i<count; i++){
00287         for(int j=0; j<dimension; j++){
00288             os << *c++ << " ";
00289         }
00290         os << endl;
00291     }
00292     return os;
00293 }//operator<<
00294 


libqhull-ours
Author(s): Robert Krug
autogenerated on Mon Jan 6 2014 11:32:11