00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifndef __INTERPKERNELGEO2DEDGE_HXX__
00021 #define __INTERPKERNELGEO2DEDGE_HXX__
00022
00023 #include "INTERPKERNELGEOMETRIC2DDefines.hxx"
00024 #include "InterpKernelGeo2DComposedEdge.hxx"
00025 #include "InterpKernelException.hxx"
00026 #include "InterpKernelGeo2DBounds.hxx"
00027 #include "InterpKernelGeo2DNode.hxx"
00028
00029 #include <iostream>
00030 #include <vector>
00031 #include <list>
00032 #include <map>
00033
00034 namespace INTERP_KERNEL
00035 {
00036 typedef enum
00037 {
00038 SEG = 1,
00039 ARC_CIRCLE = 4,
00040 ARC_PARABOL = 8
00041 } TypeOfFunction;
00042
00043 typedef enum
00044 {
00045 CIRCLE = 0 ,
00046 PARABOL = 1
00047 } TypeOfMod4QuadEdge;
00048
00049 typedef enum
00050 {
00051 START = 5,
00052 END = 1,
00053 INSIDE = 2,
00054 OUT_BEFORE = 3,
00055 OUT_AFTER = 4
00056 } TypeOfLocInEdge;
00057
00058 typedef enum
00059 {
00060 FULL_IN_1 = 1,
00061 FULL_ON_1 = 4,
00062 FULL_OUT_1 = 2,
00063 FULL_UNKNOWN = 3
00064 } TypeOfEdgeLocInPolygon;
00065
00066 class INTERPKERNELGEOMETRIC2D_EXPORT MergePoints
00067 {
00068 public:
00069 MergePoints();
00070
00071
00072 void start1Replaced();
00073 void end1Replaced();
00074 void start1OnStart2();
00075 void start1OnEnd2();
00076 void end1OnStart2();
00077 void end1OnEnd2();
00078
00079 bool isStart1(unsigned rk) const;
00080 bool isEnd1(unsigned rk) const;
00081 bool isStart2(unsigned rk) const;
00082 bool isEnd2(unsigned rk) const;
00083 void clear();
00084 unsigned getNumberOfAssociations() const;
00085 private:
00086 unsigned _ass1Start1 : 1;
00087 unsigned _ass1End1 : 1;
00088 unsigned _ass1Start2 : 1;
00089 unsigned _ass1End2 : 1;
00090 unsigned _ass2Start1 : 1;
00091 unsigned _ass2End1 : 1;
00092 unsigned _ass2Start2 : 1;
00093 unsigned _ass2End2 : 1;
00094 };
00095
00100 class INTERPKERNELGEOMETRIC2D_EXPORT IntersectElement
00101 {
00102 public:
00103 IntersectElement(double val1, double val2, bool start1, bool end1, bool start2, bool end2, Node *node, const Edge& e1, const Edge& e2, bool keepOrder);
00104 IntersectElement(const IntersectElement& other);
00106 bool operator<(const IntersectElement& other) const;
00107 IntersectElement& operator=(const IntersectElement& other);
00108 double getVal1() const { return _chararct_val_for_e1; }
00109 double getVal2() const { return _chararct_val_for_e2; }
00111 bool isLowerOnOther(const IntersectElement& other) const;
00112 unsigned isOnExtrForAnEdgeAndInForOtherEdge() const;
00113 void attachLoc() { _node->setLoc(_loc_of_node); }
00114 bool isOnMergedExtremity() const;
00115 bool isIncludedByBoth() const;
00116 void setNode(Node *node) const;
00117 void performMerging(MergePoints& commonNode) const;
00118 Node *getNodeOnly() const { return _node; }
00119 Node *getNodeAndReleaseIt() { Node *tmp=_node; _node=0; return tmp; }
00120 ~IntersectElement();
00121 private:
00122 bool _1S;
00123 bool _1E;
00124 bool _2S;
00125 bool _2E;
00126 double _chararct_val_for_e1;
00127 double _chararct_val_for_e2;
00128 Node *_node;
00129 TypeOfLocInPolygon _loc_of_node;
00130 const Edge& _e1;
00131 const Edge& _e2;
00132 public:
00133 static const unsigned LIMIT_ALONE = 22;
00134 static const unsigned LIMIT_ON = 73;
00135 static const unsigned NO_LIMIT = 19;
00136 };
00137
00141 class INTERPKERNELGEOMETRIC2D_EXPORT EdgeIntersector
00142 {
00143 protected:
00145 EdgeIntersector(const Edge& e1, const Edge& e2):_e1(e1),_e2(e2) { }
00146 public:
00147 virtual ~EdgeIntersector() { }
00148 virtual bool keepOrder() const = 0;
00150 virtual bool haveTheySameDirection() const = 0;
00152 virtual void getPlacements(Node *start, Node *end, TypeOfLocInEdge& whereStart, TypeOfLocInEdge& whereEnd, MergePoints& commonNode) const = 0;
00154 bool intersect(const Bounds *whereToFind, std::vector<Node *>& newNodes, bool& order, MergePoints& commonNode);
00156 virtual void areOverlappedOrOnlyColinears(const Bounds *whereToFind, bool& obviousNoIntersection, bool& areOverlapped) = 0;
00158 virtual std::list< IntersectElement > getIntersectionsCharacteristicVal() const = 0;
00159 protected:
00160 void obviousCaseForCurvAbscisse(Node *node, TypeOfLocInEdge& where, MergePoints& commonNode, bool& obvious) const;
00161 protected:
00162 const Edge& _e1;
00163 const Edge& _e2;
00164 };
00165
00166 class INTERPKERNELGEOMETRIC2D_EXPORT SameTypeEdgeIntersector : public EdgeIntersector
00167 {
00168 protected:
00169 SameTypeEdgeIntersector(const Edge& e1, const Edge& e2):EdgeIntersector(e1,e2) { }
00170 bool keepOrder() const { return true; }
00171 };
00172
00173 class INTERPKERNELGEOMETRIC2D_EXPORT CrossTypeEdgeIntersector : public EdgeIntersector
00174 {
00175 protected:
00176 CrossTypeEdgeIntersector(const Edge& e1, const Edge& e2, bool reverse):EdgeIntersector(e1,e2),_reverse(reverse) { }
00177 bool keepOrder() const { return _reverse; }
00178 bool haveTheySameDirection() const { throw Exception("Cross type intersector is not supposed to deal with overlapped in cross type."); }
00179 const Edge *myE1() { if(_reverse) return &_e1; else return &_e2; }
00180 const Edge *myE2() { if(_reverse) return &_e2; else return &_e1; }
00181 protected:
00183 bool _reverse;
00184 };
00185
00186 class EdgeLin;
00187 class EdgeInfLin;
00188 class EdgeArcCircle;
00189
00197 class INTERPKERNELGEOMETRIC2D_EXPORT Edge
00198 {
00199 public:
00200 Edge(Node *start, Node *end, bool direction=true):_cnt(1),_loc(FULL_UNKNOWN) { if(direction) { _start=start; _end=end; } else { _start=end; _end=start; } _start->incrRef(); _end->incrRef(); }
00201 Edge(double sX, double sY, double eX, double eY);
00202 TypeOfEdgeLocInPolygon getLoc() const { return _loc; }
00203 void incrRef() const { _cnt++; }
00204 bool decrRef();
00205 void initLocs() const { _loc=FULL_UNKNOWN; _start->initLocs(); _end->initLocs(); }
00206 void declareOn() const;
00207 void declareIn() const;
00208 void declareOut() const;
00209 const Bounds& getBounds() const { return _bounds; }
00210 void fillXfigStreamForLoc(std::ostream& stream) const;
00211 Node *getNode(TypeOfLocInEdge where) const { if(where==START) return _start; else if(where==END) return _end; else return 0; }
00212 Node *getStartNode() const { return _start; }
00213 Node *getEndNode() const { return _end; }
00214 void setEndNodeWithoutChange(Node *newEnd);
00215 void setStartNodeWithoutChange(Node *newStart);
00216 bool changeStartNodeWith(Node *otherStartNode) const;
00217 bool changeStartNodeWithAndKeepTrack(Node *otherStartNode, std::vector<Node *>& track) const;
00218 bool changeEndNodeWith(Node *otherEndNode) const;
00219 bool changeEndNodeWithAndKeepTrack(Node *otherEndNode, std::vector<Node *>& track) const;
00220 void addSubEdgeInVector(Node *start, Node *end, ComposedEdge& vec) const;
00221 void getNormalVector(double *vectOutput) const;
00222 static EdgeIntersector *buildIntersectorWith(const Edge *e1, const Edge *e2);
00223 static Edge *buildFromXfigLine(std::istream& str);
00224 static Edge *buildEdgeFrom(Node *start, Node *end);
00225 template<TypeOfMod4QuadEdge type>
00226 static Edge *buildEdgeFrom(Node *start, Node *middle, Node *end);
00227 virtual void update(Node *m) = 0;
00229 virtual double getAreaOfZone() const = 0;
00231 virtual void applySimilarity(double xBary, double yBary, double dimChar);
00233 virtual double getCurveLength() const = 0;
00234 virtual void getBarycenter(double *bary) const = 0;
00235 virtual void getBarycenterOfZone(double *bary) const = 0;
00237 virtual Node *buildRepresentantOfMySelf() const = 0;
00239 virtual bool isIn(double characterVal) const = 0;
00241 virtual bool isLower(double val1, double val2) const = 0;
00243 virtual double getCharactValue(const Node& node) const = 0;
00245 virtual double getDistanceToPoint(const double *pt) const = 0;
00247 virtual bool isNodeLyingOn(const double *coordOfNode) const = 0;
00248 virtual TypeOfFunction getTypeOfFunc() const = 0;
00249 virtual void dynCastFunction(const EdgeLin * &seg,
00250 const EdgeArcCircle * &arcSeg) const = 0;
00251 bool intersectWith(const Edge *other, MergePoints& commonNode,
00252 ComposedEdge& outVal1, ComposedEdge& outVal2) const;
00253 static bool intersectOverlapped(const Edge *f1, const Edge *f2, EdgeIntersector *intersector, MergePoints& commonNode,
00254 ComposedEdge& outValForF1, ComposedEdge& outValForF2);
00255 static void interpolate1DLin(const std::vector<double>& distrib1, const std::vector<double>& distrib2,
00256 std::map<int, std::map<int,double> >& result);
00257 virtual void dumpInXfigFile(std::ostream& stream, bool direction, int resolution, const Bounds& box) const = 0;
00258 protected:
00259 Edge():_cnt(1),_loc(FULL_UNKNOWN),_start(0),_end(0) { }
00260 virtual ~Edge();
00261 static int combineCodes(TypeOfLocInEdge code1, TypeOfLocInEdge code2);
00262 static bool intersect(const Edge *f1, const Edge *f2, EdgeIntersector *intersector, const Bounds *whereToFind, MergePoints& commonNode,
00263 ComposedEdge& outValForF1, ComposedEdge& outValForF2);
00265 static bool splitOverlappedEdges(const Edge *e1, const Edge *e2, Node *nS, Node *nE, bool direction, int code,
00266 ComposedEdge& outVal1, ComposedEdge& outVal2);
00267 virtual Edge *buildEdgeLyingOnMe(Node *start, Node *end, bool direction=true) const = 0;
00268 protected:
00269 mutable unsigned char _cnt;
00270 mutable TypeOfEdgeLocInPolygon _loc;
00271 Bounds _bounds;
00272 Node *_start;
00273 Node *_end;
00274 protected:
00275
00276 static const int OFFSET_FOR_TYPEOFLOCINEDGE = 8;
00277 };
00278 }
00279
00280 #endif