glc_geomtools.cpp

Go to the documentation of this file.
00001 /****************************************************************************
00002 
00003  This file is part of the GLC-lib library.
00004  Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net)
00005  http://glc-lib.sourceforge.net
00006 
00007  GLC-lib is free software; you can redistribute it and/or modify
00008  it under the terms of the GNU Lesser General Public License as published by
00009  the Free Software Foundation; either version 3 of the License, or
00010  (at your option) any later version.
00011 
00012  GLC-lib is distributed in the hope that it will be useful,
00013  but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  GNU Lesser General Public License for more details.
00016 
00017  You should have received a copy of the GNU Lesser General Public License
00018  along with GLC-lib; if not, write to the Free Software
00019  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
00020 
00021 *****************************************************************************/
00022 
00024 
00025 #include "glc_geomtools.h"
00026 #include "glc_matrix4x4.h"
00027 
00028 #include <QtGlobal>
00029 
00030 
00031 double glc::comparedPrecision= glc::defaultPrecision;
00032 
00034 //Tools Functions
00036 
00037 // Test if a polygon is convex
00038 bool glc::polygon2DIsConvex(const QList<GLC_Point2d>& vertices)
00039 {
00040         bool isConvex= true;
00041         const int size= vertices.size();
00042         if (vertices.size() > 3)
00043         {
00044                 GLC_Point2d s0(vertices.at(0));
00045                 GLC_Point2d s1(vertices.at(1));
00046                 GLC_Point2d s2(vertices.at(2));
00047                 const bool openAngle= ((s1.getX() - s0.getX()) * (s2.getY() - s0.getY()) - (s2.getX() - s0.getX()) * (s1.getY() - s0.getY())) < 0.0;
00048 
00049                 int i= 3;
00050                 while ((i < size) && isConvex)
00051                 {
00052                         s0= s1;
00053                         s1= s2;
00054                         s2= vertices.at(i);
00055                         isConvex= openAngle == (((s1.getX() - s0.getX()) * (s2.getY() - s0.getY()) - (s2.getX() - s0.getX()) * (s1.getY() - s0.getY())) < 0.0);
00056                         ++i;
00057                 }
00058         }
00059 
00060         return isConvex;
00061 }
00062 
00063 bool glc::polygonIsConvex(QList<GLuint>* pIndexList, const QList<float>& bulkList)
00064 {
00065         bool isConvex= true;
00066         const int size= pIndexList->size();
00067         GLuint currentIndex;
00068         GLC_Vector3d v0;
00069         GLC_Vector3d v1;
00070         int i= 0;
00071         while ((i < size) && isConvex)
00072         {
00073                 currentIndex= pIndexList->at(i);
00074                 v0.setVect(bulkList.at(currentIndex * 3), bulkList.at(currentIndex * 3 + 1), bulkList.at(currentIndex * 3 + 2));
00075                 currentIndex= pIndexList->at((i + 1) % size);
00076                 v1.setVect(bulkList.at(currentIndex * 3), bulkList.at(currentIndex * 3 + 1), bulkList.at(currentIndex * 3 + 2));
00077                 isConvex= (v0.angleWithVect(v1) < glc::PI);
00078                 ++i;
00079         }
00080         return isConvex;
00081 }
00082 // find intersection between two 2D segments
00083 QVector<GLC_Point2d> glc::findIntersection(const GLC_Point2d& s1p1, const GLC_Point2d& s1p2, const GLC_Point2d& s2p1, const GLC_Point2d& s2p2)
00084 {
00085         const GLC_Vector2d D0= s1p2 - s1p1;
00086         const GLC_Vector2d D1= s2p2 - s2p1;
00087         // The QVector of result points
00088         QVector<GLC_Point2d> result;
00089 
00090         const GLC_Vector2d E(s2p1 - s1p1);
00091         double kross= D0 ^ D1;
00092         double sqrKross= kross * kross;
00093         const double sqrLen0= D0.getX() * D0.getX() + D0.getY() * D0.getY();
00094         const double sqrLen1= D1.getX() * D1.getX() + D1.getY() * D1.getY();
00095         // Test if the line are nor parallel
00096         if (sqrKross > (EPSILON * sqrLen0 * sqrLen1))
00097         {
00098                 const double s= (E ^ D1) / kross;
00099                 if ((s < 0.0) || (s > 1.0))
00100                 {
00101                         // Intersection of lines is not a point on segment s1p1 + s * DO
00102                         return result; // Return empty QVector
00103                 }
00104                 const double t= (E ^ D0) / kross;
00105 
00106                 if ((t < 0.0) || (t > 1.0))
00107                 {
00108                         // Intersection of lines is not a point on segment s2p1 + t * D1
00109                         return result; // Return empty QVector
00110                 }
00111 
00112                 // Intersection of lines is a point on each segment
00113                 result << (s1p1 + (D0 * s));
00114                 return result; // Return a QVector of One Point
00115         }
00116 
00117         // Lines of the segments are parallel
00118         const double sqrLenE= E.getX() * E.getX() + E.getY() * E.getY();
00119         kross= E ^ D0;
00120         sqrKross= kross * kross;
00121         if (sqrKross > (EPSILON * sqrLen0 * sqrLenE))
00122         {
00123                 // Lines of the segments are different
00124                 return result; // Return empty QVector
00125         }
00126 
00127         // Lines of the segments are the same. Need to test for overlap of segments.
00128         const double s0= (D0 * E) / sqrLen0;
00129         const double s1= (D0 * D1) / sqrLen0;
00130         const double sMin= qMin(s0, s1);
00131         const double sMax= qMax(s0, s1);
00132         QVector<double> overlaps= findIntersection(0.0, 1.0, sMin, sMax);
00133         const int iMax= overlaps.size();
00134         for (int i= 0; i < iMax; ++i)
00135         {
00136                 result.append(s1p1 + (D0 * overlaps[i]));
00137         }
00138         return result;
00139 }
00140 
00141 // return true if there is an intersection between 2 segments
00142 bool glc::isIntersected(const GLC_Point2d& s1p1, const GLC_Point2d& s1p2, const GLC_Point2d& s2p1, const GLC_Point2d& s2p2)
00143 {
00144         const GLC_Vector2d D0= s1p2 - s1p1;
00145         const GLC_Vector2d D1= s2p2 - s2p1;
00146 
00147         const GLC_Vector2d E(s2p1 - s1p1);
00148         double kross= D0 ^ D1;
00149         double sqrKross= kross * kross;
00150         const double sqrLen0= D0.getX() * D0.getX() + D0.getY() * D0.getY();
00151         const double sqrLen1= D1.getX() * D1.getX() + D1.getY() * D1.getY();
00152         // Test if the line are nor parallel
00153         if (sqrKross > (EPSILON * sqrLen0 * sqrLen1))
00154         {
00155                 const double s= (E ^ D1) / kross;
00156                 if ((s < 0.0) || (s > 1.0))
00157                 {
00158                         // Intersection of lines is not a point on segment s1p1 + s * DO
00159                         return false;
00160                 }
00161                 const double t= (E ^ D0) / kross;
00162 
00163                 if ((t < 0.0) || (t > 1.0))
00164                 {
00165                         // Intersection of lines is not a point on segment s2p1 + t * D1
00166                         return false;
00167                 }
00168 
00169                 // Intersection of lines is a point on each segment
00170                 return true;
00171         }
00172 
00173         // Lines of the segments are parallel
00174         const double sqrLenE= E.getX() * E.getX() + E.getY() * E.getY();
00175         kross= E ^ D0;
00176         sqrKross= kross * kross;
00177         if (sqrKross > (EPSILON * sqrLen0 * sqrLenE))
00178         {
00179                 // Lines of the segments are different
00180                 return false;
00181         }
00182 
00183         // Lines of the segments are the same. Need to test for overlap of segments.
00184         const double s0= (D0 * E) / sqrLen0;
00185         const double s1= s0 + (D0 * D1) / sqrLen0;
00186         const double sMin= qMin(s0, s1);
00187         const double sMax= qMax(s0, s1);
00188         if (findIntersection(0.0, 1.0, sMin, sMax).size() == 0) return false; else return true;
00189 
00190 }
00191 
00192 // return true if there is an intersection between a ray and a segment
00193 bool glc::isIntersectedRaySegment(const GLC_Point2d& s1p1, const GLC_Vector2d& s1p2, const GLC_Point2d& s2p1, const GLC_Point2d& s2p2)
00194 {
00195         const GLC_Vector2d D0= s1p2 - s1p1;
00196         const GLC_Vector2d D1= s2p2 - s2p1;
00197 
00198         const GLC_Vector2d E(s2p1 - s1p1);
00199         double kross= D0 ^ D1;
00200         double sqrKross= kross * kross;
00201         const double sqrLen0= D0.getX() * D0.getX() + D0.getY() * D0.getY();
00202         const double sqrLen1= D1.getX() * D1.getX() + D1.getY() * D1.getY();
00203         // Test if the line are nor parallel
00204         if (sqrKross > (EPSILON * sqrLen0 * sqrLen1))
00205         {
00206                 const double s= (E ^ D1) / kross;
00207                 if ((s < 0.0))
00208                 {
00209                         // Intersection of lines is not a point on segment s1p1 + s * DO
00210                         return false;
00211                 }
00212                 const double t= (E ^ D0) / kross;
00213 
00214                 if ((t < 0.0) || (t > 1.0))
00215                 {
00216                         // Intersection of lines is not a point on segment s2p1 + t * D1
00217                         return false;
00218                 }
00219 
00220                 // Intersection of lines is a point on each segment
00221                 return true;
00222         }
00223 
00224         // Lines of the segments are parallel
00225         const double sqrLenE= E.getX() * E.getX() + E.getY() * E.getY();
00226         kross= E ^ D0;
00227         sqrKross= kross * kross;
00228         if (sqrKross > (EPSILON * sqrLen0 * sqrLenE))
00229         {
00230                 // Lines of are different
00231                 return false;
00232         }
00233         else return true;
00234 
00235 }
00236 
00237 // find intersection of two intervals [u0, u1] and [v0, v1]
00238 QVector<double> glc::findIntersection(const double& u0, const double& u1, const double& v0, const double& v1)
00239 {
00240         //Q_ASSERT((u0 < u1) and (v0 < v1));
00241         QVector<double> result;
00242         if (u1 < v0 || u0 > v1) return result; // Return empty QVector
00243 
00244         if (u1 > v0)
00245         {
00246                 if (u0 < v1)
00247                 {
00248                         if (u0 < v0) result.append(v0); else result.append(u0);
00249                         if (u1 > v1) result.append(v1); else result.append(u1);
00250                         return result;
00251                 }
00252                 else // u0 == v1
00253                 {
00254                         result.append(u0);
00255                         return result;
00256                 }
00257         }
00258         else // u1 == v0
00259         {
00260                 result.append(u1);
00261                 return result;
00262         }
00263 }
00264 
00265 // return true if the segment is in polygon cone
00266 bool glc::segmentInCone(const GLC_Point2d& V0, const GLC_Point2d& V1, const GLC_Point2d& VM, const GLC_Point2d& VP)
00267 {
00268         // assert: VM, V0, VP are not collinear
00269         const GLC_Vector2d diff(V1 - V0);
00270         const GLC_Vector2d edgeL(VM - V0);
00271         const GLC_Vector2d edgeR(VP - V0);
00272         if ((edgeR ^ edgeL) > 0)
00273         {
00274                 // Vertex is convex
00275                 return (((diff ^ edgeR) < 0.0) && ((diff ^ edgeL) > 0.0));
00276         }
00277         else
00278         {
00279                 // Vertex is reflex
00280                 return (((diff ^ edgeR) < 0.0) || ((diff ^ edgeL) > 0.0));
00281         }
00282 }
00283 
00284 // Return true if the segment is a polygon diagonal
00285 bool glc::isDiagonal(const QList<GLC_Point2d>& polygon, const int i0, const int i1)
00286 {
00287         const int size= polygon.size();
00288         int iM= (i0 - 1) % size;
00289         if (iM < 0) iM= size - 1;
00290         int iP= (i0 + 1) % size;
00291 
00292         if (!segmentInCone(polygon[i0], polygon[i1], polygon[iM], polygon[iP]))
00293         {
00294                 return false;
00295         }
00296 
00297         int j0= 0;
00298         int j1= size - 1;
00299         // test segment <polygon[i0], polygon[i1]> to see if it is a diagonal
00300         while (j0 < size)
00301         {
00302                 if (j0 != i0 && j0 != i1 && j1 != i0 && j1 != i1)
00303                 {
00304                         if (isIntersected(polygon[i0], polygon[i1], polygon[j0], polygon[j1]))
00305                                 return false;
00306                 }
00307 
00308                 j1= j0;
00309                 ++j0;
00310         }
00311 
00312         return true;
00313 }
00314 
00315 // Triangulate a polygon
00316 void glc::triangulate(QList<GLC_Point2d>& polygon, QList<int>& index, QList<int>& tList)
00317 {
00318         const int size= polygon.size();
00319         if (size == 3)
00320         {
00321                 tList << index[0] << index[1] << index[2];
00322                 return;
00323         }
00324         int i0= 0;
00325         int i1= 1;
00326         int i2= 2;
00327         while(i0 < size)
00328         {
00329                 if (isDiagonal(polygon, i0, i2))
00330                 {
00331                         // Add the triangle before removing the ear.
00332                         tList << index[i0] << index[i1] << index[i2];
00333                         // Remove the ear from polygon and index lists
00334                         polygon.removeAt(i1);
00335                         index.removeAt(i1);
00336                         // recurse to the new polygon
00337                         triangulate(polygon, index, tList);
00338                         return;
00339                 }
00340                 ++i0;
00341                 i1= (i1 + 1) % size;
00342                 i2= (i2 + 1) % size;
00343         }
00344 }
00345 
00346 // return true if the polygon is couterclockwise ordered
00347 bool glc::isCounterclockwiseOrdered(const QList<GLC_Point2d>& polygon)
00348 {
00349         const int size= polygon.size();
00350         int j0= 0;
00351         int j1= size - 1;
00352         // test segment <polygon[i0], polygon[i1]> to see if it is a diagonal
00353         while (j0 < size)
00354         {
00355                 GLC_Vector2d perp((polygon[j0] - polygon[j1]).perp());
00356                 int j2= 0;
00357                 int j3= size - 1;
00358                 bool isIntersect= false;
00359                 // Application of perp vector
00360                 GLC_Point2d moy((polygon[j0] + polygon[j1]) * 0.5);
00361                 while (j2 < size && !isIntersect)
00362                 {
00363                         if(j2 != j0 && j3 != j1)
00364                         {
00365                                 if (isIntersectedRaySegment(moy, (perp + moy), polygon[j2], polygon[j3]))
00366                                         isIntersect= true;
00367                         }
00368                         j3= j2;
00369                         ++j2;
00370                 }
00371                 if(!isIntersect) return false;
00372                 j1= j0;
00373                 ++j0;
00374         }
00375 
00376         return true;
00377 
00378 }
00379 
00380 // Triangulate a no convex polygon
00381 void glc::triangulatePolygon(QList<GLuint>* pIndexList, const QList<float>& bulkList)
00382 {
00383         int size= pIndexList->size();
00384         if (polygonIsConvex(pIndexList, bulkList))
00385         {
00386                 QList<GLuint> indexList(*pIndexList);
00387                 pIndexList->clear();
00388                 for (int i= 0; i < size - 2; ++i)
00389                 {
00390                         pIndexList->append(indexList.at(0));
00391                         pIndexList->append(indexList.at(i + 1));
00392                         pIndexList->append(indexList.at(i + 2));
00393                 }
00394         }
00395         else
00396         {
00397                 // Get the polygon vertice
00398                 QList<GLC_Point3d> originPoints;
00399                 QHash<int, int> indexMap;
00400 
00401                 QList<int> face;
00402                 GLC_Point3d currentPoint;
00403                 int delta= 0;
00404                 for (int i= 0; i < size; ++i)
00405                 {
00406                         const int currentIndex= pIndexList->at(i);
00407                         currentPoint= GLC_Point3d(bulkList.at(currentIndex * 3), bulkList.at(currentIndex * 3 + 1), bulkList.at(currentIndex * 3 + 2));
00408                         if (!originPoints.contains(currentPoint))
00409                         {
00410                                 originPoints.append(GLC_Point3d(bulkList.at(currentIndex * 3), bulkList.at(currentIndex * 3 + 1), bulkList.at(currentIndex * 3 + 2)));
00411                                 indexMap.insert(i - delta, currentIndex);
00412                                 face.append(i - delta);
00413                         }
00414                         else
00415                         {
00416                                 qDebug() << "Multi points";
00417                                 ++delta;
00418                         }
00419                 }
00420                 // Values of PindexList must be reset
00421                 pIndexList->clear();
00422 
00423                 // Update size
00424                 size= size - delta;
00425 
00426                 // Check new size
00427                 if (size < 3) return;
00428 
00429                 //-------------- Change frame to mach polygon plane
00430                         // Compute face normal
00431                         const GLC_Point3d point1(originPoints[0]);
00432                         const GLC_Point3d point2(originPoints[1]);
00433                         const GLC_Point3d point3(originPoints[2]);
00434 
00435                         const GLC_Vector3d edge1(point2 - point1);
00436                         const GLC_Vector3d edge2(point3 - point2);
00437 
00438                         GLC_Vector3d polygonPlaneNormal(edge1 ^ edge2);
00439                         polygonPlaneNormal.normalize();
00440 
00441                         // Create the transformation matrix
00442                         GLC_Matrix4x4 transformation;
00443 
00444                         GLC_Vector3d rotationAxis(polygonPlaneNormal ^ Z_AXIS);
00445                         if (!rotationAxis.isNull())
00446                         {
00447                                 const double angle= acos(polygonPlaneNormal * Z_AXIS);
00448                                 transformation.setMatRot(rotationAxis, angle);
00449                         }
00450 
00451                         QList<GLC_Point2d> polygon;
00452                         // Transform polygon vertexs
00453                         for (int i=0; i < size; ++i)
00454                         {
00455                                 originPoints[i]= transformation * originPoints[i];
00456                                 // Create 2d vector
00457                                 polygon << originPoints[i].toVector2d(Z_AXIS);
00458                         }
00459                         // Create the index
00460                         QList<int> index= face;
00461 
00462                         QList<int> tList;
00463                         const bool faceIsCounterclockwise= isCounterclockwiseOrdered(polygon);
00464 
00465                         if(!faceIsCounterclockwise)
00466                         {
00467                                 //qDebug() << "face Is Not Counterclockwise";
00468                                 const int max= size / 2;
00469                                 for (int i= 0; i < max; ++i)
00470                                 {
00471                                         polygon.swap(i, size - 1 -i);
00472                                         int temp= face[i];
00473                                         face[i]= face[size - 1 - i];
00474                                         face[size - 1 - i]= temp;
00475                                 }
00476                         }
00477 
00478                         triangulate(polygon, index, tList);
00479                         size= tList.size();
00480                         for (int i= 0; i < size; i+= 3)
00481                         {
00482                                 // Avoid normal problem
00483                                 if (faceIsCounterclockwise)
00484                                 {
00485                                         pIndexList->append(indexMap.value(face[tList[i]]));
00486                                         pIndexList->append(indexMap.value(face[tList[i + 1]]));
00487                                         pIndexList->append(indexMap.value(face[tList[i + 2]]));
00488                                 }
00489                                 else
00490                                 {
00491                                         pIndexList->append(indexMap.value(face[tList[i + 2]]));
00492                                         pIndexList->append(indexMap.value(face[tList[i + 1]]));
00493                                         pIndexList->append(indexMap.value(face[tList[i]]));
00494                                 }
00495                         }
00496                         Q_ASSERT(size == pIndexList->size());
00497         }
00498 
00499 }
00500 
00501 bool glc::lineIntersectPlane(const GLC_Line3d& line, const GLC_Plane& plane, GLC_Point3d* pPoint)
00502 {
00503         const GLC_Vector3d n= plane.normal();
00504         const GLC_Point3d p= line.startingPoint();
00505         const GLC_Vector3d d= line.direction();
00506 
00507         const double denominator= d * n;
00508         if (qFuzzyCompare(fabs(denominator), 0.0))
00509         {
00510                 qDebug() << " glc::lineIntersectPlane : Line parallel to the plane";
00511                 // The line is parallel to the plane
00512                 return false;
00513         }
00514         else
00515         {
00516                 // The line intersect the plane by one point
00517                 const double t= -((n * p) + plane.coefD()) / denominator;
00518                 (*pPoint)= p + (t * d);
00519 
00520                 return true;
00521         }
00522 }
00523 
00524 GLC_Point3d glc::project(const GLC_Point3d& point, const GLC_Line3d& line)
00525 {
00526         const GLC_Vector3d lineDirection(line.direction().normalize());
00527         double t= lineDirection * (point - line.startingPoint());
00528         GLC_Point3d projectedPoint= line.startingPoint() + (t * lineDirection);
00529         return projectedPoint;
00530 }
00531 
00532 double glc::pointLineDistance(const GLC_Point3d& point, const GLC_Line3d& line)
00533 {
00534         const GLC_Vector3d lineDirection(line.direction().normalize());
00535         double t= lineDirection * (point - line.startingPoint());
00536         GLC_Point3d projectedPoint= line.startingPoint() + (t * lineDirection);
00537         return (point - projectedPoint).length();
00538 }
00539 
00540 bool glc::pointsAreCollinear(const GLC_Point3d& p1, const GLC_Point3d& p2, const GLC_Point3d& p3)
00541 {
00542         bool subject= false;
00543         if (compare(p1, p2) || compare(p1, p3) || compare(p2, p3))
00544         {
00545                 subject= true;
00546         }
00547         else
00548         {
00549                 GLC_Vector3d p1p2= (p2 - p1).setLength(1.0);
00550                 GLC_Vector3d p2p3= (p3 - p2).setLength(1.0);
00551                 subject= (compare(p1p2, p2p3)  || compare(p1p2, p2p3.inverted()));
00552         }
00553         return subject;
00554 }
00555 
00556 bool glc::compare(double p1, double p2)
00557 {
00558         return qAbs(p1 - p2) <= comparedPrecision;
00559 }
00560 
00561 bool glc::compareAngle(double p1, double p2)
00562 {
00563         const double anglePrecision= toRadian(comparedPrecision);
00564         return qAbs(p1 - p2) <= anglePrecision;
00565 }
00566 
00567 bool glc::compare(const GLC_Vector3d& v1, const GLC_Vector3d& v2)
00568 {
00569         bool compareResult= (qAbs(v1.x() - v2.x()) <= comparedPrecision);
00570         compareResult= compareResult && (qAbs(v1.y() - v2.y()) <= comparedPrecision);
00571         compareResult= compareResult && (qAbs(v1.z() - v2.z()) <= comparedPrecision);
00572 
00573         return compareResult;
00574 }
00575 
00576 bool glc::compare(const GLC_Vector2d& v1, const GLC_Vector2d& v2)
00577 {
00578         bool compareResult= (qAbs(v1.getX() - v2.getX()) <= comparedPrecision);
00579         return compareResult && (qAbs(v1.getY() - v2.getY()) <= comparedPrecision);
00580 }
00581 
00582 bool glc::compare(const QPointF& v1, const QPointF& v2)
00583 {
00584         bool compareResult= (qAbs(v1.x() - v2.x()) <= comparedPrecision);
00585         return compareResult && (qAbs(v1.y() - v2.y()) <= comparedPrecision);
00586 }
00587 
00588 bool glc::pointInPolygon(const GLC_Point2d& point, const QList<GLC_Point2d>& polygon)
00589 {
00590         const int polygonSize= polygon.size();
00591         bool inside= false;
00592         int i= 0;
00593         int j= polygonSize - 1;
00594 
00595         while (i < polygonSize)
00596         {
00597                 const GLC_Point2d point0= polygon.at(i);
00598                 const GLC_Point2d point1= polygon.at(j);
00599                 if (point.getY() < point1.getY())
00600                 {
00601                         //point1 above ray
00602                         if (point0.getY() <= point.getY())
00603                         {
00604                                 //point2 on or below ray
00605                                 const double val1= (point.getY() - point0.getY()) * (point1.getX() - point0.getX());
00606                                 const double val2= (point.getX() - point0.getX()) * (point1.getY() - point0.getY());
00607                                 if (val1 > val2) inside= !inside;
00608                         }
00609                 }
00610                 else if (point.getY() < point0.getY())
00611                 {
00612                         // point 1 on or below ray, point0 above ray
00613                         const double val1= (point.getY() - point0.getY()) * (point1.getX() - point0.getX());
00614                         const double val2= (point.getX() - point0.getX()) * (point1.getY() - point0.getY());
00615                         if (val1 < val2) inside= !inside;
00616                 }
00617                 j= i;
00618                 ++i;
00619         }
00620         return inside;
00621 }
00622 
00623 double glc::zeroTo2PIAngle(double angle)
00624 {
00625         if (qFuzzyCompare(fabs(angle), glc::PI))
00626         {
00627                 angle= glc::PI;
00628         }
00629         else if (angle < 0)
00630         {
00631                 angle= (2.0 * glc::PI) + angle;
00632         }
00633         return angle;
00634 }

SourceForge.net Logo

©2005-2011 Laurent Ribon