00001 #ifndef Point_HEADER
00002 #define Point_HEADER
00003
00004 #include <boost/array.hpp>
00005 #include <math.h>
00006 #include <limits>
00007
00008 namespace Geometry {
00009
00010 template <size_t d>
00011 class Point : public boost::array<double, d> {
00012 private:
00013 bool operator==(Point other);
00014
00015 public:
00016 typedef boost::array<double, d> super;
00017 Point() { }
00018 Point(double v) { assign(v); }
00019 Point(const super& t) : super(t) { }
00020 Point(const Point& p) : super(p) { }
00021 Point(const double *v, size_t
00022 #ifndef NDEBUG
00023 n
00024 #endif
00025 ) {
00026 assert(n >= d);
00027 for(unsigned i = 0; i < d; i++) {
00028 (*this)[i] = v[i];
00029 }
00030 }
00031
00032 template <class iterator>
00033 Point(iterator begin, const iterator&
00034 #ifndef NDEBUG
00035 end
00036 #endif
00037 ) {
00038 assert(end - begin == d);
00039 for(unsigned i = 0; i < d; i++, begin++) {
00040 (*this)[i] = *begin;
00041 }
00042 }
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052 void assign(double v) {
00053 for(unsigned i = 0; i < d; ++i) {
00054 this->elems[i] = v;
00055 }
00056 }
00057
00058 static unsigned dim() { return d; }
00059 static const unsigned dimension = d;
00060
00061
00062 static Point unit(unsigned j) {
00063 Point rval(0.0);
00064 rval[j] = 1.0;
00065 return rval;
00066 }
00067
00068
00069 static Point allones() {
00070 Point rval(1.0);
00071 return rval;
00072 }
00073
00074
00075
00076
00077 static Point unitrand() {
00078 Point p;
00079 for(unsigned i = 0; i < d; ++i) {
00080 p[i] = random();
00081 }
00082 double len = sqrt(p.norm2());
00083 p *= 1.0 / len;
00084 return p;
00085 }
00086 static Point randPoint(double max) {
00087 Point p = unitrand();
00088 double r = (double)random() / (double)std::numeric_limits<long>::max();
00089 assert(r < 1.0);
00090 p *= r * max;
00091 return p;
00092 }
00093
00094 void operator+= (const Point& p) {
00095 for (unsigned i = 0; i < d; ++i) {
00096 (*this)[i] += p[i];
00097 }
00098 }
00099
00100 Point operator+ (const Point& p) const {
00101 Point copy = *this; copy += p; return copy;
00102 }
00103
00104 void operator-= (const Point& p) {
00105 for (unsigned i = 0; i < d; ++i) {
00106 (*this)[i] -= p[i];
00107 }
00108 }
00109
00110 Point operator- (const Point& p) const {
00111 Point copy = *this; copy -= p; return copy;
00112 }
00113
00114 void operator*= (double x) {
00115 for (unsigned i = 0; i < d; ++i) {
00116 (*this)[i] *= x;
00117 }
00118 }
00119
00120 Point operator* (double x) const {
00121 Point copy = *this; copy *= x; return copy;
00122 }
00123
00124 void operator/= (double x) {
00125 for (unsigned i = 0; i < d; ++i) {
00126 (*this)[i] /= x;
00127 }
00128 }
00129
00130 Point operator/ (double x) const {
00131 Point copy = *this; copy /= x; return copy;
00132 }
00133
00134 double dot(const Point& p) const {
00135 double sum = 0.0;
00136 for(unsigned i = 0; i < d; i++) {
00137 sum += (*this)[i] * p[i];
00138 }
00139 return sum;
00140 }
00141
00142 double dist2(const Point& q) const {
00143 double sum = 0.0;
00144 for(unsigned i = 0; i < d; i++) {
00145 double diff = (*this)[i] - q[i];
00146 sum += diff * diff;
00147 }
00148 return sum;
00149 }
00150
00151 double norm2() const {
00152 double sum = 0.0;
00153 for(unsigned i = 0; i < d; i++) {
00154 sum += (*this)[i] * (*this)[i];
00155 }
00156 return sum;
00157 }
00158
00159 double norm1() const {
00160 double sum = 0.0;
00161 for(unsigned i = 0; i < d; i++) {
00162 sum += (*this)[i];
00163 }
00164 return sum;
00165 }
00166
00167 bool bitwiseEqual(const Point& other) const {
00168 return std::equal(this->begin(), this->end(), other.begin());
00169 }
00170
00171 std::string toString() const {
00172 std::string s = "(";
00173 for (unsigned i = 0; i < d; i++) {
00174 char buffer[4000];
00175 snprintf(buffer, sizeof(buffer), " %g", (*this)[i]);
00176 s += buffer;
00177 }
00178 s += " )";
00179 return s;
00180 }
00181 };
00182
00189 inline Point<3> crossProduct(const Point<3>& a, const Point<3>& b) {
00190 Point<3> p;
00191 p[0] = a[1]*b[2] - a[2]*b[1];
00192 p[1] = a[2]*b[0] - a[0]*b[2];
00193 p[2] = a[0]*b[1] - a[1]*b[0];
00194 return p;
00195 }
00196
00197
00198 }
00199
00200 #endif