00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
#ifndef WFMATH_POINT_FUNCS_H
00028
#define WFMATH_POINT_FUNCS_H
00029
00030
#include <wfmath/const.h>
00031
#include <wfmath/vector.h>
00032
#include <wfmath/point.h>
00033
00034
namespace WFMath {
00035
00036
template<const
int dim>
00037 inline Point<dim>::Point(
const Point<dim>& p) : m_valid(p.m_valid)
00038 {
00039
for(
int i = 0; i < dim; ++i)
00040 m_elem[i] = p.
m_elem[i];
00041 }
00042
00043
template<const
int dim>
00044 inline Point<dim>&
Point<dim>::setToOrigin()
00045 {
00046
for(
int i = 0; i < dim; ++i)
00047 m_elem[i] = 0;
00048
00049 m_valid =
true;
00050
00051
return *
this;
00052 }
00053
00054
template<const
int dim>
00055
inline bool Point<dim>::isEqualTo(
const Point<dim> &p,
double epsilon)
const
00056
{
00057
CoordType delta = (
CoordType) _ScaleEpsilon(m_elem, p.
m_elem, dim, epsilon);
00058
00059
for(
int i = 0; i < dim; ++i)
00060
if(fabs(m_elem[i] - p.
m_elem[i]) > delta)
00061
return false;
00062
00063
return true;
00064 }
00065
00066
template<const
int dim>
00067
inline Vector<dim> operator-(
const Point<dim>& c1,
const Point<dim>& c2)
00068 {
00069 Vector<dim> out;
00070
00071
for(
int i = 0; i < dim; ++i)
00072 out.m_elem[i] = c1.m_elem[i] - c2.m_elem[i];
00073
00074 out.m_valid = c1.m_valid && c2.m_valid;
00075
00076
return out;
00077 }
00078
00079
template<const
int dim>
00080
inline Point<dim> operator+(
const Point<dim>& c,
const Vector<dim>& v)
00081 {
00082 Point<dim> out;
00083
00084
for(
int i = 0; i < dim; ++i)
00085 out.m_elem[i] = c.m_elem[i] + v.m_elem[i];
00086
00087 out.m_valid = c.m_valid && v.m_valid;
00088
00089
return out;
00090 }
00091
00092
template<const
int dim>
00093
inline Point<dim> operator-(
const Point<dim>& c,
const Vector<dim>& v)
00094 {
00095 Point<dim> out;
00096
00097
for(
int i = 0; i < dim; ++i)
00098 out.m_elem[i] = c.m_elem[i] - v.m_elem[i];
00099
00100 out.m_valid = c.m_valid && v.m_valid;
00101
00102
return out;
00103 }
00104
00105
template<const
int dim>
00106
inline Point<dim> operator+(
const Vector<dim>& v,
const Point<dim>& c)
00107 {
00108 Point<dim> out;
00109
00110
for(
int i = 0; i < dim; ++i)
00111 out.m_elem[i] = c.m_elem[i] + v.m_elem[i];
00112
00113 out.m_valid = c.m_valid && v.m_valid;
00114
00115
return out;
00116 }
00117
00118
template<const
int dim>
00119
inline Point<dim>& Point<dim>::operator=(
const Point<dim>& rhs)
00120 {
00121
00122
if (
this == &rhs)
00123
return *
this;
00124
00125
for(
int i = 0; i < dim; ++i)
00126 m_elem[i] = rhs.m_elem[i];
00127
00128 m_valid = rhs.m_valid;
00129
00130
return *
this;
00131 }
00132
00133
template<const
int dim>
00134
inline Point<dim>& operator+=(Point<dim>& p,
const Vector<dim> &rhs)
00135 {
00136
for(
int i = 0; i < dim; ++i)
00137 p.m_elem[i] += rhs.m_elem[i];
00138
00139 p.m_valid = p.m_valid && rhs.m_valid;
00140
00141
return p;
00142 }
00143
00144
template<const
int dim>
00145
inline Point<dim>& operator-=(Point<dim>& p,
const Vector<dim> &rhs)
00146 {
00147
for(
int i = 0; i < dim; ++i)
00148 p.m_elem[i] -= rhs.m_elem[i];
00149
00150 p.m_valid = p.m_valid && rhs.m_valid;
00151
00152
return p;
00153 }
00154
00155
template<const
int dim>
00156
inline CoordType SquaredDistance(
const Point<dim>& p1,
const Point<dim>& p2)
00157 {
00158
CoordType ans = 0;
00159
00160
for(
int i = 0; i < dim; ++i) {
00161
CoordType diff = p1.m_elem[i] - p2.m_elem[i];
00162 ans += diff * diff;
00163 }
00164
00165
return (fabs(ans) >= _ScaleEpsilon(p1.m_elem, p2.m_elem, dim)) ? ans : 0;
00166 }
00167
00168
#ifndef WFMATH_NO_TEMPLATES_AS_TEMPLATE_PARAMETERS
00169
template<const
int dim,
template<
class>
class container,
00170
template<
class>
class container2>
00171 Point<dim> Barycenter(
const container<
Point<dim> >& c,
00172
const container2<CoordType>& weights)
00173 {
00174
00175
00176
typename container<Point<dim> >::const_iterator c_i = c.begin(), c_end = c.end();
00177
typename container2<CoordType>::const_iterator w_i = weights.begin(),
00178 w_end = weights.end();
00179
00180 assert(
"nonempty list of points" && c_i != c_end);
00181 assert(
"nonempty list of weights" && w_i != w_end);
00182
00183
bool valid = c_i->isValid();
00184
00185
CoordType tot_weight = *w_i, max_weight = fabs(*w_i);
00186
Point<dim> out;
00187
for(
int j = 0; j < dim; ++j)
00188 out[j] = (*c_i)[j] * *w_i;
00189
00190
while(++c_i != c_end && ++w_i != w_end) {
00191 tot_weight += *w_i;
00192
CoordType val = fabs(*w_i);
00193
if(val > max_weight)
00194 max_weight = val;
00195
if(!c_i->isValid())
00196 valid =
false;
00197
for(
int j = 0; j < dim; ++j)
00198 out[j] += (*c_i)[j] * *w_i;
00199 }
00200
00201
00202 assert(
"sum of weights must be nonzero" && max_weight > 0
00203 && fabs(tot_weight) > max_weight * WFMATH_EPSILON);
00204
00205
for(
int j = 0; j < dim; ++j)
00206 out[j] /= tot_weight;
00207
00208 out.
setValid(valid);
00209
00210
return out;
00211 }
00212
00213
template<const
int dim,
template<
class>
class container>
00214 Point<dim> Barycenter(
const container<
Point<dim> >& c)
00215 {
00216
00217
00218
typename container<Point<dim> >::const_iterator i = c.begin(), end = c.end();
00219
00220 assert(
"nonempty list of points" && i != end);
00221
00222
Point<dim> out = *i;
00223
int num_points = 1;
00224
00225
bool valid = i->
isValid();
00226
00227
while(++i != end) {
00228 ++num_points;
00229
if(!i->
isValid())
00230 valid =
false;
00231
for(
int j = 0; j < dim; ++j)
00232 out[j] += (*i)[j];
00233 }
00234
00235
for(
int j = 0; j < dim; ++j)
00236 out[j] /= num_points;
00237
00238 out.
setValid(valid);
00239
00240
return out;
00241 }
00242
#endif
00243
00244
template<const
int dim>
00245 inline Point<dim> Midpoint(
const Point<dim>& p1,
const Point<dim>& p2, CoordType dist)
00246 {
00247
Point<dim> out;
00248
CoordType conj_dist = 1 - dist;
00249
00250
for(
int i = 0; i < dim; ++i)
00251 out.
m_elem[i] = p1.
m_elem[i] * conj_dist + p2.
m_elem[i] * dist;
00252
00253 out.
m_valid = p1.
m_valid && p2.
m_valid;
00254
00255
return out;
00256 }
00257
00258 template<>
inline Point<2>::Point(CoordType x, CoordType y) : m_valid(true)
00259 {
00260 m_elem[0] = x;
00261 m_elem[1] = y;
00262 }
00263
00264 template<>
inline Point<3>::Point(CoordType x, CoordType y, CoordType z) : m_valid(true)
00265 {
00266 m_elem[0] = x;
00267 m_elem[1] = y;
00268 m_elem[2] = z;
00269 }
00270
00271
#ifndef WFMATH_NO_CLASS_FUNCTION_SPECIALIZATION
00272
template<>
Point<2>&
Point<2>::polar(CoordType r, CoordType theta);
00273
template<>
void Point<2>::asPolar(CoordType& r, CoordType& theta)
const;
00274
00275
template<>
Point<3>&
Point<3>::polar(CoordType r, CoordType theta,
00276 CoordType z);
00277
template<>
void Point<3>::asPolar(CoordType& r, CoordType& theta,
00278 CoordType& z)
const;
00279
template<>
Point<3>&
Point<3>::spherical(CoordType r, CoordType theta,
00280 CoordType phi);
00281
template<>
void Point<3>::asSpherical(CoordType& r, CoordType& theta,
00282 CoordType& phi)
const;
00283
#else
00284
void _NCFS_Point2_polar(CoordType *m_elem, CoordType r, CoordType theta);
00285
void _NCFS_Point2_asPolar(CoordType *m_elem, CoordType& r, CoordType& theta);
00286
00287
void _NCFS_Point3_polar(CoordType *m_elem, CoordType r, CoordType theta,
00288 CoordType z);
00289
void _NCFS_Point3_asPolar(CoordType *m_elem, CoordType& r, CoordType& theta,
00290 CoordType& z);
00291
void _NCFS_Point3_spherical(CoordType *m_elem, CoordType r, CoordType theta,
00292 CoordType phi);
00293
void _NCFS_Point3_asSpherical(CoordType *m_elem, CoordType& r, CoordType& theta,
00294 CoordType& phi);
00295
00296
template<>
00297
inline Point<2>& Point<2>::polar(CoordType r, CoordType theta)
00298 {
00299 _NCFS_Point2_polar((CoordType*) m_elem, r, theta);
00300 m_valid =
true;
00301
return *
this;
00302 }
00303
00304
template<>
00305
inline void Point<2>::asPolar(CoordType& r, CoordType& theta)
const
00306
{
00307 _NCFS_Point2_asPolar((CoordType*) m_elem, r, theta);
00308 }
00309
00310
template<>
00311
inline Point<3>& Point<3>::polar(CoordType r, CoordType theta, CoordType z)
00312 {
00313 _NCFS_Point3_polar((CoordType*) m_elem, r, theta, z);
00314 m_valid =
true;
00315
return *
this;
00316 }
00317
00318
template<>
00319
inline void Point<3>::asPolar(CoordType& r, CoordType& theta, CoordType& z)
const
00320
{
00321 _NCFS_Point3_asPolar((CoordType*) m_elem, r, theta, z);
00322 }
00323
00324
template<>
00325
inline Point<3>& Point<3>::spherical(CoordType r, CoordType theta, CoordType phi)
00326 {
00327 _NCFS_Point3_spherical((CoordType*) m_elem, r, theta, phi);
00328 m_valid =
true;
00329
return *
this;
00330 }
00331
00332
template<>
00333
inline void Point<3>::asSpherical(CoordType& r, CoordType& theta, CoordType& phi)
const
00334
{
00335 _NCFS_Point3_asSpherical((CoordType*) m_elem, r, theta, phi);
00336 }
00337
#endif
00338
00339 }
00340
00341
#endif // WFMATH_POINT_FUNCS_H