library of assembled shared sources

http://lass.cocamware.com

point_2d.inl

Go to the documentation of this file.
00001 /** @file
00002  *  @author Bram de Greve (bramz@users.sourceforge.net)
00003  *  @author Tom De Muer (tomdemuer@users.sourceforge.net)
00004  *
00005  *  *** BEGIN LICENSE INFORMATION ***
00006  *  
00007  *  The contents of this file are subject to the Common Public Attribution License 
00008  *  Version 1.0 (the "License"); you may not use this file except in compliance with 
00009  *  the License. You may obtain a copy of the License at 
00010  *  http://lass.sourceforge.net/cpal-license. The License is based on the 
00011  *  Mozilla Public License Version 1.1 but Sections 14 and 15 have been added to cover 
00012  *  use of software over a computer network and provide for limited attribution for 
00013  *  the Original Developer. In addition, Exhibit A has been modified to be consistent 
00014  *  with Exhibit B.
00015  *  
00016  *  Software distributed under the License is distributed on an "AS IS" basis, WITHOUT 
00017  *  WARRANTY OF ANY KIND, either express or implied. See the License for the specific 
00018  *  language governing rights and limitations under the License.
00019  *  
00020  *  The Original Code is LASS - Library of Assembled Shared Sources.
00021  *  
00022  *  The Initial Developer of the Original Code is Bram de Greve and Tom De Muer.
00023  *  The Original Developer is the Initial Developer.
00024  *  
00025  *  All portions of the code written by the Initial Developer are:
00026  *  Copyright (C) 2004-2007 the Initial Developer.
00027  *  All Rights Reserved.
00028  *  
00029  *  Contributor(s):
00030  *
00031  *  Alternatively, the contents of this file may be used under the terms of the 
00032  *  GNU General Public License Version 2 or later (the GPL), in which case the 
00033  *  provisions of GPL are applicable instead of those above.  If you wish to allow use
00034  *  of your version of this file only under the terms of the GPL and not to allow 
00035  *  others to use your version of this file under the CPAL, indicate your decision by 
00036  *  deleting the provisions above and replace them with the notice and other 
00037  *  provisions required by the GPL License. If you do not delete the provisions above,
00038  *  a recipient may use your version of this file under either the CPAL or the GPL.
00039  *  
00040  *  *** END LICENSE INFORMATION ***
00041  */
00042 
00043 
00044 
00045 #ifndef LASS_GUARDIAN_OF_INCLUSION_PRIM_POINT_2D_INL
00046 #define LASS_GUARDIAN_OF_INCLUSION_PRIM_POINT_2D_INL
00047 
00048 #include "point_2d.h"
00049 
00050 namespace lass
00051 {
00052 namespace prim
00053 {
00054 
00055 template<typename T> inline
00056 Point2D<T>::Point2D():
00057     x(TNumTraits::zero),
00058     y(TNumTraits::zero)
00059 {
00060     LASS_ASSERT(isZero());
00061 }
00062 
00063 
00064 
00065 template<typename T> inline
00066 Point2D<T>::Point2D(TParam x, TParam y):
00067     x(x),
00068     y(y)
00069 {
00070 }
00071 
00072 
00073 
00074 template<typename T>
00075 template<typename U>
00076 Point2D<T>::Point2D(const Point2D<U>& other):
00077     x(static_cast<TValue>(other.x)),
00078     y(static_cast<TValue>(other.y))
00079 {
00080 }
00081 
00082 
00083 
00084 template<typename T>
00085 template<typename U>
00086 Point2D<T>::Point2D(const Vector2D<U>& position):
00087     x(static_cast<TValue>(position.x)),
00088     y(static_cast<TValue>(position.y))
00089 {
00090 }
00091 
00092 
00093 
00094 template<typename T>
00095 template<typename U>
00096 Point2D<T>::Point2D(const U& x, const U& y):
00097     x(static_cast<TValue>(x)),
00098     y(static_cast<TValue>(y))
00099 {
00100 }
00101 
00102 
00103 
00104 template <typename T> inline
00105 const typename Point2D<T>::TVector
00106 Point2D<T>::position() const
00107 {
00108     return TVector(x, y);
00109 }
00110 
00111 
00112 
00113 template<typename T> inline
00114 typename Point2D<T>::TConstReference
00115 Point2D<T>::operator[](size_t index) const
00116 {
00117     LASS_ASSERT(index < dimension);
00118     return *(&x + index);
00119 }
00120 
00121 
00122 
00123 template<typename T> inline
00124 typename Point2D<T>::TReference
00125 Point2D<T>::operator[](size_t index)
00126 {
00127     LASS_ASSERT(index < dimension);
00128     return *(&x + index);
00129 }
00130 
00131 
00132 
00133 /** Wrap index around range.
00134  */
00135 template<typename T> inline
00136 typename Point2D<T>::TConstReference
00137 Point2D<T>::at(signed index) const
00138 {
00139     return *(&x + num::mod(index, dimension));
00140 }
00141 
00142 
00143 
00144 /** Wrap index around range.
00145  */
00146 template<typename T> inline
00147 typename Point2D<T>::TReference
00148 Point2D<T>::at(signed index)
00149 {
00150     return *(&x + num::mod(index, dimension));
00151 }
00152 
00153 
00154 
00155 template<typename T>
00156 Point2D<T>&
00157 Point2D<T>::operator+=(const Vector2D<T>& offset)
00158 {
00159     x += offset.x;
00160     y += offset.y;
00161     return *this;
00162 }
00163 
00164 
00165 
00166 template<typename T>
00167 Point2D<T>&
00168 Point2D<T>::operator-=(const Vector2D<T>& offset)
00169 {
00170     x -= offset.x;
00171     y -= offset.y;
00172     return *this;
00173 }
00174 
00175 
00176 
00177 template<typename T>
00178 const bool Point2D<T>::isZero() const
00179 {
00180     return x == TNumTraits::zero && y == TNumTraits::zero;
00181 }
00182 
00183 
00184 
00185 /** Return true if at least one of the components is NaN
00186  */
00187 template<typename T> inline
00188 const bool Point2D<T>::isNaN() const
00189 {
00190     return num::isNaN(x) || num::isNaN(y);
00191 }
00192 
00193 
00194 
00195 // --- FREE FUNCTIONS ---------------------------------------------------------------------------
00196 
00197 /** @relates lass::prim::Point2D
00198  */
00199 template<typename T>
00200 bool operator==(const Point2D<T>& a, const Point2D<T>& b)
00201 {
00202     return a.x == b.x && a.y == b.y;
00203 }
00204 
00205 
00206 
00207 /** @relates lass::prim::Point2D
00208  */
00209 template<typename T> inline
00210 bool operator!=(const Point2D<T>& a, const Point2D<T>& b)
00211 {
00212     return !(a == b);
00213 }
00214 
00215 
00216 
00217 /** @relates lass::prim::Point2D
00218  */
00219 template<typename T> inline
00220 Point2D<T> operator+(const Point2D<T>& a, const Vector2D<T>& b)
00221 {
00222     Point2D<T> result(a);
00223     result += b;
00224     return result;
00225 }
00226 
00227 
00228 
00229 /** @relates lass::prim::Point2D
00230  */
00231 template<typename T> inline
00232 Point2D<T> operator+(const Vector2D<T>& a, const Point2D<T>& b)
00233 {
00234     Point2D<T> result(b);
00235     result += a;
00236     return result;
00237 }
00238 
00239 
00240 
00241 /** @relates lass::prim::Point2D
00242  */
00243 template<typename T> inline
00244 Point2D<T> operator-(const Point2D<T>& a, const Vector2D<T>& b)
00245 {
00246     Point2D<T> result(a);
00247     result -= b;
00248     return result;
00249 }
00250 
00251 
00252 
00253 /** @relates lass::prim::Point2D
00254  */
00255 template<typename T> inline
00256 Vector2D<T> operator-(const Point2D<T>& a, const Point2D<T>& b)
00257 {
00258     return Vector2D<T>(a.x - b.x, a.y - b.y);
00259 }
00260 
00261 
00262 
00263 /** @relates lass::prim::Point2D
00264  */
00265 template<typename T> inline
00266 typename Point2D<T>::TValue distance(const Point2D<T>& a, const Point2D<T>& b)
00267 {
00268     const Vector2D<T> difference = a - b;
00269     return difference.norm();
00270 }
00271 
00272 /** @relates lass::prim::Point2D
00273  */
00274 template<typename T> inline
00275 typename Point2D<T>::TValue squaredDistance(const Point2D<T>& a, const Point2D<T>& b)
00276 {
00277     const Vector2D<T> difference = a - b;
00278     return difference.squaredNorm();
00279 }
00280 
00281 
00282 /** return a point with, for each coordinate, the minimum value of a and b
00283  *  @relates lass::prim::Point2D
00284  */
00285 template<typename T>
00286 Point2D<T> pointwiseMin(const Point2D<T>& a, const Point2D<T>& b)
00287 {
00288     return Point2D<T>(std::min(a.x, b.x), std::min(a.y, b.y));
00289 }
00290 
00291 
00292 
00293 /** return a point with, for each coordinate, the maximum value of a and b
00294  *  @relates lass::prim::Point2D
00295  */
00296 template<typename T>
00297 Point2D<T> pointwiseMax(const Point2D<T>& a, const Point2D<T>& b)
00298 {
00299     return Point2D<T>(std::max(a.x, b.x), std::max(a.y, b.y));
00300 }
00301 
00302 
00303 
00304 /** interpolate linearly between two points: a + t * (b - a)
00305  *  @relates lass::prim::Point2D
00306  */
00307 template<typename T>
00308 inline Point2D<T> lerp(const Point2D<T>& a, const Point2D<T>& b, typename Point2D<T>::TParam t)
00309 {
00310     return Point2D<T>(lerp(a.position(), b.position(), t));
00311 }
00312 
00313 
00314 
00315 /** @relates lass::prim::Point2D
00316  */
00317 template<typename T>
00318 std::ostream& operator<<(std::ostream& stream, const Point2D<T>& b)
00319 {
00320     LASS_ENFORCE_STREAM(stream) << b.position();
00321     return stream;
00322 }
00323 
00324 
00325 
00326 /** @relates lass::prim::Point2D
00327  */
00328 template<typename T>
00329 io::XmlOStream& operator<<(io::XmlOStream& stream, const Point2D<T>& b)
00330 {
00331     LASS_ENFORCE_STREAM(stream)
00332         << "<Point2D>" << b.x << " " << b.y << "</Point2D>\n";
00333     return stream;
00334 }
00335 
00336 
00337 
00338 /** @relates lass::prim::Point2D
00339  */
00340 template<typename T>
00341 lass::io::MatlabOStream& operator<<(lass::io::MatlabOStream& stream, const Point2D<T>& b)
00342 {
00343     LASS_ENFORCE_STREAM(stream) << "lasthandle = line(";
00344     stream << b.x << "," << b.y << ",";
00345     stream << "'Color'," << stream.color() << ");\n";
00346     stream << "set(lasthandle,'Marker','o');\n";
00347     stream << "set(lasthandle,'markersize',2);\n";
00348     return stream;
00349 }
00350 
00351 
00352 /** @relates lass::prim::Point2D
00353  */
00354 template<typename T>
00355 std::istream& operator>>(std::istream& stream, Point2D<T>& b)
00356 {
00357     Vector2D<T> temp;
00358     LASS_ENFORCE_STREAM(stream) >> temp;
00359     b = Point2D<T>(temp);
00360     return stream;
00361 }
00362 
00363 /** returns twice signed area of triangle a,b,c
00364  *  @relates lass::prim::Point2D
00365  */
00366 // based on floating point number theory the ordening of computation is optimised
00367 // for floating point or filtered arithmetic
00368 // when T is an exact type, a faster computation could be devised
00369 // see work from Shewchuk, Fortune and Van Wyck
00370 // the basic idea is to translate points a and b by c
00371 template<typename T> inline
00372 T doubleTriangleArea( const Point2D<T>& a, const Point2D<T>& b, const Point2D<T>& c )
00373 {
00374     return perpDot(a-c,b-c);
00375     /* more intuitive (and faster) but less precise version...
00376     const Vector2D<T> a = a.position();
00377     const Vector2D<T> b = b.position();
00378     const Vector2D<T> c = c.position();
00379     return perpDot(b, c) - perpDot(a, c) + perpDot(a, b);
00380     */
00381 }
00382 
00383 // based on floating point number theory the ordening of computation is optimised
00384 // for floating point or filtered arithmetic
00385 // when T is an exact type, a faster computation could be devised
00386 // see work from Shewchuk, Fortune and Van Wyck
00387 // the basic idea is to translate points a and b by c
00388 template<typename T> inline
00389 T preciseDoubleTriangleArea( const Point2D<T>& a, const Point2D<T>& b, const Point2D<T>& c )
00390 {
00391     return perpDot(a-c,b-c);
00392 }
00393 
00394 
00395 
00396 
00397 
00398 /** returns true when the line b->c is counter clockwise oriented with respect to a->b
00399  *  @relates lass::prim::Point2D
00400  */
00401 template<typename T> inline
00402 bool ccw( const Point2D<T>& a, const Point2D<T>& b, const Point2D<T>& c )
00403 {
00404     return  doubleTriangleArea(a,b,c) > T();
00405 }
00406 
00407 /** returns true when the line b->c is clockwise oriented with respect to a->b
00408  *  @relates lass::prim::Point2D
00409  */
00410 template<typename T> inline
00411 bool cw( const Point2D<T>& a, const Point2D<T>& b, const Point2D<T>& c )
00412 {
00413     return  doubleTriangleArea(a,b,c) < T();
00414 }
00415 
00416 
00417 /** returns true when the line b->c is counter clockwise oriented with respect to a->b.
00418  *  When c is in line of a and b also returns true.
00419  *  @relates lass::prim::Point2D
00420  */
00421 template<typename T> inline
00422 bool weakCcw( const Point2D<T>& a, const Point2D<T>& b, const Point2D<T>& c )
00423 {
00424     return  doubleTriangleArea(a,b,c) >= T();
00425 }
00426 
00427 /** returns true when the line b->c is counter clockwise oriented with respect to a->b.
00428  *  When c is in line of a and b also returns true.
00429  *  @relates lass::prim::Point2D
00430  */
00431 template<typename T> inline
00432 bool weakCw( const Point2D<T>& a, const Point2D<T>& b, const Point2D<T>& c )
00433 {
00434     return  doubleTriangleArea(a,b,c) <= T();
00435 }
00436 
00437 /** returns true when the point d is strictly (within numerical precision) in the circle
00438  *  going through a, b and c.
00439  *  @relates lass::prim::Point2D
00440  *  @note this test is used for establishing Delaunay neighborhoods and this tests
00441  *        numerical stability determines the overall stability of the Delaunay meshers
00442  */
00443 template<typename T>
00444 bool inCircle( const Point2D<T>& a, const Point2D<T>& b, const Point2D<T>& c, const Point2D<T>& d )
00445 {
00446     const T az = a.position().squaredNorm();
00447     const T bz = b.position().squaredNorm();
00448     const T cz = c.position().squaredNorm();
00449     const T dz = d.position().squaredNorm();
00450 
00451     T det = (az * doubleTriangleArea(b, c, d) - bz * doubleTriangleArea(a, c, d)
00452         +    cz * doubleTriangleArea(a, b, d) - dz * doubleTriangleArea(a, b, c));
00453 
00454     return (det > T(0));
00455 }
00456 
00457 
00458 }
00459 
00460 }
00461 
00462 #endif

Generated on Mon Nov 10 14:21:00 2008 for Library of Assembled Shared Sources by doxygen 1.5.7.1
SourceForge.net Logo