symb.h
#if (!defined(__symb_h))

#include "capd/capdlib.h"
#include "eps.h"
#include "intutils.h"

using namespace std;
using namespace capd;

typedef vector <IVector> BrokenLine;
typedef vector < vector <IVector> > BrokenLineSet; // set of Segm
typedef vector <IVector> Polygon;
typedef vector < vector <IVector> > PolygonSet;
typedef vector <IVector> IVectorSet;
typedef vector <IVectorSet> IVectorSets;
typedef vector <DVector> DVectorSet;

string ColorString(int i);
IVector GetRange(const Polygon & aPolygon);
void VectorSetSave(const DVectorSet & VSet, string FileName, int prec);
void VectorSetLoad(string FileName, DVectorSet & VSet);
void IVectorSetSave(const IVectorSet & IVSet, string FileName, int prec);
void IVectorSetLoad(string FileName, IVectorSet & IVSet);
void PolygonSetSave(const PolygonSet & Polygons, string FileName, int prec);
void PolygonSetLoad(string FileName, PolygonSet & Polygons);
PolygonSet PolygonSetSymmetric(const PolygonSet & Polygons);

void PolygonSetSaveEPS(const PolygonSet & Polygons, string FileName, EPSOptions & EPSOpt, int XDisp, int YDisp, bool DoSymmetric, bool PlotLegend=true, bool UseSingleColor=true, bool fill=false);

void IVectorSetsSaveEPS(const IVectorSets & IVSets, string FileName, EPSOptions & EPSOpt, int XDisp, int YDisp, bool PlotLegend=true, bool UseSingleColor=true, bool fill=false);

struct Segment{
  vector < IVector > P;
  int size() const {return P.size();} ;
  int PointNum() const {return P.size();} ;
  void AddPoint(const IVector & aP){ P.push_back(aP);};
  IVector GetRange() const;
};

double SegmentDist(const Segment & S1, const Segment & S2);

struct Quadr{
  vector <Segment> S;
  int size() const {return S.size();} ;
  int SegmentNum() const {return S.size();} ;
  void AddSegment(const Segment & aS){ S.push_back(aS);};
  IVector GetRange();
};

struct QuadrSet{
  vector <Quadr> Q;
  int QuadrNum() const {return Q.size();} ;
  int size() const {return Q.size();} ;
  IVector GetRange();
  void AddQuadr(const Quadr & aQ){ Q.push_back(aQ);};
  void Read(string FileName);
  void Save(string FileName, int prec=8);
  void Write(int prec=8);
  PolygonSet GetPolygonSet(bool MakeSymmetric);
  void PrintEPS(string FileName, EPSOptions & EPSOpt, int XDisp, int YDisp, bool DoSymmetric, bool PlotLegend=true, bool UseSingleColor=true, bool fill=false);
};

inline int isLeftOrRight(const IVector & P0, const IVector & P1, const IVector & P2, int x, int y){
  Interval res=(P1[x]-P0[x])*(P2[y]-P0[y])-(P2[x]-P0[x])*(P1[y]-P0[y]);
  if (res>0.0) return +1;
  if (res<0.0) return -1;
  return 0;
}

struct IntPoint {
  int x,y;
  IntPoint(int ax, int ay): x(ax), y(ay){};
};

// isLeft(): tests if a point is Left|On|Right of an infinite line.
//    Input:  three points P0, P1, and P2
//    Return: >0 for P2 left of the line through P0 and P1
//            =0 for P2  on the line
//            <0 for P2  right of the line
//    See: Algorithm 1 "Area of Triangles and Polygons"
inline int isLeft( IntPoint P0, IntPoint P1, IntPoint P2 ){ return ( (P1.x - P0.x) * (P2.y - P0.y) - (P2.x -  P0.x) * (P1.y - P0.y) );}

bool PointNotInSegment(const IVector & P0, const IVector & P1, const IVector & P, int x, int y);
bool PointNotInBrokenLine(const IVector & P, const BrokenLine & BL, int x, int y); 
int IntPointInPoly(IntPoint P, const vector <IntPoint> & V);
int PointInPolyInterior(const IVector & P, const Polygon & Poly, int x, int y);

void TestIntPointInPoly();
void TestPointInPoly();

#define __symb_h __symb_h
#endif