Commit eb22bf42 authored by jean-pierre charras's avatar jean-pierre charras

Pcbnew: very minor fixes and update: update clipper version. uncrustify...

Pcbnew: very minor fixes and update:  update clipper version. uncrustify polytri/* and fix some warning compil.
parent 6e56aa2f
......@@ -13,7 +13,7 @@
#ifndef DRW_BASE_H
#define DRW_BASE_H
#define DRW_VERSION "0.5.10"
#define DRW_VERSION "0.5.11"
#include <string>
#include <cmath>
......
......@@ -27,7 +27,7 @@ class dxfRW
public:
dxfRW( const char* name );
~dxfRW();
// / reads the file specified in constructor
/// reads the file specified in constructor
/*!
* An interface must be provided. It is used by the class to signal various
* components being added.
......@@ -71,7 +71,7 @@ public:
void setEllipseParts( int parts ) { elParts = parts; } /*!< set parts munber when convert ellipse to polyline */
private:
// / used by read() to parse the content of the file
/// used by read() to parse the content of the file
bool processDxf();
bool processHeader();
bool processTables();
......
......@@ -88,8 +88,8 @@ CPolyLine::~CPolyLine()
#include "clipper.hpp"
int CPolyLine::NormalizeAreaOutlines( std::vector<CPolyLine*>* aNewPolygonList )
{
ClipperLib::Polygon raw_polygon;
ClipperLib::Polygons normalized_polygons;
ClipperLib::Path raw_polygon;
ClipperLib::Paths normalized_polygons;
unsigned corners_count = m_CornersList.GetCornersCount();
......@@ -115,7 +115,7 @@ int CPolyLine::NormalizeAreaOutlines( std::vector<CPolyLine*>* aNewPolygonList )
// enter main outline
for( unsigned ii = 0; ii < normalized_polygons.size(); ii++ )
{
ClipperLib::Polygon& polygon = normalized_polygons[ii];
ClipperLib::Path& polygon = normalized_polygons[ii];
cornerslist.clear();
for( unsigned jj = 0; jj < polygon.size(); jj++ )
cornerslist.push_back( KI_POLY_POINT( KiROUND( polygon[jj].X ),
......@@ -142,7 +142,7 @@ int CPolyLine::NormalizeAreaOutlines( std::vector<CPolyLine*>* aNewPolygonList )
ClipperLib::SimplifyPolygon( raw_polygon, normalized_polygons );
for( unsigned ii = 0; ii < normalized_polygons.size(); ii++ )
{
ClipperLib::Polygon& polygon = normalized_polygons[ii];
ClipperLib::Path& polygon = normalized_polygons[ii];
cornerslist.clear();
for( unsigned jj = 0; jj < polygon.size(); jj++ )
cornerslist.push_back( KI_POLY_POINT( KiROUND( polygon[jj].X ),
......
This source diff could not be displayed because it is too large. You can view the blob instead.
/*******************************************************************************
* *
* Author : Angus Johnson *
* Version : 5.1.4 *
* Date : 24 March 2013 *
* Version : 6.1.2 *
* Date : 15 December 2013 *
* Website : http://www.angusj.com *
* Copyright : Angus Johnson 2010-2013 *
* *
......@@ -34,11 +34,29 @@
#ifndef clipper_hpp
#define clipper_hpp
#define CLIPPER_VERSION "6.1.2"
//use_int32: When enabled 32bit ints are used instead of 64bit ints. This
//improve performance but coordinate values are limited to the range +/- 46340
//#define use_int32
//use_xyz: adds a Z member to IntPoint. Adds a minor cost to perfomance.
//#define use_xyz
//use_lines: Enables line clipping. Adds a very minor cost to performance.
//#define use_lines
//use_deprecated: Enables support for the obsolete OffsetPaths() function
//which has been replace with the ClipperOffset class.
#define use_deprecated
#include <vector>
#include <set>
#include <stdexcept>
#include <cstring>
#include <cstdlib>
#include <ostream>
#include <functional>
namespace ClipperLib {
......@@ -50,23 +68,64 @@ enum PolyType { ptSubject, ptClip };
//see http://glprogramming.com/red/chapter11.html
enum PolyFillType { pftEvenOdd, pftNonZero, pftPositive, pftNegative };
typedef signed long long long64;
typedef unsigned long long ulong64;
#ifdef use_int32
typedef int cInt;
typedef unsigned int cUInt;
#else
typedef signed long long cInt;
typedef unsigned long long cUInt;
#endif
struct IntPoint {
public:
long64 X;
long64 Y;
IntPoint(long64 x = 0, long64 y = 0): X(x), Y(y) {};
friend std::ostream& operator <<(std::ostream &s, IntPoint &p);
cInt X;
cInt Y;
#ifdef use_xyz
cInt Z;
IntPoint(cInt x = 0, cInt y = 0, cInt z = 0): X(x), Y(y), Z(z) {};
#else
IntPoint(cInt x = 0, cInt y = 0): X(x), Y(y) {};
#endif
friend inline bool operator== (const IntPoint& a, const IntPoint& b)
{
return a.X == b.X && a.Y == b.Y;
}
friend inline bool operator!= (const IntPoint& a, const IntPoint& b)
{
return a.X != b.X || a.Y != b.Y;
}
};
//------------------------------------------------------------------------------
typedef std::vector< IntPoint > Polygon;
typedef std::vector< Polygon > Polygons;
typedef std::vector< IntPoint > Path;
typedef std::vector< Path > Paths;
inline Path& operator <<(Path& poly, const IntPoint& p) {poly.push_back(p); return poly;}
inline Paths& operator <<(Paths& polys, const Path& p) {polys.push_back(p); return polys;}
std::ostream& operator <<(std::ostream &s, const IntPoint &p);
std::ostream& operator <<(std::ostream &s, const Path &p);
std::ostream& operator <<(std::ostream &s, const Paths &p);
struct DoublePoint
{
double X;
double Y;
DoublePoint(double x = 0, double y = 0) : X(x), Y(y) {}
DoublePoint(IntPoint ip) : X((double)ip.X), Y((double)ip.Y) {}
};
//------------------------------------------------------------------------------
std::ostream& operator <<(std::ostream &s, Polygon &p);
std::ostream& operator <<(std::ostream &s, Polygons &p);
#ifdef use_xyz
typedef void (*TZFillCallback)(IntPoint& z1, IntPoint& z2, IntPoint& pt);
#endif
enum InitOptions {ioReverseSolution = 1, ioStrictlySimple = 2, ioPreserveCollinear = 4};
enum JoinType {jtSquare, jtRound, jtMiter};
enum EndType {etClosedPolygon, etClosedLine, etOpenButt, etOpenSquare, etOpenRound};
#ifdef use_deprecated
enum EndType_ {etClosed, etButt = 2, etSquare, etRound};
#endif
class PolyNode;
typedef std::vector< PolyNode* > PolyNodes;
......@@ -75,17 +134,22 @@ class PolyNode
{
public:
PolyNode();
Polygon Contour;
Path Contour;
PolyNodes Childs;
PolyNode* Parent;
PolyNode* GetNext() const;
bool IsHole() const;
bool IsOpen() const;
int ChildCount() const;
private:
PolyNode* GetNextSiblingUp() const;
unsigned Index; //node index in Parent.Childs
bool m_IsOpen;
JoinType m_jointype;
EndType m_endtype;
PolyNode* GetNextSiblingUp() const;
void AddChild(PolyNode& child);
friend class Clipper; //to access Index
friend class ClipperOffset;
};
class PolyTree: public PolyNode
......@@ -99,113 +163,55 @@ private:
PolyNodes AllNodes;
friend class Clipper; //to access AllNodes
};
enum JoinType { jtSquare, jtRound, jtMiter };
bool Orientation(const Polygon &poly);
double Area(const Polygon &poly);
void OffsetPolygons(const Polygons &in_polys, Polygons &out_polys,
double delta, JoinType jointype = jtSquare, double limit = 0, bool autoFix = true);
void SimplifyPolygon(const Polygon &in_poly, Polygons &out_polys, PolyFillType fillType = pftEvenOdd);
void SimplifyPolygons(const Polygons &in_polys, Polygons &out_polys, PolyFillType fillType = pftEvenOdd);
void SimplifyPolygons(Polygons &polys, PolyFillType fillType = pftEvenOdd);
bool Orientation(const Path &poly);
double Area(const Path &poly);
void CleanPolygon(Polygon& in_poly, Polygon& out_poly, double distance = 1.415);
void CleanPolygons(Polygons& in_polys, Polygons& out_polys, double distance = 1.415);
#ifdef use_deprecated
void OffsetPaths(const Paths &in_polys, Paths &out_polys,
double delta, JoinType jointype, EndType_ endtype, double limit = 0);
#endif
void PolyTreeToPolygons(PolyTree& polytree, Polygons& polygons);
void SimplifyPolygon(const Path &in_poly, Paths &out_polys, PolyFillType fillType = pftEvenOdd);
void SimplifyPolygons(const Paths &in_polys, Paths &out_polys, PolyFillType fillType = pftEvenOdd);
void SimplifyPolygons(Paths &polys, PolyFillType fillType = pftEvenOdd);
void ReversePolygon(Polygon& p);
void ReversePolygons(Polygons& p);
void CleanPolygon(const Path& in_poly, Path& out_poly, double distance = 1.415);
void CleanPolygon(Path& poly, double distance = 1.415);
void CleanPolygons(const Paths& in_polys, Paths& out_polys, double distance = 1.415);
void CleanPolygons(Paths& polys, double distance = 1.415);
//used internally ...
enum EdgeSide { esLeft = 1, esRight = 2};
enum IntersectProtects { ipNone = 0, ipLeft = 1, ipRight = 2, ipBoth = 3 };
struct TEdge {
long64 xbot;
long64 ybot;
long64 xcurr;
long64 ycurr;
long64 xtop;
long64 ytop;
double dx;
long64 deltaX;
long64 deltaY;
PolyType polyType;
EdgeSide side;
int windDelta; //1 or -1 depending on winding direction
int windCnt;
int windCnt2; //winding count of the opposite polytype
int outIdx;
TEdge *next;
TEdge *prev;
TEdge *nextInLML;
TEdge *nextInAEL;
TEdge *prevInAEL;
TEdge *nextInSEL;
TEdge *prevInSEL;
};
void MinkowskiSum(const Path& poly, const Path& path, Paths& solution, bool isClosed);
void MinkowskiDiff(const Path& poly, const Path& path, Paths& solution, bool isClosed);
struct IntersectNode {
TEdge *edge1;
TEdge *edge2;
IntPoint pt;
IntersectNode *next;
};
void PolyTreeToPaths(const PolyTree& polytree, Paths& paths);
void ClosedPathsFromPolyTree(const PolyTree& polytree, Paths& paths);
void OpenPathsFromPolyTree(PolyTree& polytree, Paths& paths);
struct LocalMinima {
long64 Y;
TEdge *leftBound;
TEdge *rightBound;
LocalMinima *next;
};
void ReversePath(Path& p);
void ReversePaths(Paths& p);
struct Scanbeam {
long64 Y;
Scanbeam *next;
};
struct IntRect { cInt left; cInt top; cInt right; cInt bottom; };
struct OutPt; //forward declaration
struct OutRec {
int idx;
bool isHole;
OutRec *FirstLeft; //see comments in clipper.pas
PolyNode *polyNode;
OutPt *pts;
OutPt *bottomPt;
};
struct OutPt {
int idx;
IntPoint pt;
OutPt *next;
OutPt *prev;
};
struct JoinRec {
IntPoint pt1a;
IntPoint pt1b;
int poly1Idx;
IntPoint pt2a;
IntPoint pt2b;
int poly2Idx;
};
struct HorzJoinRec {
TEdge *edge;
int savedIdx;
};
//enums that are used internally ...
enum EdgeSide { esLeft = 1, esRight = 2};
struct IntRect { long64 left; long64 top; long64 right; long64 bottom; };
//forward declarations (for stuff used internally) ...
struct TEdge;
struct IntersectNode;
struct LocalMinima;
struct Scanbeam;
struct OutPt;
struct OutRec;
struct Join;
typedef std::vector < OutRec* > PolyOutList;
typedef std::vector < TEdge* > EdgeList;
typedef std::vector < JoinRec* > JoinList;
typedef std::vector < HorzJoinRec* > HorzJoinList;
typedef std::vector < Join* > JoinList;
typedef std::vector < IntersectNode* > IntersectList;
//------------------------------------------------------------------------------
//ClipperBase is the ancestor to the Clipper class. It should not be
//instantiated directly. This class simply abstracts the conversion of sets of
......@@ -215,29 +221,38 @@ class ClipperBase
public:
ClipperBase();
virtual ~ClipperBase();
bool AddPolygon(const Polygon &pg, PolyType polyType);
bool AddPolygons( const Polygons &ppg, PolyType polyType);
bool AddPath(const Path &pg, PolyType PolyTyp, bool Closed);
bool AddPaths(const Paths &ppg, PolyType PolyTyp, bool Closed);
virtual void Clear();
IntRect GetBounds();
bool PreserveCollinear() {return m_PreserveCollinear;};
void PreserveCollinear(bool value) {m_PreserveCollinear = value;};
protected:
void DisposeLocalMinimaList();
TEdge* AddBoundsToLML(TEdge *e);
TEdge* AddBoundsToLML(TEdge *e, bool IsClosed);
void PopLocalMinima();
virtual void Reset();
TEdge* ProcessBound(TEdge* E, bool IsClockwise);
void InsertLocalMinima(LocalMinima *newLm);
void DoMinimaLML(TEdge* E1, TEdge* E2, bool IsClosed);
TEdge* DescendToMin(TEdge *&E);
void AscendToMax(TEdge *&E, bool Appending, bool IsClosed);
LocalMinima *m_CurrentLM;
LocalMinima *m_MinimaList;
bool m_UseFullRange;
EdgeList m_edges;
bool m_PreserveCollinear;
bool m_HasOpenPaths;
};
//------------------------------------------------------------------------------
class Clipper : public virtual ClipperBase
{
public:
Clipper();
Clipper(int initOptions = 0);
~Clipper();
bool Execute(ClipType clipType,
Polygons &solution,
Paths &solution,
PolyFillType subjFillType = pftEvenOdd,
PolyFillType clipFillType = pftEvenOdd);
bool Execute(ClipType clipType,
......@@ -247,31 +262,40 @@ public:
void Clear();
bool ReverseSolution() {return m_ReverseOutput;};
void ReverseSolution(bool value) {m_ReverseOutput = value;};
bool StrictlySimple() {return m_StrictSimple;};
void StrictlySimple(bool value) {m_StrictSimple = value;};
//set the callback function for z value filling on intersections (otherwise Z is 0)
#ifdef use_xyz
void ZFillFunction(TZFillCallback zFillFunc);
#endif
protected:
void Reset();
virtual bool ExecuteInternal();
private:
PolyOutList m_PolyOuts;
JoinList m_Joins;
HorzJoinList m_HorizJoins;
JoinList m_GhostJoins;
IntersectList m_IntersectList;
ClipType m_ClipType;
Scanbeam *m_Scanbeam;
std::set< cInt, std::greater<cInt> > m_Scanbeam;
TEdge *m_ActiveEdges;
TEdge *m_SortedEdges;
IntersectNode *m_IntersectNodes;
bool m_ExecuteLocked;
PolyFillType m_ClipFillType;
PolyFillType m_SubjFillType;
bool m_ReverseOutput;
bool m_UsingPolyTree;
void DisposeScanbeamList();
bool m_StrictSimple;
#ifdef use_xyz
TZFillCallback m_ZFill; //custom callback
#endif
void SetWindingCount(TEdge& edge);
bool IsEvenOddFillType(const TEdge& edge) const;
bool IsEvenOddAltFillType(const TEdge& edge) const;
void InsertScanbeam(const long64 Y);
long64 PopScanbeam();
void InsertLocalMinimaIntoAEL(const long64 botY);
void InsertEdgeIntoAEL(TEdge *edge);
void InsertScanbeam(const cInt Y);
cInt PopScanbeam();
void InsertLocalMinimaIntoAEL(const cInt botY);
void InsertEdgeIntoAEL(TEdge *edge, TEdge* startEdge);
void AddEdgeToSEL(TEdge *edge);
void CopyAELToSEL();
void DeleteFromSEL(TEdge *e);
......@@ -279,48 +303,79 @@ private:
void UpdateEdgeIntoAEL(TEdge *&e);
void SwapPositionsInSEL(TEdge *edge1, TEdge *edge2);
bool IsContributing(const TEdge& edge) const;
bool IsTopHorz(const long64 XPos);
bool IsTopHorz(const cInt XPos);
void SwapPositionsInAEL(TEdge *edge1, TEdge *edge2);
void DoMaxima(TEdge *e, long64 topY);
void ProcessHorizontals();
void ProcessHorizontal(TEdge *horzEdge);
void DoMaxima(TEdge *e);
void PrepareHorzJoins(TEdge* horzEdge, bool isTopOfScanbeam);
void ProcessHorizontals(bool IsTopOfScanbeam);
void ProcessHorizontal(TEdge *horzEdge, bool isTopOfScanbeam);
void AddLocalMaxPoly(TEdge *e1, TEdge *e2, const IntPoint &pt);
void AddLocalMinPoly(TEdge *e1, TEdge *e2, const IntPoint &pt);
OutPt* AddLocalMinPoly(TEdge *e1, TEdge *e2, const IntPoint &pt);
OutRec* GetOutRec(int idx);
void AppendPolygon(TEdge *e1, TEdge *e2);
void DoEdge1(TEdge *edge1, TEdge *edge2, const IntPoint &pt);
void DoEdge2(TEdge *edge1, TEdge *edge2, const IntPoint &pt);
void DoBothEdges(TEdge *edge1, TEdge *edge2, const IntPoint &pt);
void IntersectEdges(TEdge *e1, TEdge *e2,
const IntPoint &pt, const IntersectProtects protects);
const IntPoint &pt, bool protect = false);
OutRec* CreateOutRec();
void AddOutPt(TEdge *e, const IntPoint &pt);
void DisposeAllPolyPts();
OutPt* AddOutPt(TEdge *e, const IntPoint &pt);
void DisposeAllOutRecs();
void DisposeOutRec(PolyOutList::size_type index);
bool ProcessIntersections(const long64 botY, const long64 topY);
void AddIntersectNode(TEdge *e1, TEdge *e2, const IntPoint &pt);
void BuildIntersectList(const long64 botY, const long64 topY);
bool ProcessIntersections(const cInt botY, const cInt topY);
void BuildIntersectList(const cInt botY, const cInt topY);
void ProcessIntersectList();
void ProcessEdgesAtTopOfScanbeam(const long64 topY);
void BuildResult(Polygons& polys);
void ProcessEdgesAtTopOfScanbeam(const cInt topY);
void BuildResult(Paths& polys);
void BuildResult2(PolyTree& polytree);
void SetHoleState(TEdge *e, OutRec *OutRec);
void SetHoleState(TEdge *e, OutRec *outrec);
void DisposeIntersectNodes();
bool FixupIntersectionOrder();
void FixupOutPolygon(OutRec &outRec);
void FixupOutPolygon(OutRec &outrec);
bool IsHole(TEdge *e);
void FixHoleLinkage(OutRec &outRec);
void AddJoin(TEdge *e1, TEdge *e2, int e1OutIdx = -1, int e2OutIdx = -1);
bool FindOwnerFromSplitRecs(OutRec &outRec, OutRec *&currOrfl);
void FixHoleLinkage(OutRec &outrec);
void AddJoin(OutPt *op1, OutPt *op2, const IntPoint offPt);
void ClearJoins();
void AddHorzJoin(TEdge *e, int idx);
void ClearHorzJoins();
bool JoinPoints(const JoinRec *j, OutPt *&p1, OutPt *&p2);
void FixupJoinRecs(JoinRec *j, OutPt *pt, unsigned startIdx);
void ClearGhostJoins();
void AddGhostJoin(OutPt *op, const IntPoint offPt);
bool JoinPoints(Join *j, OutRec* outRec1, OutRec* outRec2);
void JoinCommonEdges();
void DoSimplePolygons();
void FixupFirstLefts1(OutRec* OldOutRec, OutRec* NewOutRec);
void FixupFirstLefts2(OutRec* OldOutRec, OutRec* NewOutRec);
#ifdef use_xyz
void SetZ(IntPoint& pt, TEdge& e);
#endif
};
//------------------------------------------------------------------------------
class ClipperOffset
{
public:
ClipperOffset(double miterLimit = 2.0, double roundPrecision = 0.25);
~ClipperOffset();
void AddPath(const Path& path, JoinType joinType, EndType endType);
void AddPaths(const Paths& paths, JoinType joinType, EndType endType);
void Execute(Paths& solution, double delta);
void Execute(PolyTree& solution, double delta);
void Clear();
double MiterLimit;
double ArcTolerance;
private:
Paths m_destPolys;
Path m_srcPoly;
Path m_destPoly;
std::vector<DoublePoint> m_normals;
double m_delta, m_sinA, m_sin, m_cos;
double m_miterLim, m_StepsPerRad;
IntPoint m_lowest;
PolyNode m_polyNodes;
void FixOrientations();
void DoOffset(double delta);
void OffsetPoint(int j, int& k, JoinType jointype);
void DoSquare(int j, int k);
void DoMiter(int j, int k, double r);
void DoRound(int j, int k);
};
//------------------------------------------------------------------------------
class clipperException : public std::exception
......
......@@ -32,63 +32,74 @@
#include <iostream>
namespace p2t {
Triangle::Triangle(Point& a, Point& b, Point& c)
Triangle::Triangle( Point& a, Point& b, Point& c )
{
points_[0] = &a; points_[1] = &b; points_[2] = &c;
neighbors_[0] = NULL; neighbors_[1] = NULL; neighbors_[2] = NULL;
constrained_edge[0] = constrained_edge[1] = constrained_edge[2] = false;
delaunay_edge[0] = delaunay_edge[1] = delaunay_edge[2] = false;
interior_ = false;
points_[0] = &a; points_[1] = &b; points_[2] = &c;
neighbors_[0] = NULL; neighbors_[1] = NULL; neighbors_[2] = NULL;
constrained_edge[0] = constrained_edge[1] = constrained_edge[2] = false;
delaunay_edge[0] = delaunay_edge[1] = delaunay_edge[2] = false;
interior_ = false;
}
// Update neighbor pointers
void Triangle::MarkNeighbor(Point* p1, Point* p2, Triangle* t)
void Triangle::MarkNeighbor( Point* p1, Point* p2, Triangle* t )
{
if ((p1 == points_[2] && p2 == points_[1]) || (p1 == points_[1] && p2 == points_[2]))
neighbors_[0] = t;
else if ((p1 == points_[0] && p2 == points_[2]) || (p1 == points_[2] && p2 == points_[0]))
neighbors_[1] = t;
else if ((p1 == points_[0] && p2 == points_[1]) || (p1 == points_[1] && p2 == points_[0]))
neighbors_[2] = t;
else
assert(0);
if( (p1 == points_[2] && p2 == points_[1]) || (p1 == points_[1] && p2 == points_[2]) )
neighbors_[0] = t;
else if( (p1 == points_[0] && p2 == points_[2]) || (p1 == points_[2] && p2 == points_[0]) )
neighbors_[1] = t;
else if( (p1 == points_[0] && p2 == points_[1]) || (p1 == points_[1] && p2 == points_[0]) )
neighbors_[2] = t;
else
assert( 0 );
}
// Exhaustive search to update neighbor pointers
void Triangle::MarkNeighbor(Triangle& t)
void Triangle::MarkNeighbor( Triangle& t )
{
if (t.Contains(points_[1], points_[2])) {
neighbors_[0] = &t;
t.MarkNeighbor(points_[1], points_[2], this);
} else if (t.Contains(points_[0], points_[2])) {
neighbors_[1] = &t;
t.MarkNeighbor(points_[0], points_[2], this);
} else if (t.Contains(points_[0], points_[1])) {
neighbors_[2] = &t;
t.MarkNeighbor(points_[0], points_[1], this);
}
if( t.Contains( points_[1], points_[2] ) )
{
neighbors_[0] = &t;
t.MarkNeighbor( points_[1], points_[2], this );
}
else if( t.Contains( points_[0], points_[2] ) )
{
neighbors_[1] = &t;
t.MarkNeighbor( points_[0], points_[2], this );
}
else if( t.Contains( points_[0], points_[1] ) )
{
neighbors_[2] = &t;
t.MarkNeighbor( points_[0], points_[1], this );
}
}
/**
* Clears all references to all other triangles and points
*/
void Triangle::Clear()
{
Triangle *t;
for( int i=0; i<3; i++ )
Triangle* t;
for( int i = 0; i<3; i++ )
{
t = neighbors_[i];
if( t != NULL )
{
t->ClearNeighbor( this );
}
}
ClearNeighbors();
points_[0]=points_[1]=points_[2] = NULL;
points_[0] = points_[1] = points_[2] = NULL;
}
void Triangle::ClearNeighbor(Triangle *triangle )
void Triangle::ClearNeighbor( Triangle* triangle )
{
if( neighbors_[0] == triangle )
{
......@@ -104,263 +115,379 @@ void Triangle::ClearNeighbor(Triangle *triangle )
}
}
void Triangle::ClearNeighbors()
{
neighbors_[0] = NULL;
neighbors_[1] = NULL;
neighbors_[2] = NULL;
neighbors_[0] = NULL;
neighbors_[1] = NULL;
neighbors_[2] = NULL;
}
void Triangle::ClearDelunayEdges()
{
delaunay_edge[0] = delaunay_edge[1] = delaunay_edge[2] = false;
delaunay_edge[0] = delaunay_edge[1] = delaunay_edge[2] = false;
}
Point* Triangle::OppositePoint(Triangle& t, Point& p)
Point* Triangle::OppositePoint( Triangle& t, Point& p )
{
Point *cw = t.PointCW(p);
double x = cw->x;
double y = cw->y;
x = p.x;
y = p.y;
return PointCW(*cw);
Point* cw = t.PointCW( p );
double x = cw->x;
double y = cw->y;
x = p.x;
y = p.y;
return PointCW( *cw );
}
// Legalized triangle by rotating clockwise around point(0)
void Triangle::Legalize(Point& point)
void Triangle::Legalize( Point& point )
{
points_[1] = points_[0];
points_[0] = points_[2];
points_[2] = &point;
points_[1] = points_[0];
points_[0] = points_[2];
points_[2] = &point;
}
// Legalize triagnle by rotating clockwise around oPoint
void Triangle::Legalize(Point& opoint, Point& npoint)
void Triangle::Legalize( Point& opoint, Point& npoint )
{
if (&opoint == points_[0]) {
points_[1] = points_[0];
points_[0] = points_[2];
points_[2] = &npoint;
} else if (&opoint == points_[1]) {
points_[2] = points_[1];
points_[1] = points_[0];
points_[0] = &npoint;
} else if (&opoint == points_[2]) {
points_[0] = points_[2];
points_[2] = points_[1];
points_[1] = &npoint;
} else {
assert(0);
}
if( &opoint == points_[0] )
{
points_[1] = points_[0];
points_[0] = points_[2];
points_[2] = &npoint;
}
else if( &opoint == points_[1] )
{
points_[2] = points_[1];
points_[1] = points_[0];
points_[0] = &npoint;
}
else if( &opoint == points_[2] )
{
points_[0] = points_[2];
points_[2] = points_[1];
points_[1] = &npoint;
}
else
{
assert( 0 );
}
}
int Triangle::Index(const Point* p)
int Triangle::Index( const Point* p )
{
if (p == points_[0]) {
return 0;
} else if (p == points_[1]) {
return 1;
} else if (p == points_[2]) {
return 2;
}
assert(0);
if( p == points_[0] )
{
return 0;
}
else if( p == points_[1] )
{
return 1;
}
else if( p == points_[2] )
{
return 2;
}
assert( 0 );
}
int Triangle::EdgeIndex(const Point* p1, const Point* p2)
int Triangle::EdgeIndex( const Point* p1, const Point* p2 )
{
if (points_[0] == p1) {
if (points_[1] == p2) {
return 2;
} else if (points_[2] == p2) {
return 1;
}
} else if (points_[1] == p1) {
if (points_[2] == p2) {
return 0;
} else if (points_[0] == p2) {
return 2;
}
} else if (points_[2] == p1) {
if (points_[0] == p2) {
return 1;
} else if (points_[1] == p2) {
return 0;
}
}
return -1;
if( points_[0] == p1 )
{
if( points_[1] == p2 )
{
return 2;
}
else if( points_[2] == p2 )
{
return 1;
}
}
else if( points_[1] == p1 )
{
if( points_[2] == p2 )
{
return 0;
}
else if( points_[0] == p2 )
{
return 2;
}
}
else if( points_[2] == p1 )
{
if( points_[0] == p2 )
{
return 1;
}
else if( points_[1] == p2 )
{
return 0;
}
}
return -1;
}
void Triangle::MarkConstrainedEdge(const int index)
void Triangle::MarkConstrainedEdge( const int index )
{
constrained_edge[index] = true;
constrained_edge[index] = true;
}
void Triangle::MarkConstrainedEdge(Edge& edge)
void Triangle::MarkConstrainedEdge( Edge& edge )
{
MarkConstrainedEdge(edge.p, edge.q);
MarkConstrainedEdge( edge.p, edge.q );
}
// Mark edge as constrained
void Triangle::MarkConstrainedEdge(Point* p, Point* q)
void Triangle::MarkConstrainedEdge( Point* p, Point* q )
{
if ((q == points_[0] && p == points_[1]) || (q == points_[1] && p == points_[0])) {
constrained_edge[2] = true;
} else if ((q == points_[0] && p == points_[2]) || (q == points_[2] && p == points_[0])) {
constrained_edge[1] = true;
} else if ((q == points_[1] && p == points_[2]) || (q == points_[2] && p == points_[1])) {
constrained_edge[0] = true;
}
if( (q == points_[0] && p == points_[1]) || (q == points_[1] && p == points_[0]) )
{
constrained_edge[2] = true;
}
else if( (q == points_[0] && p == points_[2]) || (q == points_[2] && p == points_[0]) )
{
constrained_edge[1] = true;
}
else if( (q == points_[1] && p == points_[2]) || (q == points_[2] && p == points_[1]) )
{
constrained_edge[0] = true;
}
}
// The point counter-clockwise to given point
Point* Triangle::PointCW(Point& point)
Point* Triangle::PointCW( Point& point )
{
if (&point == points_[0]) {
return points_[2];
} else if (&point == points_[1]) {
return points_[0];
} else if (&point == points_[2]) {
return points_[1];
}
assert(0);
if( &point == points_[0] )
{
return points_[2];
}
else if( &point == points_[1] )
{
return points_[0];
}
else if( &point == points_[2] )
{
return points_[1];
}
assert( 0 );
}
// The point counter-clockwise to given point
Point* Triangle::PointCCW(Point& point)
Point* Triangle::PointCCW( Point& point )
{
if (&point == points_[0]) {
return points_[1];
} else if (&point == points_[1]) {
return points_[2];
} else if (&point == points_[2]) {
return points_[0];
}
assert(0);
if( &point == points_[0] )
{
return points_[1];
}
else if( &point == points_[1] )
{
return points_[2];
}
else if( &point == points_[2] )
{
return points_[0];
}
assert( 0 );
}
// The neighbor clockwise to given point
Triangle* Triangle::NeighborCW(Point& point)
Triangle* Triangle::NeighborCW( Point& point )
{
if (&point == points_[0]) {
return neighbors_[1];
} else if (&point == points_[1]) {
return neighbors_[2];
}
return neighbors_[0];
}
if( &point == points_[0] )
{
return neighbors_[1];
}
else if( &point == points_[1] )
{
return neighbors_[2];
}
// The neighbor counter-clockwise to given point
Triangle* Triangle::NeighborCCW(Point& point)
{
if (&point == points_[0]) {
return neighbors_[2];
} else if (&point == points_[1]) {
return neighbors_[0];
}
return neighbors_[1];
}
bool Triangle::GetConstrainedEdgeCCW(Point& p)
// The neighbor counter-clockwise to given point
Triangle* Triangle::NeighborCCW( Point& point )
{
if (&p == points_[0]) {
return constrained_edge[2];
} else if (&p == points_[1]) {
return constrained_edge[0];
}
return constrained_edge[1];
if( &point == points_[0] )
{
return neighbors_[2];
}
else if( &point == points_[1] )
{
return neighbors_[0];
}
return neighbors_[1];
}
bool Triangle::GetConstrainedEdgeCW(Point& p)
bool Triangle::GetConstrainedEdgeCCW( Point& p )
{
if (&p == points_[0]) {
if( &p == points_[0] )
{
return constrained_edge[2];
}
else if( &p == points_[1] )
{
return constrained_edge[0];
}
return constrained_edge[1];
} else if (&p == points_[1]) {
return constrained_edge[2];
}
return constrained_edge[0];
}
void Triangle::SetConstrainedEdgeCCW(Point& p, bool ce)
bool Triangle::GetConstrainedEdgeCW( Point& p )
{
if (&p == points_[0]) {
constrained_edge[2] = ce;
} else if (&p == points_[1]) {
constrained_edge[0] = ce;
} else {
constrained_edge[1] = ce;
}
if( &p == points_[0] )
{
return constrained_edge[1];
}
else if( &p == points_[1] )
{
return constrained_edge[2];
}
return constrained_edge[0];
}
void Triangle::SetConstrainedEdgeCW(Point& p, bool ce)
void Triangle::SetConstrainedEdgeCCW( Point& p, bool ce )
{
if (&p == points_[0]) {
constrained_edge[1] = ce;
} else if (&p == points_[1]) {
constrained_edge[2] = ce;
} else {
constrained_edge[0] = ce;
}
if( &p == points_[0] )
{
constrained_edge[2] = ce;
}
else if( &p == points_[1] )
{
constrained_edge[0] = ce;
}
else
{
constrained_edge[1] = ce;
}
}
bool Triangle::GetDelunayEdgeCCW(Point& p)
void Triangle::SetConstrainedEdgeCW( Point& p, bool ce )
{
if (&p == points_[0]) {
return delaunay_edge[2];
} else if (&p == points_[1]) {
return delaunay_edge[0];
}
return delaunay_edge[1];
if( &p == points_[0] )
{
constrained_edge[1] = ce;
}
else if( &p == points_[1] )
{
constrained_edge[2] = ce;
}
else
{
constrained_edge[0] = ce;
}
}
bool Triangle::GetDelunayEdgeCW(Point& p)
bool Triangle::GetDelunayEdgeCCW( Point& p )
{
if (&p == points_[0]) {
if( &p == points_[0] )
{
return delaunay_edge[2];
}
else if( &p == points_[1] )
{
return delaunay_edge[0];
}
return delaunay_edge[1];
} else if (&p == points_[1]) {
return delaunay_edge[2];
}
return delaunay_edge[0];
}
void Triangle::SetDelunayEdgeCCW(Point& p, bool e)
bool Triangle::GetDelunayEdgeCW( Point& p )
{
if (&p == points_[0]) {
delaunay_edge[2] = e;
} else if (&p == points_[1]) {
delaunay_edge[0] = e;
} else {
delaunay_edge[1] = e;
}
if( &p == points_[0] )
{
return delaunay_edge[1];
}
else if( &p == points_[1] )
{
return delaunay_edge[2];
}
return delaunay_edge[0];
}
void Triangle::SetDelunayEdgeCW(Point& p, bool e)
void Triangle::SetDelunayEdgeCCW( Point& p, bool e )
{
if (&p == points_[0]) {
delaunay_edge[1] = e;
} else if (&p == points_[1]) {
delaunay_edge[2] = e;
} else {
delaunay_edge[0] = e;
}
if( &p == points_[0] )
{
delaunay_edge[2] = e;
}
else if( &p == points_[1] )
{
delaunay_edge[0] = e;
}
else
{
delaunay_edge[1] = e;
}
}
void Triangle::SetDelunayEdgeCW( Point& p, bool e )
{
if( &p == points_[0] )
{
delaunay_edge[1] = e;
}
else if( &p == points_[1] )
{
delaunay_edge[2] = e;
}
else
{
delaunay_edge[0] = e;
}
}
// The neighbor across to given point
Triangle& Triangle::NeighborAcross(Point& opoint)
Triangle& Triangle::NeighborAcross( Point& opoint )
{
if (&opoint == points_[0]) {
return *neighbors_[0];
} else if (&opoint == points_[1]) {
return *neighbors_[1];
}
return *neighbors_[2];
if( &opoint == points_[0] )
{
return *neighbors_[0];
}
else if( &opoint == points_[1] )
{
return *neighbors_[1];
}
return *neighbors_[2];
}
void Triangle::DebugPrint()
{
std::cout << points_[0]->x << "," << points_[0]->y << " ";
std::cout << points_[1]->x << "," << points_[1]->y << " ";
std::cout << points_[2]->x << "," << points_[2]->y << "\n";
std::cout << points_[0]->x << "," << points_[0]->y << " ";
std::cout << points_[1]->x << "," << points_[1]->y << " ";
std::cout << points_[2]->x << "," << points_[2]->y << "\n";
}
}
......@@ -39,287 +39,313 @@
#include <cmath>
namespace p2t {
struct Edge;
struct Point {
double x, y;
/// Default constructor does nothing (for performance).
Point()
{
x = 0.0;
y = 0.0;
}
/// The edges this point constitutes an upper ending point
std::vector<Edge*> edge_list;
/// Construct using coordinates.
Point(double x, double y) : x(x), y(y) {}
/// Set this point to all zeros.
void set_zero()
{
x = 0.0;
y = 0.0;
}
/// Set this point to some specified coordinates.
void set(double x_, double y_)
{
x = x_;
y = y_;
}
/// Negate this point.
Point operator -() const
{
Point v;
v.set(-x, -y);
return v;
}
/// Add a point to this point.
void operator +=(const Point& v)
{
x += v.x;
y += v.y;
}
/// Subtract a point from this point.
void operator -=(const Point& v)
{
x -= v.x;
y -= v.y;
}
/// Multiply this point by a scalar.
void operator *=(double a)
{
x *= a;
y *= a;
}
/// Get the length of this point (the norm).
double Length() const
{
return sqrt(x * x + y * y);
}
/// Convert this point into a unit point. Returns the Length.
double Normalize()
{
double len = Length();
x /= len;
y /= len;
return len;
}
struct Point
{
double x, y;
/// Default constructor does nothing (for performance).
Point()
{
x = 0.0;
y = 0.0;
}
/// The edges this point constitutes an upper ending point
std::vector<Edge*> edge_list;
/// Construct using coordinates.
Point( double x, double y ) : x( x ), y( y ) {}
/// Set this point to all zeros.
void set_zero()
{
x = 0.0;
y = 0.0;
}
/// Set this point to some specified coordinates.
void set( double x_, double y_ )
{
x = x_;
y = y_;
}
/// Negate this point.
Point operator -() const
{
Point v;
v.set( -x, -y );
return v;
}
/// Add a point to this point.
void operator +=( const Point& v )
{
x += v.x;
y += v.y;
}
/// Subtract a point from this point.
void operator -=( const Point& v )
{
x -= v.x;
y -= v.y;
}
/// Multiply this point by a scalar.
void operator *=( double a )
{
x *= a;
y *= a;
}
/// Get the length of this point (the norm).
double Length() const
{
return sqrt( x * x + y * y );
}
/// Convert this point into a unit point. Returns the Length.
double Normalize()
{
double len = Length();
x /= len;
y /= len;
return len;
}
};
// Represents a simple polygon's edge
struct Edge {
Point* p, *q;
/// Constructor
Edge(Point& p1, Point& p2) : p(&p1), q(&p2)
{
if (p1.y > p2.y) {
q = &p1;
p = &p2;
} else if (p1.y == p2.y) {
if (p1.x > p2.x) {
q = &p1;
p = &p2;
} else if (p1.x == p2.x) {
// Repeat points
assert(false);
}
struct Edge
{
Point* p, * q;
/// Constructor
Edge( Point& p1, Point& p2 ) : p( &p1 ), q( &p2 )
{
if( p1.y > p2.y )
{
q = &p1;
p = &p2;
}
else if( p1.y == p2.y )
{
if( p1.x > p2.x )
{
q = &p1;
p = &p2;
}
else if( p1.x == p2.x )
{
// Repeat points
assert( false );
}
}
q->edge_list.push_back( this );
}
q->edge_list.push_back(this);
}
};
// Triangle-based data structures are know to have better performance than quad-edge structures
// See: J. Shewchuk, "Triangle: Engineering a 2D Quality Mesh Generator and Delaunay Triangulator"
// "Triangulations in CGAL"
class Triangle {
// "Triangulations in CGAL"
class Triangle
{
public:
/// Constructor
Triangle(Point& a, Point& b, Point& c);
Triangle( Point& a, Point& b, Point& c );
/// Flags to determine if an edge is a Constrained edge
bool constrained_edge[3];
bool constrained_edge[3];
/// Flags to determine if an edge is a Delauney edge
bool delaunay_edge[3];
Point* GetPoint(const int& index);
Point* PointCW(Point& point);
Point* PointCCW(Point& point);
Point* OppositePoint(Triangle& t, Point& p);
Triangle* GetNeighbor(const int& index);
void MarkNeighbor(Point* p1, Point* p2, Triangle* t);
void MarkNeighbor(Triangle& t);
void MarkConstrainedEdge(const int index);
void MarkConstrainedEdge(Edge& edge);
void MarkConstrainedEdge(Point* p, Point* q);
int Index(const Point* p);
int EdgeIndex(const Point* p1, const Point* p2);
Triangle* NeighborCW(Point& point);
Triangle* NeighborCCW(Point& point);
bool GetConstrainedEdgeCCW(Point& p);
bool GetConstrainedEdgeCW(Point& p);
void SetConstrainedEdgeCCW(Point& p, bool ce);
void SetConstrainedEdgeCW(Point& p, bool ce);
bool GetDelunayEdgeCCW(Point& p);
bool GetDelunayEdgeCW(Point& p);
void SetDelunayEdgeCCW(Point& p, bool e);
void SetDelunayEdgeCW(Point& p, bool e);
bool Contains(Point* p);
bool Contains(const Edge& e);
bool Contains(Point* p, Point* q);
void Legalize(Point& point);
void Legalize(Point& opoint, Point& npoint);
bool delaunay_edge[3];
Point* GetPoint( const int& index );
Point* PointCW( Point& point );
Point* PointCCW( Point& point );
Point* OppositePoint( Triangle& t, Point& p );
Triangle* GetNeighbor( const int& index );
void MarkNeighbor( Point* p1, Point* p2, Triangle* t );
void MarkNeighbor( Triangle& t );
void MarkConstrainedEdge( const int index );
void MarkConstrainedEdge( Edge& edge );
void MarkConstrainedEdge( Point* p, Point* q );
int Index( const Point* p );
int EdgeIndex( const Point* p1, const Point* p2 );
Triangle* NeighborCW( Point& point );
Triangle* NeighborCCW( Point& point );
bool GetConstrainedEdgeCCW( Point& p );
bool GetConstrainedEdgeCW( Point& p );
void SetConstrainedEdgeCCW( Point& p, bool ce );
void SetConstrainedEdgeCW( Point& p, bool ce );
bool GetDelunayEdgeCCW( Point& p );
bool GetDelunayEdgeCW( Point& p );
void SetDelunayEdgeCCW( Point& p, bool e );
void SetDelunayEdgeCW( Point& p, bool e );
bool Contains( Point* p );
bool Contains( const Edge& e );
bool Contains( Point* p, Point* q );
void Legalize( Point& point );
void Legalize( Point& opoint, Point& npoint );
/**
* Clears all references to all other triangles and points
*/
void Clear();
void ClearNeighbor(Triangle *triangle );
void ClearNeighbors();
void ClearDelunayEdges();
void Clear();
void ClearNeighbor( Triangle* triangle );
void ClearNeighbors();
void ClearDelunayEdges();
inline bool IsInterior();
inline void IsInterior(bool b);
inline bool IsInterior();
inline void IsInterior( bool b );
Triangle& NeighborAcross(Point& opoint);
Triangle& NeighborAcross( Point& opoint );
void DebugPrint();
void DebugPrint();
private:
/// Triangle points
Point* points_[3];
Point* points_[3];
/// Neighbor list
Triangle* neighbors_[3];
Triangle* neighbors_[3];
/// Has this triangle been marked as an interior triangle?
bool interior_;
bool interior_;
};
inline bool cmp(const Point* a, const Point* b)
inline bool cmp( const Point* a, const Point* b )
{
if (a->y < b->y) {
return true;
} else if (a->y == b->y) {
// Make sure q is point with greater x value
if (a->x < b->x) {
return true;
if( a->y < b->y )
{
return true;
}
}
return false;
else if( a->y == b->y )
{
// Make sure q is point with greater x value
if( a->x < b->x )
{
return true;
}
}
return false;
}
/// Add two points_ component-wise.
inline Point operator +(const Point& a, const Point& b)
inline Point operator +( const Point& a, const Point& b )
{
return Point(a.x + b.x, a.y + b.y);
return Point( a.x + b.x, a.y + b.y );
}
/// Subtract two points_ component-wise.
inline Point operator -(const Point& a, const Point& b)
inline Point operator -( const Point& a, const Point& b )
{
return Point(a.x - b.x, a.y - b.y);
return Point( a.x - b.x, a.y - b.y );
}
/// Multiply point by scalar
inline Point operator *(double s, const Point& a)
inline Point operator *( double s, const Point& a )
{
return Point(s * a.x, s * a.y);
return Point( s * a.x, s * a.y );
}
inline bool operator ==(const Point& a, const Point& b)
inline bool operator ==( const Point& a, const Point& b )
{
return a.x == b.x && a.y == b.y;
return a.x == b.x && a.y == b.y;
}
inline bool operator !=(const Point& a, const Point& b)
inline bool operator !=( const Point& a, const Point& b )
{
return !(a.x == b.x) && !(a.y == b.y);
return !(a.x == b.x) && !(a.y == b.y);
}
/// Peform the dot product on two vectors.
inline double Dot(const Point& a, const Point& b)
inline double Dot( const Point& a, const Point& b )
{
return a.x * b.x + a.y * b.y;
return a.x * b.x + a.y * b.y;
}
/// Perform the cross product on two vectors. In 2D this produces a scalar.
inline double Cross(const Point& a, const Point& b)
inline double Cross( const Point& a, const Point& b )
{
return a.x * b.y - a.y * b.x;
return a.x * b.y - a.y * b.x;
}
/// Perform the cross product on a point and a scalar. In 2D this produces
/// a point.
inline Point Cross(const Point& a, double s)
inline Point Cross( const Point& a, double s )
{
return Point(s * a.y, -s * a.x);
return Point( s * a.y, -s * a.x );
}
/// Perform the cross product on a scalar and a point. In 2D this produces
/// a point.
inline Point Cross(const double s, const Point& a)
inline Point Cross( const double s, const Point& a )
{
return Point(-s * a.y, s * a.x);
return Point( -s * a.y, s * a.x );
}
inline Point* Triangle::GetPoint(const int& index)
inline Point* Triangle::GetPoint( const int& index )
{
return points_[index];
return points_[index];
}
inline Triangle* Triangle::GetNeighbor(const int& index)
inline Triangle* Triangle::GetNeighbor( const int& index )
{
return neighbors_[index];
return neighbors_[index];
}
inline bool Triangle::Contains(Point* p)
inline bool Triangle::Contains( Point* p )
{
return p == points_[0] || p == points_[1] || p == points_[2];
return p == points_[0] || p == points_[1] || p == points_[2];
}
inline bool Triangle::Contains(const Edge& e)
inline bool Triangle::Contains( const Edge& e )
{
return Contains(e.p) && Contains(e.q);
return Contains( e.p ) && Contains( e.q );
}
inline bool Triangle::Contains(Point* p, Point* q)
inline bool Triangle::Contains( Point* p, Point* q )
{
return Contains(p) && Contains(q);
return Contains( p ) && Contains( q );
}
inline bool Triangle::IsInterior()
{
return interior_;
return interior_;
}
inline void Triangle::IsInterior(bool b)
inline void Triangle::IsInterior( bool b )
{
interior_ = b;
interior_ = b;
}
}
#endif
/*
/*
* Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors
* http://code.google.com/p/poly2tri/
*
......@@ -28,7 +28,7 @@
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef UTILS_H
#define UTILS_H
......@@ -39,12 +39,13 @@
#include <math.h>
namespace p2t {
const double PI_3div4 = 3 * M_PI / 4;
const double PI_div2 = 1.57079632679489661923;
const double EPSILON = 1e-12;
const double PI_3div4 = 3 * M_PI / 4;
const double PI_div2 = 1.57079632679489661923;
const double EPSILON = 1e-12;
enum Orientation { CW, CCW, COLLINEAR };
enum Orientation {
CW, CCW, COLLINEAR
};
/**
* Forumla to calculate signed area<br>
......@@ -56,68 +57,77 @@ enum Orientation { CW, CCW, COLLINEAR };
* = (x1-x3)*(y2-y3) - (y1-y3)*(x2-x3)
* </pre>
*/
Orientation Orient2d(Point& pa, Point& pb, Point& pc)
Orientation Orient2d( Point& pa, Point& pb, Point& pc )
{
double detleft = (pa.x - pc.x) * (pb.y - pc.y);
double detright = (pa.y - pc.y) * (pb.x - pc.x);
double val = detleft - detright;
if (val > -EPSILON && val < EPSILON) {
return COLLINEAR;
} else if (val > 0) {
return CCW;
}
return CW;
double detleft = (pa.x - pc.x) * (pb.y - pc.y);
double detright = (pa.y - pc.y) * (pb.x - pc.x);
double val = detleft - detright;
if( val > -EPSILON && val < EPSILON )
{
return COLLINEAR;
}
else if( val > 0 )
{
return CCW;
}
return CW;
}
/*
bool InScanArea(Point& pa, Point& pb, Point& pc, Point& pd)
{
double pdx = pd.x;
double pdy = pd.y;
double adx = pa.x - pdx;
double ady = pa.y - pdy;
double bdx = pb.x - pdx;
double bdy = pb.y - pdy;
double adxbdy = adx * bdy;
double bdxady = bdx * ady;
double oabd = adxbdy - bdxady;
if (oabd <= EPSILON) {
return false;
}
double cdx = pc.x - pdx;
double cdy = pc.y - pdy;
/*
* bool InScanArea(Point& pa, Point& pb, Point& pc, Point& pd)
* {
* double pdx = pd.x;
* double pdy = pd.y;
* double adx = pa.x - pdx;
* double ady = pa.y - pdy;
* double bdx = pb.x - pdx;
* double bdy = pb.y - pdy;
*
* double adxbdy = adx * bdy;
* double bdxady = bdx * ady;
* double oabd = adxbdy - bdxady;
*
* if (oabd <= EPSILON) {
* return false;
* }
*
* double cdx = pc.x - pdx;
* double cdy = pc.y - pdy;
*
* double cdxady = cdx * ady;
* double adxcdy = adx * cdy;
* double ocad = cdxady - adxcdy;
*
* if (ocad <= EPSILON) {
* return false;
* }
*
* return true;
* }
*
*/
double cdxady = cdx * ady;
double adxcdy = adx * cdy;
double ocad = cdxady - adxcdy;
bool InScanArea( Point& pa, Point& pb, Point& pc, Point& pd )
{
double oadb = (pa.x - pb.x) * (pd.y - pb.y) - (pd.x - pb.x) * (pa.y - pb.y);
if (ocad <= EPSILON) {
return false;
}
if( oadb >= -EPSILON )
{
return false;
}
return true;
}
double oadc = (pa.x - pc.x) * (pd.y - pc.y) - (pd.x - pc.x) * (pa.y - pc.y);
*/
if( oadc <= EPSILON )
{
return false;
}
bool InScanArea(Point& pa, Point& pb, Point& pc, Point& pd)
{
double oadb = (pa.x - pb.x)*(pd.y - pb.y) - (pd.x - pb.x)*(pa.y - pb.y);
if (oadb >= -EPSILON) {
return false;
}
double oadc = (pa.x - pc.x)*(pd.y - pc.y) - (pd.x - pc.x)*(pa.y - pc.y);
if (oadc <= EPSILON) {
return false;
}
return true;
return true;
}
}
#endif
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment