library of assembled shared sources

http://lass.cocamware.com

simple_polygon_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 #ifndef LASS_GUARDIAN_OF_INCLUSION_PRIM_SIMPLE_POLYGON_2D_INL
00044 #define LASS_GUARDIAN_OF_INCLUSION_PRIM_SIMPLE_POLYGON_2D_INL
00045 
00046 #include "prim_common.h"
00047 #include "simple_polygon_2d.h"
00048 
00049 namespace lass
00050 {
00051 namespace prim
00052 {
00053 
00054 // --- public --------------------------------------------------------------------------------------
00055 
00056 template <typename T, class DP>
00057 SimplePolygon2D<T, DP>::SimplePolygon2D():
00058     vertices_()
00059 {
00060 }
00061 
00062 
00063 
00064 template <typename T, class DP>
00065 template <typename InputIterator>
00066 SimplePolygon2D<T, DP>::SimplePolygon2D(InputIterator iFirstVertex, InputIterator iLastVertex):
00067     vertices_(iFirstVertex, iLastVertex)
00068 {
00069 }
00070 
00071 
00072 
00073 /** return vertex of polygon by its index, not wrapped, no bounds check.
00074  */
00075 template <typename T, class DP>
00076 const typename SimplePolygon2D<T, DP>::TPoint&
00077 SimplePolygon2D<T, DP>::operator[](size_t iIndexOfVertex) const
00078 {
00079     LASS_ASSERT(iIndexOfVertex < vertices_.size());
00080     return vertices_[iIndexOfVertex];
00081 }
00082 
00083 
00084 
00085 /** return vertex of polygon by its index, not wrapped, no bounds check.
00086  */
00087 template <typename T, class DP>
00088 typename SimplePolygon2D<T, DP>::TPoint&
00089 SimplePolygon2D<T, DP>::operator[](size_t iIndexOfVertex)
00090 {
00091     LASS_ASSERT(iIndexOfVertex < vertices_.size());
00092     return vertices_[iIndexOfVertex];
00093 }
00094 
00095 
00096 
00097 /** return vertex of polygon by its index, but wrap around the bounds.
00098  *  this->at(-1) will return the same vertex as this->at(this->size() - 1);
00099  *  @throw an exception is thrown if polygon is empty
00100  */
00101 template <typename T, class DP>
00102 const typename SimplePolygon2D<T, DP>::TPoint&
00103 SimplePolygon2D<T, DP>::at(int iIndexOfVertex) const
00104 {
00105     LASS_ENFORCE(!isEmpty());
00106     const int i = num::mod(iIndexOfVertex, static_cast<unsigned>(vertices_.size()));
00107     LASS_ASSERT(isInRange(i));
00108     return vertices_[i];
00109 }
00110 
00111 
00112 
00113 /** return vertex of polygon by its index, but wrap around the bounds.
00114  *  this->at(-1) will return the same vertex as this->at(this->size() - 1);
00115  *  @throw an exception is thrown if polygon is empty
00116  */
00117 template <typename T, class DP>
00118 typename SimplePolygon2D<T, DP>::TPoint&
00119 SimplePolygon2D<T, DP>::at(int iIndexOfVertex)
00120 {
00121     LASS_ENFORCE(!isEmpty());
00122     const int i = num::mod(iIndexOfVertex, static_cast<unsigned>(vertices_.size()));
00123     LASS_ASSERT(isInRange(i));
00124 
00125     return vertices_[i];
00126 }
00127 
00128 
00129 
00130 /** return the edge of the polygon between vertices at(iIndex) and at(iIndex + 1).
00131  *  @throw an exception is thrown if polygon has less than two vertices
00132  */
00133 template <typename T, class DP>
00134 const typename SimplePolygon2D<T, DP>::TLineSegment
00135 SimplePolygon2D<T, DP>::edge(int iIndexOfTailVertex) const
00136 {
00137     DP::enforceEdge(*this, iIndexOfTailVertex);
00138     return TLineSegment(at(iIndexOfTailVertex), at(iIndexOfTailVertex + 1));
00139 }
00140 
00141 
00142 
00143 /** return the vector between vertices at(iIndex) and at(iIndex + 1)\
00144  */
00145 template <typename T, class DP>
00146 const typename SimplePolygon2D<T, DP>::TVector
00147 SimplePolygon2D<T, DP>::vector(int iIndexOfTailVertex) const
00148 {
00149     DP::enforceEdge(*this, iIndexOfTailVertex);
00150     return at(iIndexOfTailVertex + 1) - at(iIndexOfTailVertex);
00151 }
00152 
00153 
00154 
00155 /** add a point at the "end" of the vertex list.
00156  *  this is almost the same as <tt>insert(0, iVertex)</tt> with the difference that
00157  *  <tt>add(iVertex)</tt> is also valid for empty polygons.
00158  */
00159 template <typename T, class DP>
00160 void SimplePolygon2D<T, DP>::add(const TPoint& iVertex)
00161 {
00162     vertices_.push_back(iVertex);
00163 }
00164 
00165 
00166 /** insert a vertex at iIndex (so it will sit before the current at(iIndex)).
00167  */
00168 template <typename T, class DP>
00169 void SimplePolygon2D<T, DP>::insert(int iIndexOfVertex, const TPoint& iVertex)
00170 {
00171     LASS_ENFORCE(!isEmpty());
00172 
00173     const int i = num::mod(iIndexOfVertex, static_cast<unsigned>(vertices_.size()));
00174     LASS_ASSERT(isInRange(i));
00175     vertices_.insert(vertices_.begin() + i, iVertex);
00176 }
00177 
00178 
00179 
00180 /** remove the vertex at(iIndex)
00181  */
00182 template <typename T, class DP>
00183 void SimplePolygon2D<T, DP>::erase(int iIndexOfVertex)
00184 {
00185     LASS_ENFORCE(!isEmpty());
00186     const int i = num::mod(iIndexOfVertex, static_cast<unsigned>(vertices_.size()));
00187     LASS_ASSERT(isInRange(i));
00188     vertices_.erase(vertices_.begin() + i);
00189 }
00190 
00191 
00192 
00193 /** return true if polygon has no vertices
00194  */
00195 template <typename T, class DP>
00196 const bool SimplePolygon2D<T, DP>::isEmpty() const
00197 {
00198     return vertices_.empty();
00199 }
00200 
00201 
00202 
00203 /** return number of vertices
00204  */
00205 template <typename T, class DP>
00206 const size_t SimplePolygon2D<T, DP>::size() const
00207 {
00208     return vertices_.size();
00209 }
00210 
00211 
00212 
00213 /** return signed polygon area.
00214  *
00215  *  <i>The area of a convex polygon is defined to be positive if the points are arranged in a
00216  *  counterclockwise order, and negative if they are in clockwise order.</i>,
00217  *  Eric W. Weisstein. "Polygon Area." From MathWorld--A Wolfram Web Resource. 
00218  *  http://mathworld.wolfram.com/PolygonArea.html 
00219  *
00220  *  @par Algorithm:
00221  *  comp.graphics.algorithms Frequently Asked Questions: 
00222  *  Subject 2.01: "How do I find the area of a polygon?"
00223  *  http://www.faqs.org/faqs/graphics/algorithms-faq/
00224  *
00225  *  @warning polygon must be simple accoring degenerate policy.
00226  */
00227 template <typename T, class DP>
00228 const typename SimplePolygon2D<T, DP>::TValue
00229 SimplePolygon2D<T, DP>::signedArea() const
00230 {
00231     DP::enforceSimple(*this);
00232 
00233     if (size() < 3)
00234     {
00235         return TNumTraits::zero;
00236     }
00237 
00238     TValue result = TNumTraits::zero;
00239     const size_t n = size();
00240     for (size_t prevI = n - 1, i = 0; i < n; prevI = i++)
00241     {
00242         result += perpDot(vertices_[prevI].position(), vertices_[i].position());
00243     }
00244     return result / T(2);
00245 }
00246 
00247 
00248 
00249 /** return area of the polygons surface.
00250  *
00251  *  <i>The area of a surface is the amount of material needed to "cover" it completely</i>,
00252  *  Eric W. Weisstein. "Area." From MathWorld--A Wolfram Web Resource.
00253  *  http://mathworld.wolfram.com/Area.html
00254  *
00255  *  @warning polygon must be simple accoring @a DegeneratePolicy.
00256  */
00257 template <typename T, class DP>
00258 const typename SimplePolygon2D<T, DP>::TValue
00259 SimplePolygon2D<T, DP>::area() const
00260 {
00261     return num::abs(signedArea()); // DP::enforceSimple(*this);
00262 }
00263 
00264 
00265 
00266 /** return orientation of polygon.
00267  *
00268  *  @warning polygon must be simple accoring @a DegeneratePolicy.
00269  */
00270 template <typename T, class DP>
00271 const Orientation SimplePolygon2D<T, DP>::orientation() const
00272 {
00273     const TValue signArea = TDegeneratePolicy::enforceNonZeroSignedArea(*this); // DP::enforceSimple(*this);
00274     return signArea == TNumTraits::zero ? oInvalid :
00275         (signArea < TNumTraits::zero ? oClockWise : oCounterClockWise);
00276 }
00277 
00278 
00279 
00280 /** return sum of the lengths of all edges
00281  */
00282 template <typename T, class DP>
00283 const typename SimplePolygon2D<T, DP>::TValue
00284 SimplePolygon2D<T, DP>::perimeter() const
00285 {
00286     TValue result = TNumTraits::zero;
00287     const size_t n = size();
00288     for (size_t prevI = n - 1, i = 0; i < n; prevI = i++)
00289     {
00290         result += distance(vertices_[prevI], vertices_[i]);
00291     }
00292     return result;
00293 }
00294 
00295 
00296 
00297 /** return the barycenter of all vertices.
00298  *  The vertex centroid is the homogenous sum of all vertices.
00299  *
00300  *  @warning for non-convex polygons, it's NOT guaranteed that this center is inside the polygon.
00301  */
00302 template <typename T, class DP>
00303 const typename SimplePolygon2D<T, DP>::TPointH
00304 SimplePolygon2D<T, DP>::vertexCentroid() const
00305 {
00306     TPointH result;
00307     const size_t n = size();
00308     for (size_t i = 0; i < n; ++i)
00309     {
00310         result += vertices_[i];
00311     }
00312     return result;
00313 }
00314 
00315 
00316 
00317 /** return the centroid of the filled polygon.
00318  *
00319  *  Eric W. Weisstein. "Geometric Centroid." From MathWorld--A Wolfram Web Resource. 
00320  *  http://mathworld.wolfram.com/GeometricCentroid.html
00321  *
00322  *  @par Algorithm:
00323  *  comp.graphics.algorithms Frequently Asked Questions: 
00324  *  Subject 2.02: "How can the centroid of a polygon be computed?"
00325  *  http://www.faqs.org/faqs/graphics/algorithms-faq/
00326  *
00327  *  @warning for non-convex polygons, it's NOT guaranteed that this center is inside the polygon.
00328  */
00329 template <typename T, class DP>
00330 const typename SimplePolygon2D<T, DP>::TPointH
00331 SimplePolygon2D<T, DP>::surfaceCentroid() const
00332 {
00333     const size_t n = size();
00334     if (n < 3)
00335     {
00336         return vertexCentroid();
00337     }
00338 
00339     TPointH result;
00340     for (size_t prevI = n - 1, i = 0; i < n; prevI = i++)
00341     {
00342         const TValue triangleWeight = perpDot(vertices_[prevI].position(), vertices_[i].position());
00343         const TPointH triangleCenter = vertices_[prevI] + vertices_[i] + TPoint();
00344         result += triangleWeight * triangleCenter;
00345     }
00346     return result;
00347 }
00348 
00349 
00350 
00351 /** return true if polygon is simple, false if not.
00352  *
00353  *  <i>A polygon P is said to be simple (or Jordan) if the only points of the plane belonging to
00354  *  two polygon edges of P are the polygon vertices of P. Such a polygon has a well defined
00355  *  interior and exterior. Simple polygons are topologically equivalent to a disk.</i>,
00356  *  Eric W. Weisstein. "Simple Polygon." From MathWorld--A Wolfram Web Resource. 
00357  *  http://mathworld.wolfram.com/SimplePolygon.html 
00358  *
00359  *  A polygon with less than four vertices is always simple.
00360  *
00361  *  @warning this is a brute force test.  we simple test for all edges if they are not intersecting
00362  *           Hence, this is O(n^2).
00363  */
00364 template <typename T, class DP>
00365 const bool SimplePolygon2D<T, DP>::isSimple() const
00366 {
00367     const int n = static_cast<int>(size());
00368     LASS_ASSERT(n >= 0);
00369     if (n < 4)
00370     {
00371         return true;
00372     }
00373 
00374     for (int i = 0; i < n; ++i)
00375     {
00376         const TLineSegment e = edge(i);
00377         TValue t1;
00378         TValue t2;
00379         if (intersect(e, edge(i + 1), t1, t2) != rOne)
00380         {
00381             return false;
00382         }
00383         for (int j = i + 2; j < n - 1; ++j)
00384         {
00385             if (intersect(e, edge(j), t1, t2) != rNone)
00386             {
00387                 return false;
00388             }
00389         }
00390         if (i != 0 && intersect(e, edge(n - 1), t1, t2) != rOne)
00391         {
00392             return false;
00393         }
00394     }
00395 
00396     return true;
00397 }
00398 
00399 
00400 
00401 /** return true if polygon is convex, false if not.
00402  *
00403  *  <i>A planar polygon is convex if it contains all the line segments connecting any pair of its
00404  *  points. Thus, for example, a regular pentagon is convex, while an indented pentagon is not.
00405  *  A planar polygon that is not convex is said to be a concave polygon</i>,
00406  *  Eric W. Weisstein. "Convex Polygon." From MathWorld--A Wolfram Web Resource. 
00407  *  http://mathworld.wolfram.com/ConvexPolygon.html 
00408  *
00409  *  A simple polygon is convex if all the cross products of adjacent edges will be the same sign
00410  *  (we ignore zero cross products of colinear edges, only + or - are taken in account), a concave polygon
00411  *  will have a mixture of cross product signs.
00412  *
00413  *  A polygon with less than three vertices is always convex.  A polygon with all coincident.
00414  *  vertices is considered convex if DegeneratePolicy allows this.
00415  *
00416  *  @warning polygon must be simple and should not have coincident vertices, according
00417  *           @a DegeneratePolicy.
00418  */
00419 template <typename T, class DP>
00420 const bool SimplePolygon2D<T, DP>::isConvex() const
00421 {
00422     DP::enforceSimple(*this);
00423 
00424     const int n = static_cast<int>(size());
00425     LASS_ASSERT(n >= 0);
00426     if (n < 3)
00427     {
00428         return true;
00429     }
00430 
00431     TValue sign = TNumTraits::zero;
00432     for (int i = 0; i < n; ++i)
00433     {
00434         const TValue s = num::sign(perpDot(vector(i - 1), vector(i))); // Ax(-B) = BxA
00435         if (sign != s && s != TNumTraits::zero)
00436         {
00437             if (sign == TNumTraits::zero)
00438             {
00439                 sign = s;
00440             }
00441             else
00442             {
00443                 return false;
00444             }
00445         }
00446     }
00447 
00448     return true;
00449 }
00450 
00451 
00452 
00453 /** return true if inner angle of vertex is reflex (is > 180 degrees).
00454  *
00455  *  <i>Reflect Angle: An angle more than 180°</i>,
00456  *  Eric W. Weisstein. "Reflex Angle." From MathWorld--A Wolfram Web Resource. 
00457  *  http://mathworld.wolfram.com/ReflexAngle.html 
00458  *
00459  *  test if signedArea() and perdDot(...) have different sign.
00460  *  if one of them is zero, it will return false by default.
00461  *
00462  *  @warning polygon must be simple accoring @a DegeneratePolicy.
00463  */
00464 template <typename T, class DP>
00465 const bool SimplePolygon2D<T, DP>::isReflex(int iIndexOfVertex) const
00466 {
00467     DP::enforceSimple(*this);
00468 
00469     const TValue pd = perpDot(vector(iIndexOfVertex - 1), vector(iIndexOfVertex)); // Ax(-B) = BxA
00470     LASS_ASSERT(!isEmpty()); // vector(i) should enforce this
00471     return signedArea() * pd < TNumTraits::zero;
00472 }
00473 
00474 
00475 
00476 /** return true when a point is inside or on a polygon.
00477  *
00478  *  When a point lies on a polygon edge the answer can either be true or false but in a way that
00479  *  for a meshing the answer will only be true for one polygon.  More precise: for polygons sharing
00480  *  an edge only one of them will return true for a point on the edge.
00481  *  For an explanation of how this exactly works:
00482  *  http://www.ecse.rpi.edu/Homepages/wrf/geom/pnpoly.html (Wm Randolph Franklin)
00483  *
00484  *  @par Algorithm:
00485  *  comp.graphics.algorithms Frequently Asked Questions: 
00486  *  Subject 2.03: "How do I find if a point lies within a polygon?"
00487  *  http://www.faqs.org/faqs/graphics/algorithms-faq/
00488  */
00489 template <typename T, class DP>
00490 const bool SimplePolygon2D<T, DP>::contains(const TPoint& iP) const
00491 {
00492     size_t i, j;
00493     const TVector& p = iP.position();
00494     bool c = false;
00495     const size_t npol = size();
00496     for (i = 0, j = npol-1; i < npol; j = i++)
00497     {
00498         const TVector& a = vertices_[i].position();
00499         const TVector& b = vertices_[j].position();
00500         if (((a.y <= p.y && p.y < b.y) || (b.y <= p.y && p.y < a.y)) &&
00501             p.x < (b.x - a.x) * (p.y - a.y) / (b.y - a.y) + a.x)
00502         {
00503             c = !c;
00504         }
00505     }
00506     return c;
00507 }
00508 
00509 
00510 
00511 template <typename T, class DP>
00512 const Side SimplePolygon2D<T, DP>::classify(const TPoint& iP) const
00513 {
00514     return contains(iP) ? sInside : sOutside;
00515 }
00516 
00517 
00518 
00519 /** flip orientation of polygon.
00520  */
00521 template <typename T, class DP>
00522 void SimplePolygon2D<T, DP>::flip()
00523 {
00524     std::reverse(vertices_.begin(), vertices_.end());
00525 }
00526 
00527 
00528 
00529 /** fixes degenerate polygons as far as possible.
00530  *
00531  *  things that can be repared are:
00532  *  - coincident vertices: if two or more adjacent vertices are coincident, they can be reduced to
00533  *                         one vertex.
00534  *  - colinear edges: if two or more adjacent edges are colinear, they can be merged to one edge.
00535  *  - zero area: if a polygon has no area, this is pretty much the same as an @a empty polygon.
00536  *               All vertices will be removed.
00537  *
00538  *  Things that can't repared (and will cause an exception to be thrown) are:
00539  *  - non-simple polygons: there's no way we can repare polygons that are not simple, so we don't
00540  *                         even try to!  An exception is thrown regardless the @a DegeneratePolicy.
00541  */
00542 template <typename T, class DP>
00543 void SimplePolygon2D<T, DP>::fixDegenerate()
00544 {
00545     // remove coincident vertices
00546     //
00547     int i = 0;
00548     while (i < size())
00549     {
00550         if (at(i) == at(i + 1))
00551         {
00552             erase(i);
00553         }
00554         else
00555         {
00556             ++i;
00557         }
00558     }
00559 
00560     // merge colinear edges
00561     //
00562     while (size() > 2 && i < size())
00563     {
00564         if (perpDot(vector(i - 1), vector(i)) == TNumTraits::zero)
00565         {
00566             erase(i);
00567         }
00568         else
00569         {
00570             ++i;
00571         }
00572     }
00573 
00574     // by now there are no coincident points that can trigger policy predicates in @c isSimple()
00575     // so exceptions are not thrown before we get the change to fix it.
00576     //
00577     LASS_ENFORCE(isSimple());
00578 
00579     // check zero area of polygons in two ways: literally, and by the knowledge that less than
00580     // three vertices is zero area for sure.
00581     //
00582     if (size() < 3 || signedArea() == TNumTraits::zero)
00583     {
00584         vertices_.clear();
00585     }
00586 }
00587 
00588 
00589 
00590 /** a simple polygon is valid if it is not degenerate.
00591  */
00592 template <typename T, class DP>
00593 const bool SimplePolygon2D<T, DP>::isValid() const
00594 {
00595     return size() >= 3 && isSimple() && signedArea() != TNumTraits::zero;
00596 }
00597 
00598 
00599 
00600 // --- protected -----------------------------------------------------------------------------------
00601 
00602 
00603 
00604 // --- private -------------------------------------------------------------------------------------
00605 
00606 /** return if index of vertex is in range of the std::vector
00607  */
00608 template <typename T, class DP>
00609 const bool SimplePolygon2D<T, DP>::isInRange(int iIndexOfVertex) const
00610 {
00611     LASS_ASSERT(static_cast<int>(size()) >= 0);
00612     return iIndexOfVertex >= 0 && iIndexOfVertex < static_cast<int>(size());
00613 }
00614 
00615 
00616 
00617 // --- free ----------------------------------------------------------------------------------------
00618 
00619 /** @relates lass::prim::SimplePolygon2D
00620  */
00621 template <typename T, class DP>
00622 io::XmlOStream& operator<<(io::XmlOStream& ioOStream, const SimplePolygon2D<T, DP>& iPolygon)
00623 {
00624     const size_t n = iPolygon.size();
00625     LASS_ENFORCE_STREAM(ioOStream) << "<SimplePolygon2D>\n";
00626     for (size_t i = 0; i < n; ++i)
00627     {
00628         ioOStream << "<vertex id='" << static_cast<unsigned long>(i) << "'>" << iPolygon[i] << "</vertex>\n";
00629     }
00630     ioOStream << "</SimplePolygon2D>\n";
00631     return ioOStream;
00632 }
00633 
00634 
00635 /** @relates lass::prim::SimplePolygon2D
00636  */
00637 template <typename T, class DP>
00638 std::ostream& operator<<(std::ostream& ioOStream, const SimplePolygon2D<T, DP>& iPolygon)
00639 {
00640     const size_t n = iPolygon.size();
00641     LASS_ENFORCE_STREAM(ioOStream) << "{";
00642     if (n > 0)
00643     {
00644         ioOStream << iPolygon[0];
00645     }   
00646     for (size_t i = 1; i < n; ++i)
00647     {
00648         ioOStream << ", " << iPolygon[i];
00649     }
00650     ioOStream << "}";
00651     return ioOStream;
00652 }
00653 
00654 /** @relates lass::prim::SimplePolygon2D
00655  */
00656 template <typename T, class DP>
00657 lass::io::MatlabOStream& operator<<(lass::io::MatlabOStream& oOStream,
00658                                     const SimplePolygon2D<T, DP>& iPolygon)
00659 {
00660     LASS_ENFORCE_STREAM(oOStream) << "lasthandle = patch(";
00661     oOStream << "[" << iPolygon[0].x;
00662     for (size_t i=1;i<iPolygon.size();++i)
00663         oOStream << "," << iPolygon[i].x;
00664     oOStream << "],";
00665     oOStream << "[" << iPolygon[0].y;
00666     for (size_t i=1;i<iPolygon.size();++i)
00667         oOStream << "," << iPolygon[i].y;
00668     oOStream << "],";
00669     oOStream << "'Color'," << oOStream.color() << ");\n";
00670     return oOStream;
00671 }
00672 
00673 
00674 }
00675 
00676 }
00677 
00678 #endif
00679 
00680 // EOF

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