Compounds | |
| struct | gugr::_cut_info |
| struct | gugr::_cut_record |
| struct | gugr::contour_node |
| class | gugr::Dump |
| class | gugr::dump_graph |
| class | gugr::dump_segs |
| class | gugr::DumpPS |
| struct | gugr::edge_interval |
| struct | gugr::edge_interval_tree |
| struct | gugr::eventrec |
| struct | gugr::graph_edge |
| struct | gugr::graph_vertex |
| struct | gugr::GraphConvInfo |
| struct | gugr::GraphInfo |
| struct | gugr::intersection |
| struct | gugr::intersectionseg |
| struct | gugr::line |
| struct | gugr::line_rep |
| struct | gugr::linepair |
| struct | gugr::linerec |
| struct | gugr::monpoly_info |
| struct | gugr::polyline |
| struct | gugr::seg_point_info |
| struct | gugr::segment |
| struct | gugr::segnode |
| struct | gugr::segtree |
| struct | gugr::triangle |
| struct | gugr::vertex |
| struct | gugr::vertex_rep |
Typedefs | |
| typedef List< graph_vertex > | graph_vertex_list |
| typedef List2< graph_vertex > | graph_vertex_list2 |
| typedef List< graph_edge > | graph_edge_list |
| typedef gugr::_cut_record | cut_record |
| typedef List< cut_record > | cut_record_list |
| typedef gugr::_cut_info | cut_info |
| typedef List< triangle > | triangle_list |
| typedef gul::List< gul::ListNode< segment > > | segment_list |
| typedef GraphInfo * | GraphInfo4 [4] |
Functions | |
| bool | intersect_nonvert (const line &a, const line &b, point2< rational > &I) |
| bool | intersect_vert (const rational &x0, const line &b, point2< rational > &I) |
| bool | intersect_horiz (const rational &y0, const line &b, point2< rational > &I) |
| bool | intersect (const line &a, const line &b, point2< rational > &I) |
| template<class T> void | PolygonToGraph (const int n, gul::Ptr< gul::point2< T > > P, const T orgx, const T orgy, const T scalex, const T scaley, int fleft, int fright, graph_edge_list *E, graph_vertex_list *V) |
| template void | PolygonToGraph (const int n, gul::Ptr< gul::point2< float > > P, const float orgx, const float orgy, const float scalex, const float scaley, int fleft, int fright, graph_edge_list *E, graph_vertex_list *V) |
| template void | PolygonToGraph (const int n, gul::Ptr< gul::point2< double > > P, const double orgx, const double orgy, const double scalex, const double scaley, int fleft, int fright, graph_edge_list *E, graph_vertex_list *V) |
| template<class T> void | PolygonToGraphNV (const int n, gul::Ptr< gul::point2< T > > P, const T orgx, const T orgy, const T scalex, const T scaley, int fleft, int fright, graph_edge_list *E, graph_vertex_list *V) |
| template void | PolygonToGraphNV (const int n, gul::Ptr< gul::point2< float > > P, const float orgx, const float orgy, const float scalex, const float scaley, int fleft, int fright, graph_edge_list *E, graph_vertex_list *V) |
| template void | PolygonToGraphNV (const int n, gul::Ptr< gul::point2< double > > P, const double orgx, const double orgy, const double scalex, const double scaley, int fleft, int fright, graph_edge_list *E, graph_vertex_list *V) |
| int | IncidentEdges (const graph_vertex *v, graph_edge **A) |
| int | EdgeCycle (graph_edge *e, graph_vertex *v, graph_edge **A) |
| void | OrientEdge (graph_edge *e) |
| void | OrientEdges (graph_edge *E) |
| int | DetermineOrientation (const point2< rational > &A, const point2< rational > &B, const point2< rational > &C) |
| int | DetermineOrientationPV (const point2< rational > &A, const point2< rational > &AB, const point2< rational > &C) |
| int | CompareAngles (const point2< rational > &A, const point2< rational > &B, const point2< rational > &C, const point2< rational > &D, int *match, int *code_c, int *code_d) |
| int | EdgeInsertPosition (const vertex &a, const vertex &b, int nE, graph_edge **E, int *eleft, int *eright, int *code_left, int *code_right) |
| void | ConnectEdge (graph_edge *e, int maxE) |
| int | DisconnectEdge (graph_edge *e, int maxE) |
| int | coord2int (double f, unsigned long *buf) |
| int | coord2int (float f, unsigned long *buf) |
| template<class T> T | cnv2coord (const T &i) |
| template<class T> void | cnv2coord_rnd (rational &f, T *ret) |
| bool | operator== (const vertex &a, const vertex &b) |
| bool | parallel (const line &a, const line &b) |
| void | CT_DoAboveEdge (graph_edge *e, graph_vertex *v, contour_node **pCA, contour_node **pCB) |
| void | CT_DoBelowEdge (graph_edge *e, graph_vertex *v, contour_node **pCA, contour_node **pCB) |
| void | ContainmentTree (List< ListNode< segment > > &insegs, const rational &far_maxx, const rational &far_maxy, gul::List< contour_node > &contours, contour_node &universe) |
| void | IntersectionSubTree (contour_node *C, int oset, int InA, int InB, List< ListNode< gul::polyline< point2< rational > > > > &pl) |
| void | UnionSubTree (contour_node *C, int oset, int OutA, int OutB, List< ListNode< gul::polyline< point2< rational > > > > &pl) |
| void | DifferenceSubTree (contour_node *C, int oset, int InA, int OutB, List< ListNode< gul::polyline< point2< rational > > > > &pl) |
| GULAPI void | DoIntersection (List< ListNode< polyline > > &PA, List< ListNode< polyline > > &PB, const rational &far_x, const rational &far_y, List< ListNode< gul::polyline< point2< rational > > > > &C) |
| GULAPI void | DoUnion (List< ListNode< polyline > > &PA, List< ListNode< polyline > > &PB, const rational &far_x, const rational &far_y, List< ListNode< gul::polyline< point2< rational > > > > &C) |
| GULAPI void | DoDifference (List< ListNode< polyline > > &PA, List< ListNode< polyline > > &PB, const rational &far_x, const rational &far_y, List< ListNode< gul::polyline< point2< rational > > > > &C) |
| template<class T> GULAPI void | ConvertToRationalPolys (List< ListNode< gul::polyline< point2< T > > > > &A, List< ListNode< gul::polyline< point2< T > > > > &B, T *ret_minx, T *ret_miny, T *ret_scale, rational *ret_far_x, rational *ret_far_y, List< ListNode< gugr::polyline > > &PA, List< ListNode< gugr::polyline > > &PB) |
| template GULAPI void | ConvertToRationalPolys (List< ListNode< gul::polyline< point2< float > > > > &A, List< ListNode< gul::polyline< point2< float > > > > &B, float *ret_minx, float *ret_miny, float *ret_scale, rational *ret_far_x, rational *ret_far_y, List< ListNode< gugr::polyline > > &PA, List< ListNode< gugr::polyline > > &PB) |
| template GULAPI void | ConvertToRationalPolys (List< ListNode< gul::polyline< point2< double > > > > &A, List< ListNode< gul::polyline< point2< double > > > > &B, double *ret_minx, double *ret_miny, double *ret_scale, rational *ret_far_x, rational *ret_far_y, List< ListNode< gugr::polyline > > &PA, List< ListNode< gugr::polyline > > &PB) |
| template<class T> GULAPI void | ConvertToFloatPoly (List< ListNode< gul::polyline< point2< rational > > > > &inA, T minx, T miny, T scale, List< ListNode< gul::polyline< point2< T > > > > &outA) |
| template GULAPI void | ConvertToFloatPoly (List< ListNode< gul::polyline< point2< rational > > > > &inA, float minx, float miny, float scale, List< ListNode< gul::polyline< point2< float > > > > &outA) |
| template GULAPI void | ConvertToFloatPoly (List< ListNode< gul::polyline< point2< rational > > > > &inA, double minx, double miny, double scale, List< ListNode< gul::polyline< point2< double > > > > &outA) |
| GULAPI void | DoIntersection (gul::List< gul::ListNode< gugr::polyline > > &PA, gul::List< gul::ListNode< gugr::polyline > > &PB, const rational &far_x, const rational &far_y, gul::List< gul::ListNode< gul::polyline< gul::point2< rational > > > > &C) |
| template<class T> void | Intersection (gul::List< gul::ListNode< gul::polyline< gul::point2< T > > > > &fPA, gul::List< gul::ListNode< gul::polyline< gul::point2< T > > > > &fPB, gul::List< gul::ListNode< gul::polyline< gul::point2< T > > > > &fPC) |
| template<class T> void | Union (gul::List< gul::ListNode< gul::polyline< gul::point2< T > > > > &fPA, gul::List< gul::ListNode< gul::polyline< gul::point2< T > > > > &fPB, gul::List< gul::ListNode< gul::polyline< gul::point2< T > > > > &fPC) |
| template<class T> void | Difference (gul::List< gul::ListNode< gul::polyline< gul::point2< T > > > > &fPA, gul::List< gul::ListNode< gul::polyline< gul::point2< T > > > > &fPB, gul::List< gul::ListNode< gul::polyline< gul::point2< T > > > > &fPC) |
| void | AppendContour (polyline *c, int keyleft, int keyright, List< ListNode< segment > > &segs) |
| template<class EP> void | AppendContourFNT (polyline *c, Ptr< EP > &F, Ptr< EP > &N, Ptr< EP > &T, int keyleft, int keyright, List< ListNode< segment > > &segs) |
| template void | AppendContourFNT (polyline *c, Ptr< point< float > > &F, Ptr< point< float > > &N, Ptr< point< float > > &T, int keyleft, int keyright, List< ListNode< segment > > &segs) |
| template void | AppendContourFNT (polyline *c, Ptr< point< double > > &F, Ptr< point< double > > &N, Ptr< point< double > > &T, int keyleft, int keyright, List< ListNode< segment > > &segs) |
| void | LeftSideContour (graph_edge *e, graph_edge_list &E, contour_node *cn) |
| void | RightSideContour (graph_edge *e, graph_edge_list &E, contour_node *cn) |
| void | FindContours (graph_edge_list &E, graph_vertex_list &V, const rational &far_maxx, const rational &far_maxy, List< ListNode< segment > > &outsegs, List< contour_node > &contours) |
| void | RemoveUnnecessaryEdges (graph_edge_list &E, graph_vertex_list &V, const rational &far_maxx, const rational &far_maxy, int key_inside, int key_outside, List< ListNode< segment > > &outsegs) |
| GULAPI void | OddEvenRule (List< ListNode< polyline > > &inC, const rational &far_maxx, const rational &far_maxy, int key_inside, int key_outside, graph_edge_list &E, graph_vertex_list &V, List< ListNode< segment > > &outsegs) |
| template<class T> GULAPI bool | CalcPlane (int nVerts, const Ptr< point< T > > &Verts, point< T > &o, point< T > &b1, point< T > &b2, point< T > &b3) |
| template GULAPI bool | CalcPlane (int nVerts, const Ptr< point< float > > &Verts, point< float > &o, point< float > &b1, point< float > &b2, point< float > &b3) |
| template GULAPI bool | CalcPlane (int nVerts, const Ptr< point< double > > &Verts, point< double > &o, point< double > &b1, point< double > &b2, point< double > &b3) |
| template<class T> GULAPI bool | CheckLeftHandedness (int nP, const Ptr< point< T > > &P, const Ptr< Ptr< T > > &Ti, bool &lefthanded, bool &selfintersect) |
| template GULAPI bool | CheckLeftHandedness (int nP, const Ptr< point< float > > &P, const Ptr< Ptr< float > > &Ti, bool &lefthanded, bool &selfintersect) |
| template GULAPI bool | CheckLeftHandedness (int nP, const Ptr< point< double > > &P, const Ptr< Ptr< double > > &Ti, bool &lefthanded, bool &selfintersect) |
| template<class T> void | Polygon3dTo2d (const List< ListNode< gul::polyline< point< T > > > > &C3, const Ptr< Ptr< T > > &Ti, List< ListNode< gul::polyline< point2< T > > > > &C2) |
| template void | Polygon3dTo2d (const List< ListNode< gul::polyline< point< float > > > > &C3, const Ptr< Ptr< float > > &Ti, List< ListNode< gul::polyline< point2< float > > > > &C2) |
| template void | Polygon3dTo2d (const List< ListNode< gul::polyline< point< double > > > > &C3, const Ptr< Ptr< double > > &Ti, List< ListNode< gul::polyline< point2< double > > > > &C2) |
| template<class T> GULAPI void | TriangulatePolygon3d (const List< ListNode< gul::polyline< point< T > > > > &C3, const List< ListNode< gul::polyline< point< T > > > > &N3, const List< ListNode< gul::polyline< point< T > > > > &T3, const Ptr< Ptr< T > > &Ti, Ptr< point2< T > > &D, Ptr< point< T > > &F, Ptr< point< T > > &N, Ptr< point< T > > &Tx, int *nTri, Ptr< itriangle > &Tri) |
| template GULAPI void | TriangulatePolygon3d< float > (const List< ListNode< gul::polyline< point< float > > > > &C3, const List< ListNode< gul::polyline< point< float > > > > &N3, const List< ListNode< gul::polyline< point< float > > > > &T3, const Ptr< Ptr< float > > &Ti, Ptr< point2< float > > &D, Ptr< point< float > > &F, Ptr< point< float > > &N, Ptr< point< float > > &Tx, int *nTri, Ptr< itriangle > &Tri) |
| template GULAPI void | TriangulatePolygon3d< double > (const List< ListNode< gul::polyline< point< double > > > > &C3, const List< ListNode< gul::polyline< point< double > > > > &N3, const List< ListNode< gul::polyline< point< double > > > > &T3, const Ptr< Ptr< double > > &Ti, Ptr< point2< double > > &D, Ptr< point< double > > &F, Ptr< point< double > > &N, Ptr< point< double > > &Tx, int *nTri, Ptr< itriangle > &Tri) |
| template<class T> GULAPI void | TriangulatePolygon3d (const gul::List< gul::ListNode< gul::polyline< point< T > > > > &C3, const gul::List< gul::ListNode< gul::polyline< point< T > > > > &N3, const gul::List< gul::ListNode< gul::polyline< point< T > > > > &T3, const Ptr< Ptr< T > > &Ti, Ptr< point2< T > > &D, Ptr< point< T > > &F, Ptr< point< T > > &N, Ptr< point< T > > &Tx, int *nTri, Ptr< gul::itriangle > &Tri) |
| std::ostream & | operator<< (std::ostream &s, gugr::dump_graph &g) |
| void | dump_segment (segment *S, std::ostream &s) |
| std::ostream & | operator<< (std::ostream &s, gugr::dump_segs &S) |
| int | compare_point_to_linerec (point2< rational > *P, linerec *L) |
| int | compare_linerec_to_linerec (linerec *L1, linerec *L2) |
| int | compare_point_to_eventrec (point2< rational > *C, eventrec *E) |
| int | compare_segment_to_linerec (segment *S, linerec *L) |
| int | hcompare_point_to_intersection (point2< rational > *C, intersection *R) |
| int | vcompare_point_to_intersection (point2< rational > *C, intersection *R) |
| int | compare_pointer_to_pointer (void *p1, void *p2) |
| intersection * | intersect (Map< linerec >::Node L1, Map< linerec >::Node L2, const rational &xleft, Map< eventrec > *EvQ, List< intersection > *Ipts) |
| intersection * | intersect_vert (linerec *vL, Map< linerec >::Node L, List< intersection > *Ipts) |
| void | finish_line (linerec *L, graph_edge_list *E, graph_vertex_list *V, int maxE, List< intersection > *Ipts, List< intersectionseg > *Isegs) |
| void | finish_vertline (linerec *L, graph_edge_list *E, graph_vertex_list *V, int maxE, List< intersection > *Ipts, List< intersectionseg > *Isegs) |
| void | DoIntersectSegments (int nsegs, Map< eventrec > &EvQ, gugr::graph_edge_list *E, gugr::graph_vertex_list *V) |
| void | IntersectSegments (int nsegs, Ptr< segment > segs, gugr::graph_edge_list *E, gugr::graph_vertex_list *V) |
| void | ISDeleteOwnerMaps (gugr::graph_edge_list &E) |
| void | ISDeleteBackpointers (gugr::graph_edge_list &E) |
| void | IntersectSegments (gul::List< gul::ListNode< segment > > &segs, gugr::graph_edge_list *E, gugr::graph_vertex_list *V, bool need_backpointers) |
| int | compare_vertices (void *p1, void *p2, void *data) |
| graph_vertex * | SortVertices (graph_vertex_list *V) |
| const graph_edge | NegInf (0,(graph_vertex *)(-1)) |
| const graph_edge | PosInf (0,(graph_vertex *)(+1)) |
| int | CompareEdgesBU (const graph_edge *A, const graph_edge *B) |
| int | CompareEdgesTD (const graph_edge *A, const graph_edge *B) |
| int | compare_edge_to_intervalBU (void *p1, void *p2) |
| int | compare_edge_to_intervalTD (void *p1, void *p2) |
| void | EdgeInsert (graph_edge *e, int maxE) |
| void | Regularize (graph_edge_list *E, graph_vertex_list *V) |
| int | compare_cut_records (void *p1, void *p2, void *data) |
| void | sort_cut_records (int ns, Ptr< cut_info > S) |
| void | IntersectWithAscendant (const point2< rational > &A, const point2< rational > &B, const graph_edge_list &E, const graph_vertex_list &V, line &L, cut_record_list &R) |
| void | InsertDiagonal (graph_edge_list *E, graph_vertex_list *V, graph_vertex *P11, graph_vertex *P22) |
| int | FindCutInfo (rational &x, int nA, const Ptr< cut_info > &A, bool &found) |
| void | IntersectWithHorizontals (graph_edge_list *E, graph_vertex_list *V, const int nS, Ptr< cut_info > S) |
| void | DivideHorizontalStrips (cut_info *Sa, cut_info *Sb, int maxE, const rational &minx, const rational maxx, const rational &far_left, const rational &far_right, graph_vertex **minSaV, graph_vertex **minSbV, graph_vertex **maxSaV, graph_vertex **maxSbV) |
| void | IntersectWithVerticals (graph_edge_list *E, graph_vertex_list *V, const int nS, Ptr< cut_info > S) |
| void | DivideVerticalStrips (cut_info *Sb, cut_info *Sa, int maxE, const rational &miny, const rational maxy, const rational &far_bottom, const rational &far_top, graph_vertex **minSbV, graph_vertex **minSaV, graph_vertex **maxSbV, graph_vertex **maxSaV) |
| template<class T> void | SplitGraph (GraphInfo *G, T xmed, T ymed, GraphConvInfo< T > *Gconv, GraphInfo4 &sub) |
| template void | SplitGraph (GraphInfo *G, float xmed, float ymed, GraphConvInfo< float > *Gconv, GraphInfo4 &sub) |
| template void | SplitGraph (GraphInfo *G, double xmed, double ymed, GraphConvInfo< double > *Gconv, GraphInfo4 &sub) |
| template<class T> void | InitGraph (const rational &X1, const rational &X2, const rational &Y1, const rational &Y2, GraphConvInfo< T > *Gconv, graph_edge_list *E, graph_vertex_list *V, GraphInfo *G) |
| template void | InitGraph (const rational &X1, const rational &X2, const rational &Y1, const rational &Y2, GraphConvInfo< float > *Gconv, graph_edge_list *E, graph_vertex_list *V, GraphInfo *G) |
| template void | InitGraph (const rational &X1, const rational &X2, const rational &Y1, const rational &Y2, GraphConvInfo< double > *Gconv, graph_edge_list *E, graph_vertex_list *V, GraphInfo *G) |
| void | Triangulate (graph_edge_list *E, graph_vertex_list *V, const rational &far_left, triangle_list *T) |
| void | TriangulateMonotonePolygon (graph_vertex_list2 *V1, graph_vertex_list2 *V2, graph_edge_list *E, triangle_list *T) |
|
|
|
|
|
|
|
|
Definition at line 408 of file gugr_basics.h. Referenced by gugr::_cut_record::operator delete(). |
|
|
Definition at line 383 of file gugr_basics.h. Referenced by gugr::monpoly_info::AppendRight(), gugr::edge_interval_tree::dump_edge_interval(), gugr::DumpPS::dump_edges(), gugr::dump_graph::dump_graph(), gugr::GraphInfo::operator delete(), gugr::seg_point_info::operator delete(), and gugr::graph_edge::operator delete(). |
|
|
Definition at line 332 of file gugr_basics.h. Referenced by gugr::monpoly_info::AppendRight(), gugr::edge_interval_tree::dump_edge_interval(), gugr::dump_graph::dump_graph(), gugr::GraphInfo::operator delete(), gugr::seg_point_info::operator delete(), and gugr::graph_vertex::operator delete(). |
|
|
Definition at line 333 of file gugr_basics.h. Referenced by gugr::graph_vertex::operator delete(). |
|
|
Definition at line 67 of file gugr_split.h. Referenced by gugr::GraphInfo::operator delete(). |
|
|
Definition at line 74 of file gugr_planesweep.h. |
|
|
Definition at line 442 of file gugr_basics.h. Referenced by gugr::triangle::operator delete(). |
|
||||||||||||||||||||
|
Definition at line 51 of file gugr_contour.cpp.
00053 {
00054 int i;
00055 ListNode<segment> *sn;
00056 segment *s;
00057 rational x1,x2,y1,y2;
00058 bool swap;
00059
00060 // travert vertices of contour
00061 for( i = 0; i < c->nVerts; i++ )
00062 {
00063 sn = new ListNode<segment>;
00064 segs.Append( sn );
00065
00066 s = &sn->el;
00067
00068 s->l = c->lines[i]; // use existing line equation
00069 s->f[0].set_i(keyleft);
00070 s->f[1].set_i(keyright);
00071 s->m = 1; // set multiplicity to 1
00072
00073 x1 = c->verts[i].x;
00074 y1 = c->verts[i].y;
00075 if( i+1 == c->nVerts )
00076 {
00077 x2 = c->verts[0].x;
00078 y2 = c->verts[0].y;
00079 }
00080 else
00081 {
00082 x2 = c->verts[i+1].x;
00083 y2 = c->verts[i+1].y;
00084 }
00085
00086 // orient the edges as the planesweep algorithm expects them
00087
00088 if( c->lines[i].IsVertical() )
00089 swap = (compare( y1, y2 ) > 0);
00090 else
00091 swap = (compare( x1, x2 ) > 0);
00092
00093 if( swap )
00094 {
00095 Swap(x1,x2);
00096 Swap(y1,y2);
00097 Swap(s->f[0],s->f[1]);
00098 }
00099
00100 s->B.x = x1;
00101 s->B.y = y1;
00102 s->E.x = x2;
00103 s->E.y = y2;
00104 }
00105 }
|
|
||||||||||||||||||||||||||||||||
|
|
|
||||||||||||||||||||||||||||||||
|
|
|
||||||||||||||||||||||||||||||||||||
|
Definition at line 108 of file gugr_contour.cpp.
00110 {
00111 int i;
00112 ListNode<segment> *sn;
00113 segment *s;
00114 rational x1,x2,y1,y2;
00115 bool swap;
00116 seg_point_info<EP> *spi;
00117
00118 // travert vertices of contour
00119 for( i = 0; i < c->nVerts; i++ )
00120 {
00121 sn = new ListNode<segment>;
00122 segs.Append( sn );
00123
00124 s = &sn->el;
00125
00126 s->l = c->lines[i]; // use existing line equation
00127 s->f[0].set_i(keyleft);
00128 s->f[1].set_i(keyright);
00129 spi = new seg_point_info<EP>;
00130 spi->f = &F[i];
00131 spi->n = &N[i];
00132 spi->t = &T[i];
00133 s->reserved[0] = spi;
00134
00135 s->m = 1; // set multiplicity to 1
00136
00137 x1 = c->verts[i].x;
00138 y1 = c->verts[i].y;
00139 if( i+1 == c->nVerts )
00140 {
00141 x2 = c->verts[0].x;
00142 y2 = c->verts[0].y;
00143 spi = new seg_point_info<EP>;
00144 spi->f = &F[0];
00145 spi->n = &N[0];
00146 spi->t = &T[0];
00147 s->reserved[1] = spi;
00148 }
00149 else
00150 {
00151 x2 = c->verts[i+1].x;
00152 y2 = c->verts[i+1].y;
00153 spi = new seg_point_info<EP>;
00154 spi->f = &F[i+1];
00155 spi->n = &N[i+1];
00156 spi->t = &T[i+1];
00157 s->reserved[1] = spi;
00158 }
00159
00160 // orient the edges as the planesweep algorithm expects them
00161
00162 if( c->lines[i].IsVertical() )
00163 swap = (compare( y1, y2 ) > 0);
00164 else
00165 swap = (compare( x1, x2 ) > 0);
00166
00167 if( swap )
00168 {
00169 Swap(x1,x2);
00170 Swap(y1,y2);
00171 Swap(s->f[0],s->f[1]);
00172 Swap(s->reserved[0],s->reserved[1]);
00173 }
00174
00175 s->B.x = x1;
00176 s->B.y = y1;
00177 s->E.x = x2;
00178 s->E.y = y2;
00179 }
00180 }
|
|
||||||||||||||||||||||||||||
|
|
|
||||||||||||||||||||||||||||
|
|
|
||||||||||||||||||||||||||||||||
|
Definition at line 143 of file gugr_face.cpp.
00146 {
00147 Interval ix0,iy0,iz0,ix1,iy1,iz1,ix2,iy2,iz2,ibx1,iby1,ibz1,ibx2,iby2,ibz2;
00148 Interval ilen,ilen2,inx,iny,inz;
00149 double rat,rat1;
00150 int i0,i1,i2,irat0,irat1,irat2;
00151 point<T> v1,v2;
00152
00153 irat0 = -1;
00154 rat = rtr<double>::giant(); // start with a gigantic ratio
00155
00156 for( i0 = 0; i0 < nVerts; i0++ )
00157 {
00158 ix0 = Verts[i0].x;
00159 iy0 = Verts[i0].y;
00160 iz0 = Verts[i0].z;
00161
00162 i1 = i0+1; if( i1 == nVerts ) i1 = 0;
00163 i2 = i1+1; if( i2 == nVerts ) i2 = 0;
00164
00165 // calc first basis vector
00166
00167 ix1 = Verts[i1].x;
00168 iy1 = Verts[i1].y;
00169 iz1 = Verts[i1].z;
00170
00171 ibx1 = ix1 - ix0;
00172 iby1 = iy1 - iy0;
00173 ibz1 = iz1 - iz0;
00174
00175 // normalize b1
00176
00177 ilen2 = ibx1*ibx1 + iby1*iby1 + ibz1*ibz1;
00178 ilen = Sqrt( ilen2 );
00179 if( Test(ilen)==0 ) continue; // avoid division by zero
00180
00181 ibx1 = ibx1 / ilen;
00182 iby1 = iby1 / ilen;
00183 ibz1 = ibz1 / ilen;
00184
00185 // calc second basis vector of plane
00186
00187 ix2 = Verts[i2].x;
00188 iy2 = Verts[i2].y;
00189 iz2 = Verts[i2].z;
00190
00191 ibx2 = ix2 - ix0;
00192 iby2 = iy2 - iy0;
00193 ibz2 = iz2 - iz0;
00194
00195 // project vector onto b1
00196
00197 ilen = ibx2*ibx1 + iby2*iby1 + ibz2*ibz1;
00198
00199 // get the component orthogonal to b1
00200
00201 ibx2 = ibx2 - ilen * ibx1;
00202 iby2 = iby2 - ilen * iby1;
00203 ibz2 = ibz2 - ilen * ibz1;
00204
00205 // normalize b2
00206
00207 ilen2 = ibx2*ibx2 + iby2*iby2 + ibz2*ibz2;
00208 ilen = Sqrt( ilen2 );
00209 if( Test(ilen)==0 ) continue; // avoid division by zero
00210
00211 ibx2 = ibx2 / ilen;
00212 iby2 = iby2 / ilen;
00213 ibz2 = ibz2 / ilen;
00214
00215 // calculate the crossproduct of b1 and b2
00216
00217 inx = iby1*ibz2 - ibz1*iby2;
00218 iny = ibz1*ibx2 - ibx1*ibz2;
00219 inz = ibx1*iby2 - iby1*ibx2;
00220
00221 // normalize it (superfluous since b1 and b2 are orthonormal)
00222
00223 ilen2 = inx*inx + iny*iny + inz*inz;
00224 ilen = Sqrt( ilen2 );
00225 if( Test(ilen)==0 ) continue;
00226
00227 inx = inx / ilen;
00228 iny = iny / ilen;
00229 inz = inz / ilen;
00230
00231 rat1 = GetRatio(inx*inx + iny*iny + inz*inz);
00232 if( rat1 < rat )
00233 {
00234 rat = rat1;
00235 irat0 = i0;
00236 irat1 = i1;
00237 irat2 = i2;
00238 }
00239 }
00240 if( (irat0 < 0) || (rat == rtr<double>::giant()) ) return false;
00241 i0 = irat0;
00242 i1 = irat1;
00243 i2 = irat2;
00244
00245 // the same calculation as above, now with floating point arithmetic
00246
00247 o = Verts[i0];
00248 v1 = Verts[i1] - o;
00249 v2 = Verts[i2] - o;
00250 normalize(&b1,v1);
00251 b2 = v2 - (v2*b1)*b1;
00252 normalize(&b2,b2);
00253 b3 = cross_product(b1,b2);
00254 normalize(&b3,b3);
00255
00256 return true;
00257 }
|
|
||||||||||||||||||||||||
|
|
|
||||||||||||||||||||||||
|
|
|
||||||||||||||||||||||||||||
|
Definition at line 272 of file gugr_face.cpp.
00275 {
00276 polyline pl;
00277 Ptr< point2<T> > P2;
00278 Ptr<T> v3,v2;
00279 List< ListNode<segment> > segs,outsegs;
00280 ListNode<segment> *seg;
00281 graph_edge_list E;
00282 graph_vertex_list V;
00283 rational far_minx,far_maxx,far_miny,far_maxy;
00284 T minx,maxx,miny,maxy;
00285 T dx,dy,scale,scalei;
00286 int i,left;
00287 List< ListNode< ListNodeInfo< ListNode<graph_edge *> > > > *L;
00288 graph_edge *e;
00289 List< ListNode<graph_edge *> > *Le;
00290 unsigned long *cbuf =
00291 (unsigned long *)alloca(gul::rtr<T>::mantissa_length());
00292
00293 if( !nP ) return false;
00294
00295 // project vertices onto plane
00296
00297 P2.reserve_pool(nP);
00298 v3.reserve_pool(4);
00299 v2.reserve_pool(4);
00300
00301 for( i = 0; i < nP; i++ )
00302 {
00303 v3[0] = P[i].x;
00304 v3[1] = P[i].y;
00305 v3[2] = P[i].z;
00306 v3[3] = (T)1;
00307
00308 VMProduct(4,4,v3,Ti,v2);
00309
00310 P2[i].x = v2[0];
00311 P2[i].y = v2[1];
00312 }
00313
00314 CalcBoundingBoxE( nP, P2, minx, maxx, miny, maxy );
00315
00316 dx = maxx - minx;
00317 dy = maxy - miny;
00318 scale = dx > dy ? dx : dy;
00319 minx -= scale;
00320 miny -= scale;
00321 scalei = (T)1.0/scale;
00322
00323 /*
00324 Dump<float>::set_transformation(minx,miny,scale,scale);
00325 */
00326
00327 pl.init( nP, P2, minx, miny, scalei );
00328
00329 AppendContour( &pl, 0, 1, segs );
00330
00331 IntersectSegments( segs, &E, &V, true );
00332
00333 /*
00334 std::cout << "EDGES AFTER INTERSECTION\n";
00335 std::cout << "========================\n";
00336 Dump<float>::dump_edges( E.head );
00337 std::cout << "\n";
00338 */
00339
00340 far_miny = far_minx = rational( guar::ULong(0x100000), -1 );
00341 far_maxy = far_maxx = rational( coord2int((T)2,cbuf),cbuf) +
00342 rational( guar::ULong(0x100000) );
00343
00344 RemoveUnnecessaryEdges( E, V, far_maxx, far_maxy, 1, 0, outsegs );
00345
00346 e = E.First(); if( !e ) return false; // internal error
00347
00348 // backpointer to the segment edge lists which contain the fist edge
00349 L = (List< ListNode< ListNodeInfo< ListNode<graph_edge *> > > > *)
00350 e->reserved[1].p;
00351 // the first backpointed List
00352 Le = L->First()->el.m_L;
00353
00354 // find the corresponding segment
00355 for( seg = segs.First(); seg != 0; seg = seg->next )
00356 if( &seg->el.e == Le ) break;
00357
00358 if( !seg ) return false; // internal error
00359
00360 if( e->l.IsHorizontal() || (e->l.dx().test() < 0) )
00361 left = e->f[1].i; // edge orientation different
00362 else
00363 left = e->f[0].i;
00364
00365 lefthanded = (left != 1);
00366
00367 // check if there were self-intersections
00368
00369 for( seg = segs.First(); seg != 0; seg = seg->next )
00370 if( seg->el.e.nElems != 1 ) break;
00371
00372 selfintersect = (seg != 0);
00373
00374 // delete data which would not be automatically destructed
00375
00376 e = E.First();
00377 while( e ) // delete backpointer lists
00378 {
00379 L = (List< ListNode< ListNodeInfo< ListNode<graph_edge *> > > > *)
00380 e->reserved[1].p;
00381 L->DeleteElems();
00382 delete L;
00383 e->reserved[1].p = 0;
00384 e = e->next;
00385 }
00386
00387 return true;
00388 }
|
|
||||||||||
|
Definition at line 86 of file gugr_basics.h.
00087 {
00088 return i * gul::rtr<T>::epsilon() + (T)1.0;
00089 }
|
|
||||||||||||||||
|
Definition at line 96 of file gugr_basics.h.
00097 {
00098 rational q,r,rd,h;
00099 T flt;
00100
00101 f.div_mod(&q,&r);
00102
00103 rd = r/f.denominator();
00104 h = rational(ULong(1))/rational(ULong(2));
00105
00106 if( compare(rd,h) >= 0 )
00107 q = q + rational(ULong(1));
00108
00109 guar::IntTo<T>(q.m->m_na,q.m->m_a,flt);
00110
00111 *ret = cnv2coord(flt);
00112 }
|
|
||||||||||||||||
|
Definition at line 45 of file gugr_split.cpp.
00046 {
00047 rational &r1 = ((cut_record *)p1)->val, &r2 = ((cut_record *)p2)->val;
00048 int sign;
00049
00050 sign = compare( r1, r2 );
00051 return(sign);
00052 }
|
|
||||||||||||
|
Definition at line 220 of file gugr_regularize.cpp. Referenced by gugr::edge_interval_tree::dump_edge_interval().
00221 {
00222 graph_edge *e = (graph_edge *)p1;
00223 edge_interval *ei = (edge_interval *)p2;
00224
00225 if( CompareEdgesBU( e, ei->l ) <= 0 )
00226 return(-1);
00227 if( CompareEdgesBU( e, ei->r ) < 0 )
00228 return(0);
00229
00230 return(1);
00231 }
|
|
||||||||||||
|
Definition at line 232 of file gugr_regularize.cpp. Referenced by gugr::edge_interval_tree::dump_edge_interval().
00233 {
00234 graph_edge *e = (graph_edge *)p1;
00235 edge_interval *ei = (edge_interval *)p2;
00236
00237 if( CompareEdgesTD( e, ei->l ) <= 0 )
00238 return(-1);
00239 if( CompareEdgesTD( e, ei->r ) < 0 )
00240 return(0);
00241
00242 return(1);
00243 }
|
|
||||||||||||
|
Definition at line 68 of file gugr_planesweep.cpp.
00069 {
00070 int sign = DetermineOrientation(L2->B, L2->E, L1->B );
00071 if( sign == 0 )
00072 sign = DetermineOrientation(L2->B, L2->E, L1->E );
00073 return sign;
00074 }
|
|
||||||||||||
|
Definition at line 75 of file gugr_planesweep.cpp. Referenced by gugr::DumpPS::dump_point(), and gugr::segtree::leaves_to_array().
00076 {
00077 int sign = compare( C->x, E->key.x );
00078 if( sign == 0 ) sign = compare( C->y, E->key.y );
00079 return sign;
00080 }
|
|
||||||||||||
|
Definition at line 64 of file gugr_planesweep.cpp.
00065 {
00066 return DetermineOrientation( L->B, L->E, *P );
00067 }
|
|
||||||||||||
|
Definition at line 95 of file gugr_planesweep.cpp. Referenced by gugr::segnode::insert(), gugr::contour_node::Insert(), and gugr::segnode::remove().
00096 {
00097 if( p1 < p2 ) return -1;
00098 else if( p1 == p2 ) return 0;
00099 return 1;
00100 }
|
|
||||||||||||
|
Definition at line 81 of file gugr_planesweep.cpp.
00082 {
00083 int sign = DetermineOrientation( L->B, L->E, S->B );
00084 if( sign == 0 ) sign = DetermineOrientation( L->B, L->E, S->E );
00085 return sign;
00086 }
|
|
||||||||||||||||
|
Definition at line 46 of file gugr_regularize.cpp.
00047 {
00048 const graph_vertex& v1 = *((graph_vertex *)p1);
00049 const graph_vertex& v2 = *((graph_vertex *)p2);
00050 int sign;
00051
00052 sign = compare( v1.v.v().y, v2.v.v().y );
00053 if( !sign ) sign = -compare( v1.v.v().x, v2.v.v().x );
00054
00055 return(sign);
00056 }
|
|
||||||||||||||||||||||||||||||||
|
Definition at line 545 of file gugr_basics.cpp.
00549 {
00550 const Interval& iAx = A.x.get_bounds();
00551 const Interval& iAy = A.y.get_bounds();
00552 const Interval& iBx = B.x.get_bounds();
00553 const Interval& iBy = B.y.get_bounds();
00554 const Interval& iCx = C.x.get_bounds();
00555 const Interval& iCy = C.y.get_bounds();
00556 const Interval& iDx = D.x.get_bounds();
00557 const Interval& iDy = D.y.get_bounds();
00558 Interval iABx,iABy, iACx,iACy, iADx,iADy;
00559 Interval iABcAC,iABdAC;
00560 Interval iABcAD,iABdAD;
00561 bool flag1 = false, flag2 = false;
00562 int sideC,sideD,sign;
00563 const rational& rAx = A.x;
00564 const rational& rAy = A.y;
00565 const rational& rBx = B.x;
00566 const rational& rBy = B.y;
00567 const rational& rCx = C.x;
00568 const rational& rCy = C.y;
00569 const rational& rDx = D.x;
00570 const rational& rDy = D.y;
00571 rational rABx,rABy, rACx,rACy, rADx,rADy;
00572 rational rABcAC, rABdAC;
00573 rational rABcAD, rABdAD;
00574 Interval iLambda;
00575 rational rLambda;
00576
00577 *match = 0;
00578 *code_c = 0;
00579 *code_d = 0;
00580
00581 iABx = iBx - iAx;
00582 iABy = iBy - iAy;
00583 iACx = iCx - iAx;
00584 iACy = iCy - iAy;
00585
00586 iABcAC = iABx*iACy - iABy*iACx;
00587
00588 if( iABcAC.m_low > 0.0 ) sideC = +1;
00589 else if( iABcAC.m_high < 0.0 ) sideC = -1;
00590 else
00591 {
00592 flag1 = true;
00593 rABx = rBx - rAx;
00594 rABy = rBy - rAy;
00595 rACx = rCx - rAx;
00596 rACy = rCy - rAy;
00597
00598 rABcAC = rABx*rACy - rABy*rACx;
00599 sideC = rABcAC.test();
00600 }
00601
00602 *code_c = sideC + 2;
00603
00604 if( sideC == 0 ) /* sideC == 0 => check orientation with dot product */
00605 {
00606 iABdAC = iABx*iACx + iABy*iACy;
00607 if( iABdAC.m_low > 0.0 ) /* 0=angle(AB,AC) < angle(AB,AD) */
00608 { *match = 1; return(-1); }
00609 else if( iABdAC.m_high >= 0.0 )
00610 {
00611 rABdAC = rABx*rACx + rABy*rACy;
00612 if( rABdAC.test() > 0.0 ) /* 0=angle(AB,AC) < angle(AB,AD) */
00613 { *match = 1; return(-1); }
00614 }
00615 /* now angle(AB,AC) == 180 if sideC == 0 */
00616 }
00617
00618 iADx = iDx - iAx;
00619 iADy = iDy - iAy;
00620
00621 iABcAD = iABx*iADy - iABy*iADx;
00622
00623 if( iABcAD.m_low > 0.0 ) sideD = +1;
00624 else if( iABcAD.m_high < 0.0 ) sideD = -1;
00625 else
00626 {
00627 flag2 = true;
00628 rADx = rDx - rAx;
00629 rADy = rDy - rAy;
00630 if( !flag1 )
00631 {
00632 rABx = rBx - rAx;
00633 rABy = rBy - rAy;
00634 }
00635 rABcAD = rABx*rADy - rABy*rADx;
00636 sideD = rABcAD.test();
00637 }
00638
00639 *code_d = sideD + 2;
00640
00641 if( sideD == 0 ) /* sideD == 0 => check orientation with dot product */
00642 {
00643 if( sideC == 0 ) { *match = 2; return(+1); }
00644
00645 iABdAD = iABx*iADx + iABy*iADy;
00646 if( iABdAD.m_low > 0.0 ) /* 0=angle(AB,AD) < angle(AB,AC) */
00647 { *match = 2; return(+1); }
00648 else if( iABdAD.m_high >= 0.0 ) /* exact calculation if necessary */
00649 {
00650 rABdAD = rABx*rADx + rABy*rADy;
00651 if( rABdAD.test() > 0.0 ) /* 0=angle(AB,AD) < angle(AB,AC) */
00652 { *match = 2; return(+1); }
00653 }
00654 /* now angle(AB,AD) == 180 if sideD == 0 */
00655
00656 if( sideC > 0 ) return(-1);
00657 return(+1);
00658 }
00659
00660 if( sideC == 0 )
00661 {
00662 if( sideD > 0 ) return(+1);
00663 return(-1);
00664 }
00665
00666 if( sideC > sideD ) return(-1);
00667 else if( sideC < sideD ) return(+1);
00668
00669 /* intersect Line(C,AB) and Line(A,AD) */
00670
00671 iLambda = (iADx*iACy - iACx*iADy)/(iABx*iADy - iABy*iADx);
00672 if( iLambda.m_low > 0.0 )
00673 {
00674 if( sideC > 0 ) return(+1); /* angle(AB,AC) > angle(AB,AD) */
00675 return(-1);
00676 }
00677 if( iLambda.m_high < 0.0 )
00678 {
00679 if( sideC > 0 ) return(-1); /* angle(AB,AC) < angle(AB,AD) */
00680 return(+1);
00681 }
00682
00683 if( !flag1 )
00684 {
00685 rACx = rCx - rAx;
00686 rACy = rCy - rAy;
00687 }
00688 if( !flag2 )
00689 {
00690 if( !flag1 )
00691 {
00692 rABx = rBx - rAx;
00693 rABy = rBy - rAy;
00694 }
00695 rADx = rDx - rAx;
00696 rADy = rDy - rAy;
00697 }
00698
00699 rLambda = (rADx*rACy - rACx*rADy)/(rABx*rADy - rABy*rADx);
00700 sign = rLambda.test();
00701
00702 if( sign > 0 )
00703 {
00704 if( sideC > 0 ) return(+1); /* angle(AB,AC) > angle(AB,AD) */
00705 return(-1);
00706 }
00707 if( sideC > 0 ) return(-1); /* angle(AB,AC) < angle(AB,AD) */
00708 return(+1);
00709 }
|
|
||||||||||||
|
Definition at line 179 of file gugr_regularize.cpp.
00180 {
00181 int sign;
00182
00183 if( A == B ) return(0);
00184
00185 if( IS_INF(*A) )
00186 return( INF_SIGN(*A) );
00187 if( IS_INF(*B) )
00188 return( -INF_SIGN(*B) );
00189
00190 if( A->v[0] != B->v[0] ) {
00191 sign = DetermineOrientation( B->v[0]->v.v(), B->v[1]->v.v(),
00192 A->v[0]->v.v() );
00193 } else {
00194 sign = DetermineOrientation( B->v[0]->v.v(), B->v[1]->v.v(),
00195 A->v[1]->v.v() );
00196 }
00197 return(-sign);
00198 }
|
|
||||||||||||
|
Definition at line 199 of file gugr_regularize.cpp.
00200 {
00201 int sign;
00202
00203 if( A == B ) return(0);
00204
00205 if( IS_INF(*A) )
00206 return( INF_SIGN(*A) );
00207 if( IS_INF(*B) )
00208 return( -INF_SIGN(*B) );
00209
00210 if( A->v[1] != B->v[1] ) {
00211 sign = DetermineOrientation( B->v[0]->v.v(), B->v[1]->v.v(),
00212 A->v[1]->v.v() );
00213 } else {
00214 sign = DetermineOrientation( B->v[0]->v.v(), B->v[1]->v.v(),
00215 A->v[0]->v.v() );
00216 }
00217 return(-sign);
00218 }
|
|
||||||||||||
|
Definition at line 838 of file gugr_basics.cpp.
00839 {
00840 graph_edge *left, *right, **E;
00841 graph_vertex *v0 = e->v[0], *v1 = e->v[1];
00842 int ileft, iright, codel, coder, nE;
00843
00844 E = (graph_edge **)alloca( sizeof(graph_edge *) * maxE );
00845 if( E == NULL ) throw AllocError();
00846
00847 nE = IncidentEdges( v0, E );
00848 if( nE > 0 )
00849 {
00850 EdgeInsertPosition( v0->v, v1->v, nE, E, &ileft, &iright,
00851 &codel, &coder );
00852 left = E[ileft]; right = E[iright];
00853
00854 if( left->v[0] == v0 )
00855 left->e[0] = e;
00856 else
00857 left->e[1] = e;
00858
00859 e->e[0] = right;
00860 }
00861 else
00862 {
00863 v0->e = e;
00864 e->e[0] = e;
00865 }
00866
00867 nE = IncidentEdges( v1, E );
00868 if( nE > 0 )
00869 {
00870 EdgeInsertPosition( v1->v, v0->v, nE, E, &ileft, &iright,
00871 &coder, &codel );
00872 left = E[ileft]; right = E[iright];
00873
00874 if( left->v[0] == v1 )
00875 left->e[0] = e;
00876 else
00877 left->e[1] = e;
00878
00879 e->e[1] = right;
00880 }
00881 else
00882 {
00883 v1->e = e;
00884 e->e[1] = e;
00885 }
00886 }
|
|
||||||||||||||||||||||||
|
Definition at line 178 of file gugr_bool.cpp.
00182 {
00183 graph_edge_list E;
00184 graph_vertex_list V;
00185 List< ListNode<segment> > segs;
00186 contour_node *cn;
00187 graph_edge *e;
00188 int end,side,n,i;
00189 graph_edge **TE;
00190 ListNode<graph_edge *> *en;
00191 contour_node *CA,*CB;
00192 RefMap<void>::Node mn;
00193 Ptr<void *> edges;
00194 int nEdges;
00195 List<ListNode<gul::polyline<point2<rational> > > > testC;
00196
00197 IntersectSegments( insegs, &E, &V, false );
00198
00199 // cout << dump_graph(&V,&E);
00200
00201 FindContours(E,V,far_maxx,far_maxy,segs,contours);
00202
00203 // cout << dump_graph(&V,&E);
00204 // cout << dump_segs(&segs);
00205
00206 E.DeleteElems();
00207 V.DeleteElems();
00208
00209 // travert the help lines and build the containment tree
00210
00211 IntersectSegments( segs, &E, &V, false );
00212
00213 // cout << dump_graph(&V,&E);
00214
00215 TE = (graph_edge **)alloca(sizeof(graph_edge *)*E.nElems);
00216 edges.reserve_pool(E.nElems);
00217
00218 for( cn = contours.First(); cn != 0; cn = cn->next ) // travert contours
00219 {
00220 CA = &universe; // current open contour above (or right) of help line
00221 CB = &universe; // current open contour below (or left) of help line
00222
00223 if( !cn->hseg ) continue;
00224
00225 // dump_segment(cn->hseg,cout);
00226
00227 en = cn->hseg->e.First();
00228 if( en )
00229 {
00230 e = en->el;
00231
00232 if( e->l.IsHorizontal() || (e->l.dx().test() < 0) )
00233 end = 1;
00234 else
00235 end = 0;
00236 side = !end;
00237 }
00238
00239 while( en )
00240 {
00241 en = en->next;
00242 if( !en ) break; // the last edge is a special case
00243
00244 n = EdgeCycle( e, e->v[end], TE );
00245
00246 for( i = 1; TE[i] != en->el; i++ ) // edges above help line (or left of
00247 { // vertical help line)
00248 CT_DoAboveEdge( TE[i], e->v[end], &CA, &CB );
00249 }
00250
00251 for( i = n-1; TE[i] != en->el; i-- ) // edges below help line (or right of
00252 { // vertical help line)
00253 CT_DoBelowEdge( TE[i], e->v[end], &CA, &CB );
00254 }
00255
00256 e = en->el; // next edge
00257 }
00258 // last edge, its endpoint lies on the segment of the contour which
00259 // shall be classified. it is sufficient to do the classification
00260 // with one of the edges of these segment
00261
00262 nEdges = cn->seg->e.nElems;
00263 for( en = cn->seg->e.First(), i=0; en != 0; en = en->next, i++ )
00264 edges[i] = en->el;
00265 heapsort( nEdges, edges );
00266
00267 n = EdgeCycle( e, e->v[end], TE );
00268
00269 for( i = 1; ; i++ ) // edges above help line until edge on segment reached
00270 {
00271 CT_DoAboveEdge( TE[i], e->v[end], &CA, &CB );
00272
00273 if( BinarySearch( (void *)TE[i], nEdges, edges ) >= 0 )
00274 break;
00275 }
00276
00277 for( i = n-1; ; i-- ) // edges below help line until edge on segment reached
00278 {
00279 CT_DoBelowEdge( TE[i], e->v[end], &CA, &CB );
00280
00281 if( BinarySearch( (void *)TE[i], nEdges, edges ) >= 0 )
00282 break;
00283 }
00284 }
00285
00286 // cleanup
00287 ISDeleteOwnerMaps(E);
00288
00289 /*
00290 int j;
00291 cn = contours.First();
00292 j = 0;
00293 while( cn )
00294 {
00295 j++;
00296 cout << "CONTOUR #" << j << " (" << (void *)cn << ")\n";
00297 cout << dump_vector<void*>(cn->nOwners, cn->owners);
00298 for( i = 0; i < cn->nVerts; i++ )
00299 cout << "(" << cn->verts[i].v() << "), ";
00300 cout << "\n";
00301 cn = cn->next;
00302 }
00303 */
00304
00305 // cout << "containment tree\n";
00306 // universe.dump(0);
00307 }
|
|
||||||||||||||||||||||||
|
|
|
||||||||||||||||||||||||
|
|
|
||||||||||||||||||||||||||||
|
Definition at line 659 of file gugr_bool.cpp.
00665 {
00666 ListNode<gul::polyline<point2<rational> > > *c;
00667 ListNode<gul::polyline<point2<T> > > *fc;
00668 Interval ix,iy;
00669 T x,y;
00670 int i;
00671
00672 c = inA.First();
00673 while( c )
00674 {
00675 fc = new ListNode<gul::polyline<point2<T> > >;
00676 fc->el.P.reserve_pool(c->el.n);
00677 fc->el.n = c->el.n;
00678 outA.Append(fc);
00679
00680 for( i = 0; i < c->el.n; i++ )
00681 {
00682 ix = c->el.P[i].x.get_bounds();
00683 iy = c->el.P[i].y.get_bounds();
00684 x = (T)((ix.m_low+ix.m_high)/2.0);
00685 y = (T)((iy.m_low+iy.m_high)/2.0);
00686 x = gugr::cnv2coord(x)*scale + minx;
00687 y = gugr::cnv2coord(y)*scale + miny;
00688 fc->el.P[i].x = x;
00689 fc->el.P[i].y = y;
00690 }
00691 c = c->next;
00692 }
00693 }
|
|
||||||||||||||||||||||||||||||||||||||||
|
|
|
||||||||||||||||||||||||||||||||||||||||
|
|
|
||||||||||||||||||||||||||||||||||||||||||||
|
Definition at line 568 of file gugr_bool.cpp.
00578 {
00579 T minx,maxx,miny,maxy;
00580 T dx,dy,scale,scalei;
00581 ListNode< gugr::polyline > *pn;
00582 ListNode< gul::polyline<point2<T> > > *c;
00583 unsigned long *cbuf =
00584 (unsigned long *)alloca(gul::rtr<T>::mantissa_length());
00585
00586 c = A.First();
00587 CalcBoundingBoxE( c->el.n, c->el.P, minx, maxx, miny, maxy );
00588 c = c->next;
00589 while( c )
00590 {
00591 UpdateBoundingBoxE( c->el.n, c->el.P, minx, maxx, miny, maxy );
00592 c = c->next;
00593 }
00594 c = B.First();
00595 while( c )
00596 {
00597 UpdateBoundingBoxE( c->el.n, c->el.P, minx, maxx, miny, maxy );
00598 c = c->next;
00599 }
00600
00601 dx = maxx - minx;
00602 dy = maxy - miny;
00603 scale = dx > dy ? dx : dy;
00604 minx -= scale;
00605 miny -= scale;
00606 scalei = (T)1/scale;
00607
00608 c = A.First();
00609 while( c )
00610 {
00611 pn = new ListNode<gugr::polyline>();
00612 PA.Append( pn );
00613 pn->el.init( c->el.n, c->el.P, minx, miny, scalei );
00614 c = c->next;
00615 }
00616 c = B.First();
00617 while( c )
00618 {
00619 pn = new ListNode<gugr::polyline>();
00620 PB.Append( pn );
00621 pn->el.init( c->el.n, c->el.P, minx, miny, scalei );
00622 c = c->next;
00623 }
00624
00625 *ret_minx = minx;
00626 *ret_miny = miny;
00627 *ret_scale = scale;
00628 *ret_far_y = *ret_far_x = rational(coord2int((T)2,cbuf),cbuf) +
00629 rational(ULong(0x100000));
00630 }
|
|
||||||||||||
|
Definition at line 67 of file gugr_basics.h.
00068 {
00069 unsigned long i;
00070
00071 // gul::Assert<InternalError>( ndebug | (1.0f <= f && f <= 2.0f) );
00072 if( f < 1.0f ) f = 1.0f;
00073 else if( f > 2.0f ) f = 2.0f;
00074 i = (unsigned long)(f * gul::rtr<float>::epsilon_inv());
00075 i -= (unsigned long)gul::rtr<float>::epsilon_inv();
00076 if( !i ) return 0;
00077 buf[0] = i;
00078 return 1;
00079 }
|
|
||||||||||||
|
Definition at line 44 of file gugr_basics.h. Referenced by gugr::polyline::init().
00045 {
00046 gul::uint64 i;
00047 unsigned long hi,lo;
00048
00049 // gul::Assert<gul::InternalError>( ndebug | (1.0 <= f && f <= 2.0) );
00050 if( f < 1.0 ) f = 1.0;
00051 else if( f > 2.0 ) f = 2.0;
00052 i = (gul::uint64)(f*gul::rtr<double>::epsilon_inv());
00053 i -= (gul::uint64)gul::rtr<double>::epsilon_inv();
00054 hi = (unsigned long)((i >> 32) & LL(0xffffffff));
00055 lo = (unsigned long)(i & LL(0xffffffff));
00056 if( !hi )
00057 {
00058 if( !lo ) return 0;
00059 buf[0] = lo;
00060 return 1;
00061 }
00062 buf[0] = lo;
00063 buf[1] = hi;
00064 return 2;
00065 }
|
|
||||||||||||||||||||
|
Definition at line 46 of file gugr_bool.cpp.
00051 {
00052 RefMap<void> *Mout,*Min,*M;
00053 RefMap<void>::Node mn;
00054 contour_node *CA,*CB,*C,*Cout,*Cin;
00055
00056 CA = *pCA;
00057 CB = *pCB;
00058
00059 if( e->v[0] == v )
00060 {
00061 Mout = (RefMap<void> *)e->f[1].p;
00062 Min = (RefMap<void> *)e->f[0].p;
00063 }
00064 else
00065 {
00066 Mout = (RefMap<void> *)e->f[0].p;
00067 Min = (RefMap<void> *)e->f[1].p;
00068 }
00069
00070 Cout = Cin = 0;
00071
00072 M = Mout;
00073 mn = M->First();
00074 while( !mn.IsEmpty() ) // because of the first planesweep edge/side
00075 { // pairs can have only one owner contour
00076 if( mn.key() ) { Cout = (contour_node *)mn.key(); break; }
00077 mn = M->Successor( mn );
00078 }
00079
00080 M = Min;
00081 mn = M->First();
00082 while( !mn.IsEmpty() )
00083 {
00084 if( mn.key() ) { Cin = (contour_node *)mn.key(); break; }
00085 mn = M->Successor( mn );
00086 }
00087
00088 C = Cout;
00089 if( !C ) return; // ignore help lines of other contours
00090
00091 if( C != CA )
00092 {
00093 CA->Insert( C );
00094 CA = C;
00095 }
00096 else
00097 CA = CA->parent;
00098
00099 C = Cin;
00100 if( C != CA )
00101 {
00102 CA->Insert( C );
00103 CA = C;
00104 }
00105 else
00106 CA = CA->parent;
00107
00108 *pCA = CA;
00109 *pCB = CB;
00110 }
|
|
||||||||||||||||||||
|
Definition at line 112 of file gugr_bool.cpp.
00117 {
00118 RefMap<void> *Mout,*Min,*M;
00119 RefMap<void>::Node mn;
00120 contour_node *CA,*CB,*C,*Cout,*Cin;
00121
00122 CA = *pCA;
00123 CB = *pCB;
00124
00125 if( e->v[0] == v )
00126 {
00127 Mout = (RefMap<void> *)e->f[0].p;
00128 Min = (RefMap<void> *)e->f[1].p;
00129 }
00130 else
00131 {
00132 Mout = (RefMap<void> *)e->f[1].p;
00133 Min = (RefMap<void> *)e->f[0].p;
00134 }
00135
00136 Cout = Cin = 0;
00137
00138 M = Mout;
00139 mn = M->First();
00140 while( !mn.IsEmpty() ) // because of the first planesweep edge/side
00141 { // pairs can have only one owner contour
00142 if( mn.key() ) { Cout = (contour_node *)mn.key(); break; }
00143 mn = M->Successor( mn );
00144 }
00145
00146 M = Min;
00147 mn = M->First();
00148 while( !mn.IsEmpty() )
00149 {
00150 if( mn.key() ) { Cin = (contour_node *)mn.key(); break; }
00151 mn = M->Successor( mn );
00152 }
00153
00154 C = Cout;
00155 if( !C ) return; // ignore help lines of other contours
00156
00157 if( C != CB )
00158 {
00159 CB->Insert( C );
00160 CB = C;
00161 }
00162 else
00163 CB = CB->parent;
00164
00165 C = Cin;
00166 if( C != CB )
00167 {
00168 CB->Insert( C );
00169 CB = C;
00170 }
00171 else
00172 CB = CB->parent;
00173
00174 *pCA = CA;
00175 *pCB = CB;
00176 }
|
|
||||||||||||||||
|
Definition at line 476 of file gugr_basics.cpp.
00478 {
00479 const Interval& ix1 = A.x.get_bounds();
00480 const Interval& iy1 = A.y.get_bounds();
00481 const Interval& ix2 = B.x.get_bounds();
00482 const Interval& iy2 = B.y.get_bounds();
00483 const Interval& ix = C.x.get_bounds();
00484 const Interval& iy = C.y.get_bounds();
00485 Interval i;
00486
00487 i = (ix2-ix1)*(iy-iy1) - (ix-ix1)*(iy2-iy1);
00488 if( i.m_low > 0.0 ) return(+1);
00489 else if( i.m_high < 0.0 ) return(-1);
00490
00491 const rational& x1 = A.x;
00492 const rational& y1 = A.y;
00493 const rational& x2 = B.x;
00494 const rational& y2 = B.y;
00495 const rational& x = C.x;
00496 const rational& y = C.y;
00497 rational det;
00498
00499 det = (x2-x1)*(y-y1) - (x-x1)*(y2-y1);
00500 return( det.test() );
00501 }
|
|
||||||||||||||||
|
Definition at line 503 of file gugr_basics.cpp.
00505 {
00506 const Interval& ix1 = A.x.get_bounds();
00507 const Interval& iy1 = A.y.get_bounds();
00508 const Interval& ix1x2 = AB.x.get_bounds();
00509 const Interval& iy1y2 = AB.y.get_bounds();
00510 const Interval& ix = C.x.get_bounds();
00511 const Interval& iy = C.y.get_bounds();
00512 Interval i;
00513
00514 i = ix1x2*(iy-iy1) - (ix-ix1)*iy1y2;
00515 if( i.m_low > 0.0 ) return(+1);
00516 else if( i.m_high < 0.0 ) return(-1);
00517
00518 const rational& x1 = A.x;
00519 const rational& y1 = A.y;
00520 const rational& x1x2 = AB.x;
00521 const rational& y1y2 = AB.y;
00522 const rational& x = C.x;
00523 const rational& y = C.y;
00524 rational det;
00525
00526 det = x1x2*(y-y1) - (x-x1)*y1y2;
00527 return( det.test() );
00528 }
|
|
||||||||||||||||||||
|
Definition at line 125 of file gugr_bool.h.
00129 {
00130 T minx,miny,scale;
00131 rational far_x,far_y;
00132 gul::List<gul::ListNode<gugr::polyline> > PA,PB;
00133 gul::List<gul::ListNode<gul::polyline<gul::point2<rational> > > > PC;
00134
00135 ConvertToRationalPolys(fPA,fPB,&minx,&miny,&scale,&far_x,&far_y,PA,PB);
00136 // DumpPS<T>::set_transformation(minx,miny,scale,scale);
00137 DoDifference(PA,PB,far_x,far_y,PC);
00138 ConvertToFloatPoly(PC,minx,miny,scale,fPC);
00139 }
|
|
||||||||||||||||||||||||
|
Definition at line 413 of file gugr_bool.cpp.
00415 {
00416 ListNode<gul::polyline<point2<rational> > > *pln;
00417 gul::ptr_int_union UA,UB;
00418 gul::RefMap<void>::Node cn;
00419 bool store;
00420
00421 UA.set_i(InA);
00422 UB.set_i(OutB);
00423 store = false;
00424
00425 if( oset == InA )
00426 {
00427 if( C->hasOwner(UA.p) )
00428 oset ^= InA;
00429
00430 if( C->hasOwner(UB.p) )
00431 oset ^= OutB;
00432
00433 if( oset != InA )
00434 store = true;
00435 }
00436 else
00437 {
00438 if( C->hasOwner(UA.p) )
00439 oset ^= InA;
00440
00441 if( C->hasOwner(UB.p) )
00442 oset ^= OutB;
00443
00444 if( oset == InA )
00445 store = true;
00446 }
00447
00448 if( store )
00449 {
00450 pln = new ListNode<gul::polyline<point2<rational> > >();
00451 C->get_polyline_joined( pln->el );
00452 pl.Append(pln);
00453 }
00454
00455 // travert children
00456 cn = C->childs.First();
00457 while( !cn.IsEmpty() )
00458 {
00459 DifferenceSubTree( (contour_node *)cn.key(), oset, InA, OutB, pl );
00460 cn = C->childs.Successor( cn );
00461 }
00462 }
|
|
||||||||||||
|
Definition at line 892 of file gugr_basics.cpp.
00893 {
00894 graph_edge *left, *right, **E;
00895 graph_vertex *v;
00896 int n,isolated;
00897
00898 E = (graph_edge **)alloca( sizeof(graph_edge *) * maxE );
00899 if( E == NULL ) throw AllocError();
00900
00901 isolated = 0;
00902 v = e->v[0];
00903
00904 n = EdgeCycle( e, v, E );
00905 if( n > 1 )
00906 {
00907 right = E[1];
00908 left = E[n-1];
00909
00910 if( left->v[0] == v )
00911 left->e[0] = right;
00912 else
00913 left->e[1] = right;
00914
00915 if( v->e == e ) v->e = left;
00916 }
00917 else
00918 isolated |= 1;
00919
00920 v = e->v[1];
00921
00922 n = EdgeCycle( e, v, E );
00923 if( n > 1 )
00924 {
00925 right = E[1];
00926 left = E[n-1];
00927
00928 if( left->v[0] == v )
00929 left->e[0] = right;
00930 else
00931 left->e[1] = right;
00932
00933 if( v->e == e ) v->e = left;
00934 }
00935 else
00936 isolated |= 2;
00937
00938 return isolated;
00939 }
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
|
Definition at line 477 of file gugr_split.cpp.
00483 {
00484 graph_edge **E;
00485 cut_record *rec;
00486 int nE,L1,L2,R1,R2,match1,match2,cL1,cR1,cL2,cR2;
00487 vertex farleft,farright;
00488 graph_edge *ah,*el,*bl,*bh,*er,*al, *e, *eu, *ew;
00489 graph_vertex *v, *lva, *lvb, *vu, *vl, *delv;
00490 int fa,fb,nfa,nfb;
00491 line hori;
00492
00493 farleft = vertex( point2<rational>(far_left,Sa->val) );
00494 farright = vertex( point2<rational>(far_right,Sa->val) );
00495 hori = line( farleft.v(), rational(ULong(1)), rational() );
00496
00497 E = (graph_edge **)alloca( sizeof(graph_edge *)*maxE );
00498 if( E == NULL ) throw AllocError();
00499
00500 rec = Sa->R.head;
00501 fa=fb=nfa=nfb=0;
00502 /* new vertex for strip above cutting line*/
00503 v = new graph_vertex( point2<rational>(minx,Sa->val), NULL );
00504 Sa->V.Append(v);
00505 lva = *minSaV = v;
00506 /* new vertex for strip below cutting line */
00507 v = new graph_vertex(lva->v, NULL);
00508 Sb->V.Append(v);
00509 lvb = *minSbV = v;
00510
00511 delv = 0;
00512 while( rec != NULL )
00513 {
00514 if( rec->v != NULL ) /* vertex on cutting line */
00515 {
00516 nE = IncidentEdges( rec->v, E );
00517
00518 match1 = EdgeInsertPosition( rec->v->v, farleft, nE, E,
00519 &L1, &R1, &cL1, &cR1 );
00520 cL1 = 2-(cL1-2); cR1 = 2-(cR1-2);
00521
00522 if( cL1 == 1 ) /* special case: E[L1] below cutting line */
00523 {
00524 bh= E[L1];
00525 er = al = ah = NULL;
00526
00527 if( cR1 == 2 )
00528 {
00529 el = E[R1];
00530 bl = E[R1]->e[0];
00531 }
00532 else
00533 {
00534 el = NULL;
00535 bl = E[R1];
00536 }
00537 }
00538 else if( cL1 == 2 ) /* special case: E[L1] on cutting line */
00539 {
00540 er = E[L1];
00541 al = ah = NULL;
00542
00543 if( cR1 == 2 )
00544 {
00545 el = E[R1];
00546 if( el->e[0] == er )
00547 bl = NULL;
00548 else
00549 bl = el->e[0];
00550 }
00551 else
00552 {
00553 bl = E[R1];
00554 el = NULL;
00555 }
00556 bh = bl;
00557 if( bh != NULL )
00558 while( bh->e[1] != er ) bh = bh->e[1];
00559 }
00560 else /* E[L1] above cutting line */
00561 {
00562 ah = E[L1];
00563
00564 if( cR1 == 3 ) /* E[R1] above cutting line */
00565 {
00566 el = bl = bh = er = NULL;
00567 al = E[R1];
00568 }
00569 else if( (cR1 == 2) && (!match1) ) /* E[R1] on cutting line */
00570 { /* but different orientation */
00571 el = bl = bh = NULL;
00572 er = E[R1];
00573 al = E[R1]->e[1]; /* using edge orientatation and
00574 that cutting line is horizontal ! */
00575 }
00576 else
00577 {
00578 match2 = EdgeInsertPosition( rec->v->v, farright, nE, E,
00579 &L2, &R2, &cL2, &cR2 );
00580 if( match1 ) /* E[R1] on cutting line, same orientation */
00581 {
00582 el = E[R1];
00583 if( cL2 == 1 )
00584 {
00585 bl = E[R1]->e[0];
00586 bh = E[L2];
00587 }
00588 else
00589 bl = bh = NULL;
00590 }
00591 else
00592 {
00593 el = NULL;
00594 bl = E[R1];
00595 bh = E[L2];
00596 }
00597
00598 if( cR2 == 2 ) /* R2 on cutting line */
00599 {
00600 er = E[R2];
00601 al = E[R2]->e[1];
00602 }
00603 else
00604 {
00605 er = NULL;
00606 al = E[R2];
00607 }
00608 }
00609 }
00610
00611 if( el != NULL )
00612 {
00613 fb = el->f[0].i;
00614 fa = el->f[1].i;
00615 }
00616
00617 if( al != NULL )
00618 {
00619 /* create new vertex: */
00620 v = new graph_vertex( ah->v[0]->v, ah );
00621 Sa->V.Append(v);
00622
00623 ah->e[0] = al; /* connect upper edges to new vertex */
00624 e = al;
00625 do
00626 {
00627 e->v[0] = v;
00628 e = e->e[0];
00629 }
00630 while( e != al );
00631
00632 if( el == NULL )
00633 fa = ah->f[0].i;
00634 /* create new edge */
00635 e = new graph_edge();
00636 Sa->E.Append(e);
00637
00638 e->l = hori;
00639
00640 e->f[0].set_i(fb);
00641 e->f[1].set_i(fa);
00642
00643 e->e[0] = al;
00644 ah->e[0] = e;
00645
00646 if( lva->e != NULL )
00647 {
00648 e->e[1] = lva->e->e[0];
00649 lva->e->e[0] = e;
00650 }
00651 else
00652 {
00653 e->e[1] = e;
00654 lva->e = e;
00655 }
00656 v->e = e;
00657
00658 e->v[0] = v;
00659 e->v[1] = lva;
00660
00661 lva = v;
00662 nfa = nfb = al->f[1].i;
00663 }
00664
00665 if( bl != NULL )
00666 {
00667 /* create new vertex: */
00668 v = new graph_vertex( bl->v[1]->v, bh );
00669 Sb->V.Append(v);
00670
00671 bh->e[1] = bl; /* connect edges below to new vertex */
00672 e = bl;
00673 do
00674 {
00675 Sa->E.Remove(e);
00676 Sb->E.Append(e);
00677 e->v[1] = v;
00678 e = e->e[1];
00679 }
00680 while( e != bl );
00681
00682 if( el == NULL )
00683 fb = bl->f[0].i;
00684 /* create new edge */
00685 e = new graph_edge();
00686 Sb->E.Append(e);
00687
00688 e->l = hori;
00689
00690 e->f[0].set_i(fb);
00691 e->f[1].set_i(fa);
00692
00693 e->e[0] = bl;
00694 bh->e[1] = e;
00695
00696 if( lvb->e != NULL )
00697 {
00698 e->e[1] = lvb->e->e[1];
00699 lvb->e->e[1] = e;
00700 }
00701 else
00702 {
00703 e->e[1] = e;
00704 lvb->e = e;
00705 }
00706
00707 e->v[0] = v;
00708 e->v[1] = lvb;
00709
00710 lvb = v;
00711 nfa = nfb = bh->f[1].i;
00712 }
00713
00714 if( er != NULL )
00715 {
00716 fa = er->f[1].i;
00717 fb = er->f[0].i;
00718 }
00719 else
00720 {
00721 fa = nfa;
00722 fb = nfb;
00723 }
00724
00725 Sa->V.Remove( rec->v ); /* remove original vertex */
00726 delete delv; /* delayed deletion of vertex from original graph */
00727 delv = rec->v;
00728
00729 if( el != NULL ) { /* remove original horizontal edge */
00730 Sa->E.Remove(el);
00731 delete el;
00732 }
00733 }
00734 else /* cutting line intersects edge */
00735 {
00736 ew = rec->e;
00737 /* new vertex for strip above cutting line */
00738 vu = new graph_vertex( point2<rational>(rec->val,Sa->val), NULL );
00739 Sa->V.Append(vu);
00740 /* new vertex for strip below cutting line */
00741 vl = new graph_vertex( vu->v, NULL );
00742 Sb->V.Append(vl);
00743 /* new edge for upper halve of intersecting edge */
00744 eu = new graph_edge();
00745 Sa->E.Append(eu);
00746
00747 eu->l = ew->l;
00748
00749 eu->f[0] = ew->f[0];
00750 eu->f[1] = ew->f[1];
00751 eu->v[0] = vu;
00752 eu->v[1] = ew->v[1];
00753
00754 eu->e[0] = NULL;
00755 if( ew->e[1] != ew )
00756 {
00757 eu->e[1] = ew->e[1];
00758 nE = EdgeCycle( ew, ew->v[1], E ); e = E[nE-1];
00759 if( e->e[0] == ew ) e->e[0] = eu; else e->e[1] = eu;
00760 }
00761 else eu->e[1] = eu;
00762 ew->v[1]->e = eu;
00763
00764 /* shorten intersecting edge and add it to lower strip */
00765 Sa->E.Remove(ew);
00766 Sb->E.Append(ew);
00767
00768 ew->v[1] = vl;
00769 ew->e[1] = NULL;
00770
00771 vu->e = eu; /* set vertex pointers to an incident edge */
00772 vl->e = ew;
00773 /* create new horizontal edge for upper strip */
00774 e = new graph_edge();
00775 Sa->E.Append(e);
00776
00777 e->l = hori;
00778
00779 e->f[0] = e->f[1] = ew->f[0]; /* same face below and above */
00780
00781 e->e[0] = eu;
00782 eu->e[0] = e;
00783
00784 if( lva->e != NULL )
00785 {
00786 e->e[1] = lva->e->e[0];
00787 lva->e->e[0] = e;
00788 }
00789 else
00790 {
00791 e->e[1] = e;
00792 lva->e = e;
00793 }
00794 vu->e = e;
00795
00796 e->v[0] = vu;
00797 e->v[1] = lva;
00798 /* create new horizontal edge for lower strip */
00799 e = new graph_edge();
00800 Sb->E.Append(e);
00801
00802 e->l = hori;
00803
00804 e->f[0] = e->f[1] = ew->f[0]; /* same face below and above */
00805
00806 e->e[0] = ew;
00807 ew->e[1] = e;
00808
00809 if( lvb->e != NULL )
00810 {
00811 e->e[1] = lvb->e->e[1];
00812 lvb->e->e[1] = e;
00813 }
00814 else
00815 {
00816 e->e[1] = e;
00817 lvb->e = e;
00818 }
00819 vl->e = ew;
00820
00821 e->v[0] = vl;
00822 e->v[1] = lvb;
00823
00824 lva = vu;
00825 lvb = vl;
00826 fa = fb = ew->f[1].i;
00827 }
00828
00829 rec = rec->next;
00830 }
00831 delete delv;
00832 /* new vertex for strip above cutting line */
00833 v = new graph_vertex( point2<rational>(maxx,Sa->val), NULL );
00834 *maxSaV = v;
00835 Sa->V.Append(v);
00836 /* create new horizontal edge for upper strip */
00837 e = new graph_edge();
00838 Sa->E.Append(e);
00839
00840 e->l = hori;
00841
00842 e->f[0].set_i(fb);
00843 e->f[1].set_i(fa);
00844
00845 e->e[0] = e;
00846
00847 if( lva->e != NULL )
00848 {
00849 e->e[1] = lva->e->e[0];
00850 lva->e->e[0] = e;
00851 }
00852 else
00853 {
00854 e->e[1] = e;
00855 lva->e = e;
00856 }
00857 v->e = e;
00858
00859 e->v[0] = v;
00860 e->v[1] = lva;
00861 /* new vertex for strip below cutting line */
00862 v = new graph_vertex( v->v, NULL );
00863 *maxSbV = v;
00864 Sb->V.Append(v);
00865 /* create new horizontal edge for lower strip */
00866 e = new graph_edge();
00867 Sb->E.Append(e);
00868
00869 e->l = hori;
00870
00871 e->f[0].set_i(fb);
00872 e->f[1].set_i(fa);
00873
00874 e->e[0] = e;
00875
00876 if( lvb->e != NULL )
00877 {
00878 e->e[1] = lvb->e->e[1];
00879 lvb->e->e[1] = e;
00880 }
00881 else
00882 {
00883 e->e[1] = e;
00884 lvb->e = e;
00885 }
00886 v->e = e;
00887
00888 e->v[0] = v;
00889 e->v[1] = lvb;
00890 }
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
|
Definition at line 1009 of file gugr_split.cpp.
01015 {
01016 graph_edge **E;
01017 cut_record *rec;
01018 int nE,L1,L2,R1,R2,match1,match2,cL1,cR1,cL2,cR2,iv,sign,ew_ori;
01019 vertex farbottom,fartop;
01020 graph_edge *ah,*el,*bl,*bh,*er,*al, *e, *eu, *ew;
01021 graph_vertex *v, *lva, *lvb, *vu, *vl, *delv;
01022 int fa,fb,nfa,nfb;
01023 line verti;
01024
01025 farbottom = vertex( point2<rational>(Sb->val,far_bottom) );
01026 fartop = vertex( point2<rational>(Sb->val,far_top) );
01027 verti = line( farbottom.v(), rational(), rational(ULong(1)) );
01028
01029 E = (graph_edge **)alloca( sizeof(graph_edge *)*maxE );
01030 if( E == NULL ) throw AllocError();
01031
01032 rec = Sb->R.head;
01033 fa=fb=nfa=nfb=0;
01034 /* new vertex for strip left from cutting line*/
01035 v = *minSaV = new graph_vertex( point2<rational>(Sb->val,miny), NULL );
01036 Sa->V.Append(v);
01037 lva = v;
01038 /* new vertex for strip right from cutting line */
01039 v = *minSbV = new graph_vertex(lva->v, NULL);
01040 Sb->V.Append(v);
01041 lvb = v;
01042
01043 delv = 0;
01044 while( rec != NULL )
01045 {
01046 if( rec->v != NULL ) /* vertex on cutting line */
01047 {
01048 nE = IncidentEdges( rec->v, E );
01049
01050 match1 = EdgeInsertPosition( rec->v->v, farbottom, nE, E,
01051 &L1, &R1, &cL1, &cR1 );
01052 cL1 = 2-(cL1-2); cR1 = 2-(cR1-2);
01053
01054 if( cL1 == 1 ) /* special case: E[L1] left from cutting line */
01055 {
01056 bh = E[L1];
01057 er = al = ah = NULL;
01058
01059 if( cR1 == 2 )
01060 {
01061 el = E[R1];
01062 bl = E[R1]->e[1];
01063 }
01064 else
01065 {
01066 el = NULL;
01067 bl = E[R1];
01068 }
01069 }
01070 else if( cL1 == 2 ) /* special case: E[L1] on cutting line */
01071 {
01072 er = E[L1];
01073 al = ah = NULL;
01074
01075 if( cR1 == 2 )
01076 {
01077 el = E[R1];
01078 if( el->e[1] == er )
01079 bl = NULL;
01080 else
01081 bl = el->e[1];
01082 }
01083 else
01084 {
01085 bl = E[R1];
01086 el = NULL;
01087 }
01088 bh = bl;
01089 if( bh != NULL )
01090 {
01091 e = (bh->v[0] == rec->v ? bh->e[0] : bh->e[1]);
01092 while( e != er )
01093 {
01094 bh = e;
01095 e = (bh->v[0] == rec->v ? bh->e[0] : bh->e[1]);
01096 }
01097 }
01098 }
01099 else /* E[L1] right from cutting line */
01100 {
01101 ah = E[L1];
01102
01103 if( cR1 == 3 ) /* E[R1] right from cutting line */
01104 {
01105 el = bl = bh = er = NULL;
01106 al = E[R1];
01107 }
01108 else if( (cR1 == 2) && (!match1) ) /* E[R1] on cutting line */
01109 { /* but different orientation */
01110 el = bl = bh = NULL;
01111 er = E[R1];
01112 al = E[R1]->e[0]; /* using edge orientatation and
01113 that cutting line is vertical ! */
01114 }
01115 else
01116 {
01117 match2 = EdgeInsertPosition( rec->v->v, fartop, nE, E,
01118 &L2, &R2, &cL2, &cR2 );
01119 if( match1 ) /* E[R1] on cutting line, same orientation */
01120 {
01121 el = E[R1];
01122 if( cL2 == 1 )
01123 {
01124 bl = E[R1]->e[1];
01125 bh = E[L2];
01126 }
01127 else
01128 bl = bh = NULL;
01129 }
01130 else
01131 {
01132 el = NULL;
01133 bl = E[R1];
01134 bh = E[L2];
01135 }
01136
01137 if( cR2 == 2 ) /* R2 on cutting line */
01138 {
01139 er = E[R2];
01140 al = E[R2]->e[0];
01141 }
01142 else
01143 {
01144 er = NULL;
01145 al = E[R2];
01146 }
01147 }
01148 }
01149
01150 if( el != NULL )
01151 {
01152 fb = el->f[1].i;
01153 fa = el->f[0].i;
01154 }
01155
01156 if( al != NULL )
01157 {
01158 /* create new vertex: */
01159 iv = (ah->v[0] == rec->v ? 0 : 1);
01160 v = new graph_vertex( rec->v->v, ah );
01161 Sa->V.Append(v);
01162
01163 ah->e[iv] = al; /* connect edges to the left to new vertex */
01164 e = al;
01165 do
01166 {
01167 Sb->E.Remove(e);
01168 Sa->E.Append(e);
01169 if( e->v[0] == rec->v )
01170 { e->v[0] = v;
01171 e = e->e[0];
01172 } else
01173 { e->v[1] = v;
01174 e = e->e[1];
01175 }
01176 }
01177 while( e != al );
01178
01179 if( el == NULL )
01180 fa = ah->f[iv].i;
01181 /* create new edge */
01182 e = new graph_edge();
01183 Sa->E.Append(e);
01184
01185 e->l = verti;
01186
01187 e->f[0].set_i(fa);
01188 e->f[1].set_i(fb);
01189
01190 e->e[1] = al;
01191 ah->e[iv] = e;
01192
01193 if( lva->e != NULL )
01194 {
01195 if( lva->e->v[0] == lva ) {
01196 e->e[0] = lva->e->e[0];
01197 lva->e->e[0] = e;
01198 } else {
01199 e->e[0] = lva->e->e[1];
01200 lva->e->e[1] = e;
01201 }
01202 }
01203 else
01204 {
01205 e->e[0] = e;
01206 lva->e = e;
01207 }
01208 v->e = e;
01209
01210 e->v[1] = v;
01211 e->v[0] = lva;
01212
01213 lva = v;
01214 nfa = nfb = (al->v[0] == v ? al->f[1].i : al->f[0].i);
01215 }
01216
01217 if( bl != NULL )
01218 {
01219 /* create new vertex: */
01220 v = new graph_vertex( rec->v->v, bh );
01221 Sb->V.Append(v);
01222 /* connect edges on the right to new vertex */
01223 if( bh->v[0] == rec->v )
01224 bh->e[0] = bl;
01225 else
01226 bh->e[1] = bl;
01227 e = bl;
01228 do
01229 {
01230 if( e->v[0] == rec->v )
01231 { e->v[0] = v;
01232 e = e->e[0];
01233 } else {
01234 e->v[1] = v;
01235 e = e->e[1];
01236 }
01237 }
01238 while( e != bl );
01239
01240 if( el == NULL )
01241 if( bl->v[1] == v )
01242 fb = bl->f[0].i;
01243 else
01244 fb = bl->f[1].i;
01245 /* create new edge */
01246 e = new graph_edge();
01247 Sb->E.Append(e);
01248
01249 e->l = verti;
01250
01251 e->f[0].set_i(fa);
01252 e->f[1].set_i(fb);
01253
01254 e->e[1] = bl;
01255 if( bh->v[0] == v ) bh->e[0] = e; else bh->e[1] = e;
01256
01257 if( lvb->e != NULL )
01258 {
01259 if( lvb->e->v[0] == lvb ) {
01260 e->e[0] = lvb->e->e[0];
01261 lvb->e->e[0] = e;
01262 } else {
01263 e->e[0] = lvb->e->e[1];
01264 lvb->e->e[1] = e;
01265 }
01266 }
01267 else
01268 {
01269 e->e[0] = e;
01270 lvb->e = e;
01271 }
01272
01273 e->v[1] = v;
01274 e->v[0] = lvb;
01275
01276 lvb = v;
01277 nfa = nfb = (bh->v[1] == v ? bh->f[1].i : bh->f[0].i);
01278 }
01279
01280 Sb->V.Remove( rec->v ); /* remove original vertex */
01281 delete delv; /* delayed deletion of vertex from original graph */
01282 delv = rec->v;
01283
01284 if( er != NULL )
01285 {
01286 fa = er->f[0].i;
01287 fb = er->f[1].i;
01288 }
01289 else
01290 {
01291 fa = nfa;
01292 fb = nfb;
01293 }
01294
01295 if( el != NULL ) { /* remove original vertical edge */
01296 Sb->E.Remove(el);
01297 delete el;
01298 }
01299 }
01300 else /* cutting line intersects edge */
01301 {
01302 ew = rec->e;
01303 /* new vertex for strip right from cutting line */
01304 vu = new graph_vertex( point2<rational>(Sb->val,rec->val), NULL );
01305 Sb->V.Append(vu);
01306 /* new vertex for strip left from cutting line */
01307 vl = new graph_vertex( vu->v, NULL );
01308 Sa->V.Append(vl);
01309 /* new edge for right halve of intersecting edge */
01310 eu = new graph_edge();
01311 Sb->E.Append(eu);
01312
01313 eu->l = ew->l;
01314
01315 eu->f[0] = ew->f[0];
01316 eu->f[1] = ew->f[1];
01317
01318 sign = compare(ew->v[1]->v.v().x, ew->v[0]->v.v().x);
01319 if( sign > 0 ) ew_ori = 1; else ew_ori = 0;
01320
01321 if( ew_ori ) /*** ew oriented from left to right ***/
01322 {
01323 eu->v[0] = vu;
01324 eu->v[1] = ew->v[1];
01325
01326 eu->e[0] = NULL;
01327 if( ew->e[1] != ew )
01328 {
01329 eu->e[1] = ew->e[1];
01330 nE = EdgeCycle( ew, ew->v[1], E ); e = E[nE-1];
01331 if( e->e[0] == ew ) e->e[0] = eu; else e->e[1] = eu;
01332 }
01333 else eu->e[1] = eu;
01334 ew->v[1]->e = eu;
01335
01336 /* shorten intersecting edge and add it to left strip */
01337 Sb->E.Remove(ew);
01338 Sa->E.Append(ew);
01339
01340 ew->v[1] = vl;
01341 ew->e[1] = NULL;
01342
01343 vu->e = eu; /* set vertex pointers to an incident edge */
01344 vl->e = ew;
01345 /* create new vertical edge for right strip */
01346 e = new graph_edge();
01347 Sb->E.Append(e);
01348
01349 e->l = verti;
01350
01351 e->f[0] = e->f[1] = ew->f[1]; /* same face on left and right side */
01352 /* of edge */
01353 eu->e[0] = e;
01354 }
01355 else /*** ew oriented from right to left ***/
01356 {
01357 eu->v[1] = vu;
01358 eu->v[0] = ew->v[0];
01359
01360 eu->e[1] = NULL;
01361 if( ew->e[0] != ew )
01362 {
01363 eu->e[0] = ew->e[0];
01364 nE = EdgeCycle( ew, ew->v[0], E ); e = E[nE-1];
01365 if( e->e[0] == ew ) e->e[0] = eu; else e->e[1] = eu;
01366 }
01367 else eu->e[0] = eu;
01368 ew->v[0]->e = eu;
01369
01370 /* shorten intersecting edge and add it to lower strip */
01371 Sb->E.Remove(ew);
01372 Sa->E.Append(ew);
01373
01374 ew->v[0] = vl;
01375 ew->e[0] = NULL;
01376
01377 vu->e = eu; /* set vertex pointers to an incident edge */
01378 vl->e = ew;
01379 /* create new vertical edge for right strip */
01380 e = new graph_edge();
01381 Sb->E.Append(e);
01382
01383 e->l = verti;
01384
01385 e->f[0] = e->f[1] = ew->f[0]; /* same face on left and right side */
01386 /* of edge */
01387 eu->e[1] = e;
01388 }
01389
01390 e->e[1] = eu;
01391
01392 if( lvb->e != NULL )
01393 {
01394 if( lvb->e->v[0] == lvb ) {
01395 e->e[0] = lvb->e->e[0];
01396 lvb->e->e[0] = e;
01397 } else {
01398 e->e[0] = lvb->e->e[1];
01399 lvb->e->e[1] = e;
01400 }
01401 }
01402 else
01403 {
01404 e->e[0] = e;
01405 lvb->e = e;
01406 }
01407 vu->e = eu;
01408
01409 e->v[1] = vu;
01410 e->v[0] = lvb;
01411 /* create new vertical edge for left strip */
01412 e = new graph_edge();
01413 Sa->E.Append(e);
01414
01415 e->l = verti;
01416
01417 if( ew_ori ) /*** ew oriented from left to right ***/
01418 {
01419 e->f[0] = e->f[1] = ew->f[1]; /* same face on left and right side */
01420
01421 e->e[1] = ew;
01422 ew->e[1] = e;
01423
01424 fa = fb = ew->f[0].i; /* for next intersection */
01425 }
01426 else /*** ew oriented from left to right ***/
01427 {
01428 e->f[0] = e->f[1] = ew->f[0]; /* same face on left and right side */
01429
01430 e->e[1] = ew;
01431 ew->e[0] = e;
01432
01433 fa = fb = ew->f[1].i; /* for next intersection */
01434 }
01435
01436 if( lva->e != NULL )
01437 {
01438 if( lva->e->v[0] == lva ) {
01439 e->e[0] = lva->e->e[0];
01440 lva->e->e[0] = e;
01441 } else {
01442 e->e[0] = lva->e->e[1];
01443 lva->e->e[1] = e;
01444 }
01445 }
01446 else
01447 {
01448 e->e[0] = e;
01449 lva->e = e;
01450 }
01451 vl->e = e;
01452
01453 e->v[1] = vl;
01454 e->v[0] = lva;
01455
01456 lvb = vu;
01457 lva = vl;
01458 }
01459
01460 rec = rec->next;
01461 }
01462 delete delv;
01463 /* new vertex for strip left from cutting line */
01464 v = new graph_vertex( point2<rational>(Sb->val,maxy), NULL );
01465 *maxSaV = v;
01466 Sa->V.Append(v);
01467 /* create new vertical edge for left strip */
01468 e = new graph_edge();
01469 Sa->E.Append(e);
01470
01471 e->l = verti;
01472
01473 e->f[0].set_i(fa);
01474 e->f[1].set_i(fb);
01475
01476 e->e[1] = e;
01477
01478 if( lva->e != NULL )
01479 {
01480 if( lva->e->v[0] == lva ) {
01481 e->e[0] = lva->e->e[0];
01482 lva->e->e[0] = e;
01483 } else {
01484 e->e[0] = lva->e->e[1];
01485 lva->e->e[1] = e;
01486 }
01487 }
01488 else
01489 {
01490 e->e[0] = e;
01491 lva->e = e;
01492 }
01493 v->e = e;
01494
01495 e->v[1] = v;
01496 e->v[0] = lva;
01497 /* new vertex for strip right from cutting line */
01498 v = new graph_vertex( v->v, NULL );
01499 *maxSbV = v;
01500 Sb->V.Append(v);
01501 /* create new vertical edge for right strip */
01502 e = new graph_edge();
01503 Sb->E.Append(e);
01504
01505 e->l = verti;
01506
01507 e->f[0].set_i(fa);
01508 e->f[1].set_i(fb);
01509
01510 e->e[1] = e;
01511
01512 if( lvb->e != NULL )
01513 {
01514 if( lvb->e->v[0] == lvb ) {
01515 e->e[0] = lvb->e->e[0];
01516 lvb->e->e[0] = e;
01517 } else {
01518 e->e[0] = lvb->e->e[1];
01519 lvb->e->e[1] = e;
01520 }
01521 }
01522 else
01523 {
01524 e->e[0] = e;
01525 lvb->e = e;
01526 }
01527 v->e = e;
01528
01529 e->v[1] = v;
01530 e->v[0] = lvb;
01531 }
|
|
||||||||||||||||||||||||
|
Definition at line 533 of file gugr_bool.cpp.
00539 {
00540 const int OutA = 1;
00541 const int InA = 2;
00542 const int OutB = 4;
00543 const int InB = 8;
00544 graph_edge_list E;
00545 graph_vertex_list V;
00546 segment_list S,Stmp;
00547 List<contour_node> contours;
00548 contour_node universe(0); // pseudo contour which contains everything
00549
00550 // get the segments of both polygons and mark them with
00551 // InA,OutA,InB,OutB
00552 OddEvenRule( PA, far_x, far_y, InA, OutA, E, V, S );
00553 OddEvenRule( PB, far_x, far_y, InB, OutB, E, V, Stmp );
00554 S += Stmp;
00555
00556 // find all contours and build their containment tree
00557 ContainmentTree( S, far_x, far_y, contours, universe );
00558 // universe.dump(0);
00559
00560 DifferenceSubTree( &universe, 0, InA, OutB, C );
00561 }
|
|
||||||||||||||||||||||||
|
|
|
||||||||||||||||||||||||
|
Definition at line 467 of file gugr_bool.cpp.
00473 {
00474 const int OutA = 1;
00475 const int InA = 2;
00476 const int OutB = 4;
00477 const int InB = 8;
00478 graph_edge_list E;
00479 graph_vertex_list V;
00480 segment_list S,Stmp;
00481 List<contour_node> contours;
00482 contour_node universe(0); // pseudo contour which contains everything
00483
00484 // get the segments of both polygons and mark them with
00485 // InA,OutA,InB,OutB
00486 OddEvenRule( PA, far_x, far_y, InA, OutA, E, V, S );
00487 OddEvenRule( PB, far_x, far_y, InB, OutB, E, V, Stmp );
00488 S += Stmp;
00489
00490 // find all contours and build their containment tree
00491 ContainmentTree( S, far_x, far_y, contours, universe );
00492 // universe.dump(0);
00493
00494 IntersectionSubTree( &universe, 0, InA, InB, C );
00495 }
|
|
||||||||||||||||||||
|
Definition at line 754 of file gugr_planesweep.cpp.
00756 {
00757
00758 Map<eventrec>::Node enode,evnode,evnode1;
00759 int side,sign;
00760 ListNode<segment *> *begseg;
00761 Map<linerec> SwS;
00762 segment *seg;
00763 ListNode<Map<linerec>::Node> *lrefnode,*lstnode;
00764 Map<linerec>::Node lnode,lnodelo,lnodehi,lnode1,lnode2;
00765 linerec *vlin = 0, *lin;
00766 bool addvend,iflag,iexflag,checkneighbors;
00767 RefMap<intersection>::Node irnode, irnode1;
00768 intersection *irec;
00769 ListNode<linepair> *lpnode;
00770 linepair lpair;
00771 List<intersection> Ipts;
00772 List<intersectionseg> Isegs;
00773 int maxE;
00774
00775 maxE = nsegs*4;
00776
00777 /*--- loop until event queue empty ---*/
00778
00779 for(;;)
00780 {
00781 enode = EvQ.First();
00782 if( enode.IsEmpty() ) break; // queue empty
00783
00784 /*--- process starting vertical segments ---*/
00785
00786 while( enode.key()->BV.nElems > 0 )
00787 {
00788 begseg = enode.key()->BV.First();
00789 enode.key()->BV.Remove( begseg );
00790
00791 /*
00792 cout << "[processing starting vertical line segment]: ";
00793 DumpPS<float>::dump_segment( begseg->el );
00794 */
00795
00796 addvend = false;
00797 if( vlin == 0 )
00798 {
00799 vlin = new linerec( begseg->el );
00800 delete begseg;
00801 addvend = true;
00802 }
00803 else
00804 {
00805 vlin->S.Append( begseg ); // add line-segment (using ex. list node)
00806
00807 sign = compare( begseg->el->E.y, vlin->E.y );
00808 if( sign > 0 )
00809 {
00810 vlin->E = begseg->el->E;
00811
00812 /* remove old vertical-line-end event */
00813
00814 vlin->endev.key()->EV = 0;
00815
00816 if( (vlin->endev.key()->IsEmpty()) &&
00817 (vlin->endev.key() != enode.key()) )
00818 {
00819 EvQ.RemoveNode( vlin->endev );
00820 EvQ.FreeNode( vlin->endev );
00821 }
00822
00823 addvend = true;
00824 }
00825 }
00826 if( addvend )
00827 {
00828 /* add new vertical-line-end event */
00829
00830 side = EvQ.SearchNode( &vlin->E, compare_point_to_eventrec, &evnode );
00831 if( side != 0 )
00832 {
00833 evnode1 = EvQ.NewNode( vlin->E );
00834 EvQ.InsertNode( evnode1, evnode, side );
00835 evnode = evnode1;
00836 }
00837 evnode.key()->EV = vlin;
00838 vlin->endev = evnode;
00839 }
00840 }
00841
00842 /* check if current event point is a intersection point */
00843
00844 if( enode.key()->I.nElems > 0 )
00845 iexflag = true;
00846 else
00847 iexflag = false;
00848
00849 if( iexflag ||
00850 ((vlin != 0) && (enode.key()->B.nElems > 0)) ||
00851 ((vlin != 0) && (!enode.key()->E.IsEmpty())) ||
00852 ((enode.key()->B.nElems > 0) && (!enode.key()->E.IsEmpty())) )
00853 {
00854 iflag = true;
00855 if( iexflag )
00856 {
00857 /* get the intersection record from one of two intersecting lines */
00858
00859 lin = enode.key()->I.First()->el.L1.key();
00860 side = lin->I.SearchNode( &enode.key()->key,
00861 hcompare_point_to_intersection, &irnode );
00862 gul::Assert<InternalError>( ndebug || (side == 0) );
00863
00864 irec = irnode.key();
00865 }
00866 else
00867 {
00868 /* create a new intersection record */
00869
00870 irec = new intersection( enode.key()->key );
00871 Ipts.Append(irec);
00872 }
00873 }
00874 else
00875 iflag = false;
00876
00877 /* --- add intersection to vertical line --- */
00878
00879 if( vlin && iflag )
00880 {
00881 side = vlin->I.SearchNode(
00882 &irec->I, vcompare_point_to_intersection, &irnode1 );
00883 if( side != 0 )
00884 {
00885 irnode = vlin->I.NewNode(irec);
00886 vlin->I.InsertNode( irnode, irnode1, side );
00887 }
00888 }
00889
00890 /*--- process ending lines ---*/
00891
00892 lrefnode = enode.key()->E.First();
00893 while( lrefnode != 0 )
00894 {
00895 /* first element in list of lines ending in current event point */
00896
00897 lnode = lrefnode->el;
00898 lrefnode = lrefnode->next;
00899
00900 if( iflag )
00901 {
00902 /* add intersection record (if not already existing) */
00903
00904 side = lnode.key()->I.SearchNode( &irec->I,
00905 hcompare_point_to_intersection, &irnode );
00906 if( side != 0 )
00907 {
00908 irnode1 = lnode.key()->I.NewNode(irec);
00909 lnode.key()->I.InsertNode( irnode1, irnode, side );
00910 }
00911 }
00912
00913 lnodelo = SwS.Predecessor( lnode ); /* get neighbors in symetric order */
00914 lnodehi = SwS.Successor( lnode );
00915
00916 SwS.RemoveNode( lnode ); /* remove ending line from symmetric order */
00917
00918 /* intersect neighbors */
00919
00920 if( !lnodelo.IsEmpty() && !lnodehi.IsEmpty() )
00921 intersect( lnodelo, lnodehi, enode.key()->key.x, &EvQ, &Ipts );
00922 }
00923
00924 /* process intersecting lines */
00925
00926 while( enode.key()->I.nElems > 0 )
00927 {
00928 lpnode = enode.key()->I.First();
00929 enode.key()->I.Remove( lpnode );
00930 lpair = lpnode->el;
00931 delete lpnode; // free list node
00932
00933 lnode1 = lpair.L1;
00934 lnode2 = lpair.L2;
00935
00936 if( !SwS.IsRemoved(lnode1) && !SwS.IsRemoved(lnode2) )
00937 {
00938 SwS.RemoveNode( lnode1 );
00939 SwS.RemoveNode( lnode2 );
00940
00941 lnode1.key()->B = enode.key()->key;
00942 lnode2.key()->B = enode.key()->key;
00943
00944 side = SwS.SearchNode( lnode1.key(), compare_linerec_to_linerec,
00945 &lnode );
00946 gul::Assert<InternalError>(ndebug | (side!=0) );
00947
00948 SwS.InsertNode(lnode1,lnode,side); // reinsert
00949
00950 lnodelo = SwS.Predecessor( lnode1 ); /* get neighbors in order */
00951 lnodehi = SwS.Successor( lnode1 );
00952
00953 if( !lnodelo.IsEmpty() )
00954 intersect( lnodelo, lnode1, enode.key()->key.x, &EvQ, &Ipts );
00955 if( !lnodehi.IsEmpty() )
00956 intersect( lnodehi, lnode1, enode.key()->key.x, &EvQ, &Ipts );
00957
00958 side = SwS.SearchNode( lnode2.key(), compare_linerec_to_linerec,
00959 &lnode );
00960 gul::Assert<InternalError>(ndebug | (side!=0) );
00961
00962 SwS.InsertNode(lnode2,lnode,side); // reinsert
00963
00964 lnodelo = SwS.Predecessor( lnode2 ); /* get neighbors in order */
00965 lnodehi = SwS.Successor( lnode2 );
00966
00967 if( !lnodelo.IsEmpty() )
00968 intersect( lnodelo, lnode2, enode.key()->key.x, &EvQ, &Ipts );
00969 if( !lnodehi.IsEmpty() )
00970 intersect( lnodehi, lnode2, enode.key()->key.x, &EvQ, &Ipts );
00971 }
00972 }
00973
00974 /* process beginning lines */
00975
00976 while( enode.key()->B.nElems > 0 )
00977 {
00978 begseg = enode.key()->B.First();
00979 enode.key()->B.Remove( begseg );
00980 seg = begseg->el;
00981
00982 side = SwS.SearchNode( seg, compare_segment_to_linerec, &lnode );
00983 if( side == 0 ) // colinear with existing line
00984 {
00985 lnode.key()->S.Append( begseg ); // add line-segment (using list node)
00986
00987 sign = compare( begseg->el->E.x, lnode.key()->E.x );
00988 if( sign > 0 )
00989 {
00990 lnode.key()->E = begseg->el->E;
00991
00992 /* remove old line-end event */
00993
00994 lnode.key()->endev.key()->E.Remove( lnode.key()->endev_node );
00995 delete lnode.key()->endev_node; // delete line-end lstnode
00996
00997 if( lnode.key()->endev.key()->IsEmpty() )
00998 {
00999 EvQ.RemoveNode( lnode.key()->endev );
01000 EvQ.FreeNode( lnode.key()->endev );
01001 }
01002
01003 checkneighbors = true;
01004 }
01005 else
01006 {
01007 checkneighbors = false;
01008 }
01009 }
01010 else
01011 {
01012 delete begseg; // delete list node;
01013
01014 lnode1 = SwS.NewNode( seg );
01015 SwS.InsertNode( lnode1, lnode, side );
01016 lnode = lnode1;
01017
01018 checkneighbors = true;
01019 }
01020
01021 if( checkneighbors )
01022 {
01023 lnodelo = SwS.Predecessor( lnode ); /* get neighbors in order */
01024 lnodehi = SwS.Successor( lnode );
01025
01026 lstnode = new ListNode< Map<linerec>::Node >(lnode);
01027
01028 side = EvQ.SearchNode( &seg->E, compare_point_to_eventrec, &evnode );
01029 if( side != 0 )
01030 {
01031 evnode1 = EvQ.NewNode( seg->E );
01032 EvQ.InsertNode( evnode1, evnode, side );
01033 evnode = evnode1;
01034 }
01035
01036 evnode.key()->E.Append( lstnode );
01037
01038 lnode.key()->endev = evnode;
01039 lnode.key()->endev_node = lstnode;
01040
01041 if( !lnodelo.IsEmpty() )
01042 intersect( lnodelo, lnode, enode.key()->key.x, &EvQ, &Ipts );
01043 if( !lnodehi.IsEmpty() )
01044 intersect( lnodehi, lnode, enode.key()->key.x, &EvQ, &Ipts );
01045 }
01046
01047 if( iflag )
01048 {
01049 /* add intersection record (if not already existing) */
01050
01051 side = lnode.key()->I.SearchNode( &irec->I,
01052 hcompare_point_to_intersection, &irnode );
01053 if( side != 0 )
01054 {
01055 irnode1 = lnode.key()->I.NewNode(irec);
01056 lnode.key()->I.InsertNode( irnode1, irnode, side );
01057 }
01058 }
01059 }
01060
01061 /* --- process end of vertical line --- */
01062
01063 if( enode.key()->EV != 0 )
01064 {
01065 /* find linerecs passing between start and end of vertical line */
01066
01067 if( !SwS.IsEmpty() )
01068 {
01069 side = SwS.SearchNode( &enode.key()->EV->B, compare_point_to_linerec,
01070 &lnode );
01071 if( side > 0 )
01072 lnode = SwS.Successor( lnode );
01073
01074 do
01075 {
01076 if( !lnode.IsEmpty() )
01077 {
01078 irec = intersect_vert( vlin, lnode, &Ipts );
01079 lnode = SwS.Successor( lnode );
01080 }
01081 }
01082 while( !lnode.IsEmpty() && (irec != 0) );
01083 }
01084
01085 // cout << "[before finish_vertline]: ";
01086 // DumpPS<float>::dump_linerec( enode.key()->EV );
01087
01088 finish_vertline( vlin, E, V, maxE, &Ipts, &Isegs );
01089
01090 delete vlin;
01091 vlin = 0;
01092 }
01093
01094 /* --- process finished lines --- */
01095
01096 while( (lrefnode = enode.key()->E.First()) != 0 )
01097 {
01098 enode.key()->E.Remove( lrefnode );
01099 lnode = lrefnode->el;
01100 delete lrefnode;
01101
01102 /*
01103 cout << "[before finish_line]: ";
01104 DumpPS<float>::dump_linerec( lnode.key() );
01105 */
01106
01107 finish_line( lnode.key(), E, V, maxE, &Ipts, &Isegs );
01108 SwS.FreeNode(lnode); // already removed, see above
01109 }
01110
01111 EvQ.RemoveNode( enode );
01112 EvQ.FreeNode(enode);
01113 }
01114
01115 /*
01116 gugr::Dump<float>::dump_vertices( V.head );
01117 gugr::Dump<float>::dump_edges( E.head );
01118 */
01119
01120 /*
01121 cout << "\nINTERSECTIONS\n";
01122 cout << "=============\n";
01123 DumpPS<float>::dump_intersections( Ipts );
01124 cout << "\n";
01125 DumpPS<float>::dump_intersectionsegs( Isegs );
01126 */
01127
01128 Ipts.DeleteElems();
01129 Isegs.DeleteElems();
01130 }
|
|
||||||||||||||||||||||||
|
Definition at line 500 of file gugr_bool.cpp.
00506 {
00507 const int OutA = 1;
00508 const int InA = 2;
00509 const int OutB = 4;
00510 const int InB = 8;
00511 graph_edge_list E;
00512 graph_vertex_list V;
00513 segment_list S,Stmp;
00514 List<contour_node> contours;
00515 contour_node universe(0); // pseudo contour which contains everything
00516
00517 // get the segments of both polygons and mark them with
00518 // InA,OutA,InB,OutB
00519 OddEvenRule( PA, far_x, far_y, InA, OutA, E, V, S );
00520 OddEvenRule( PB, far_x, far_y, InB, OutB, E, V, Stmp );
00521 S += Stmp;
00522
00523 // find all contours and build their containment tree
00524 ContainmentTree( S, far_x, far_y, contours, universe );
00525 // universe.dump(0);
00526
00527 UnionSubTree( &universe, 0, OutA, OutB, C );
00528 }
|
|
||||||||||||
|
Definition at line 255 of file gugr_io.h.
00256 {
00257 s << "[" << S->f[0].i << ", " << S->f[1].i << "] B=("
00258 << S->B << "), (" << S->E << ")\n";
00259 }
|
|
||||||||||||||||
|
Definition at line 373 of file gugr_basics.cpp.
00374 {
00375 graph_edge *a0,*a;
00376 int i;
00377
00378 A[0] = a0 = a = e;
00379
00380 if( a->v[0] == v )
00381 a = a->e[0];
00382 else
00383 a = a->e[1];
00384
00385 i = 1;
00386 while( a != a0 )
00387 {
00388 A[i] = a;
00389 i++;
00390
00391 if( a->v[0] == v )
00392 a = a->e[0];
00393 else
00394 a = a->e[1];
00395 }
00396
00397 return(i);
00398 }
|
|
||||||||||||
|
Definition at line 245 of file gugr_regularize.cpp.
00246 {
00247 graph_edge *left, *right, **E;
00248 graph_vertex *v0 = e->v[0], *v1 = e->v[1];
00249 int ileft, iright, codel, coder, nE;
00250
00251 E = (graph_edge **)alloca( sizeof(graph_edge *) * maxE );
00252 if( E == NULL ) throw AllocError();
00253
00254 nE = IncidentEdges( v0, E );
00255 EdgeInsertPosition( v0->v, v1->v, nE, E, &ileft, &iright,
00256 &codel, &coder );
00257 left = E[ileft]; right = E[iright];
00258
00259 if( left->v[0] == v0 )
00260 left->e[0] = e;
00261 else
00262 left->e[1] = e;
00263
00264 e->e[0] = right;
00265
00266 if( left->v[0] == v0 )
00267 e->f[1] = left->f[0];
00268 else
00269 e->f[1] = left->f[1];
00270
00271 if( right->v[0] == v0 )
00272 e->f[0] = right->f[1];
00273 else
00274 e->f[0] = right->f[0];
00275
00276 nE = IncidentEdges( v1, E );
00277
00278 EdgeInsertPosition( v1->v, v0->v, nE, E, &ileft, &iright,
00279 &coder, &codel );
00280 left = E[ileft]; right = E[iright];
00281
00282 if( left->v[0] == v1 )
00283 left->e[0] = e;
00284 else
00285 left->e[1] = e;
00286
00287 e->e[1] = right;
00288 }
|
|
||||||||||||||||||||||||||||||||||||
|
Definition at line 725 of file gugr_basics.cpp.
00730 {
00731 vertex v1,v2,v3;
00732 int left,right,mid,sign,s1,s2,s3,tmp;
00733 int match = 0;
00734
00735 left = 0;
00736 right = nE-1;
00737
00738 if( right > 0 )
00739 {
00740 if( E[left]->v[0]->v == a ) v1 = E[left]->v[1]->v;
00741 else v1 = E[left]->v[0]->v;
00742 if( E[right]->v[0]->v == a ) v2 = E[right]->v[1]->v;
00743 else v2 = E[right]->v[0]->v;
00744
00745 sign = CompareAngles( a.v(), b.v(), v1.v(), v2.v(),
00746 &match, &s1, &s2 );
00747 if( sign > 0 )
00748 {
00749 if( match )
00750 {
00751 if( right-1 != left ) s1 = 0;
00752 left = right-1;
00753 }
00754 else
00755 {
00756 mid = (left+right)/2;
00757
00758 while( mid != left )
00759 {
00760 if( E[mid]->v[0]->v == a ) v3 = E[mid]->v[1]->v;
00761 else v3 = E[mid]->v[0]->v;
00762
00763 sign = CompareAngles( a.v(), b.v(), v1.v(), v3.v(),
00764 &match, &s1, &s3 );
00765 if( match )
00766 {
00767 right = mid;
00768 s2 = s3;
00769 if( mid-1 != left ) s1 = 0;
00770 left = mid-1;
00771 break;
00772 }
00773
00774 if( sign > 0 )
00775 {
00776 right = mid;
00777 s2 = s3;
00778 }
00779 else if( sign < 0 )
00780 {
00781 left = mid;
00782 v1 = v3;
00783 s1 = s3;
00784 }
00785 else
00786 throw InternalError(); /* this cannot be */
00787
00788 mid = (left+right)/2;
00789 }
00790 }
00791 }
00792 else
00793 {
00794 gul::Assert< gul::InternalError >( ndebug ||
00795 ((sign != 0) && (left == 0) && (right == nE-1)) );
00796
00797 tmp = left; left = right; right = tmp;
00798 tmp = s1; s1 = s2; s2 = tmp;
00799 }
00800 }
00801 else
00802 {
00803 right = left;
00804 s1 = s2 = 0;
00805 }
00806
00807 if( s1 == 0 )
00808 {
00809 if( E[left]->v[0]->v == a ) v1 = E[left]->v[1]->v;
00810 else v1 = E[left]->v[0]->v;
00811
00812 s1 = DetermineOrientation( a.v(), b.v(), v1.v() ) + 2;
00813 }
00814 if( s2 == 0 )
00815 {
00816 if( right != left )
00817 {
00818 if( E[right]->v[0]->v == a ) v2 = E[right]->v[1]->v;
00819 else v2 = E[right]->v[0]->v;
00820
00821 s2 = DetermineOrientation( a.v(), b.v(), v2.v() ) + 2;
00822 }
00823 else
00824 s2 = s1;
00825 }
00826
00827 *eleft = left;
00828 *eright = right;
00829 *code_left = s1;
00830 *code_right = s2;
00831 return(match);
00832 }
|
|
||||||||||||||||||||||||||||
|
Definition at line 489 of file gugr_contour.cpp.
00494 {
00495 graph_edge *e,*laste;
00496 ListNode<segment> *sn;
00497 contour_node *cn;
00498 ListNode<segment> *hn;
00499 segment *h,*lastseg;
00500
00501 outsegs.DeleteElems();
00502
00503 // reserve a new segment struct for each edge (needed later for the
00504 // classification of the formed regions with the odd/even winding rule)
00505
00506 e = E.First();
00507 while( e )
00508 {
00509 sn = new ListNode<segment>;
00510 outsegs.Append(sn);
00511
00512 // orient the segments as the planesweep algorithm expects them
00513
00514 if( e->l.IsHorizontal() || (e->l.dx().test() < 0) )
00515 {
00516 sn->el.B = e->v[1]->v.v();
00517 sn->el.E = e->v[0]->v.v();
00518 }
00519 else
00520 {
00521 sn->el.B = e->v[0]->v.v();
00522 sn->el.E = e->v[1]->v.v();
00523 }
00524 sn->el.l = e->l;
00525 sn->el.m = e->reserved[0].i; // multiplicity of edge (for winding rule)
00526
00527 e->reserved[2].p = &sn->el; // back pointer edge -> new segment
00528 e = e->next;
00529 }
00530
00531 // find the non-intersecting regions
00532
00533 e = E.First();
00534 laste = 0;
00535 lastseg = 0;
00536
00537 while( e )
00538 {
00539 /*
00540 cout << "processing edge " << (void *)e << "\n";
00541 */
00542
00543 if( e->f[0].p )
00544 {
00545 cn = new contour_node(0); // new contour
00546 contours.Append(cn);
00547 cn->seg = (segment *)e->reserved[2].p;
00548
00549 LeftSideContour( e, E, cn );
00550
00551 if( e != laste )
00552 {
00553 // construct a help line for each contour for classifying it
00554 // later with an odd/even winding rule
00555
00556 hn = new ListNode<segment>;
00557 outsegs.Append(hn);
00558 h = &hn->el;
00559
00560 if( !e->l.IsHorizontal() ) // horizontal help line
00561 {
00562 h->E.y =
00563 (e->v[0]->v.v().y + e->v[1]->v.v().y)/rational(ULong(2));
00564 h->E.x = far_maxx;
00565
00566 intersect_horiz( h->E.y, e->l, h->B );
00567
00568 h->f[0].p = h->f[1].p = 0; // edge/side pairs belong to no contour
00569 h->l = line( h->E, rational(ULong(1)), rational(ULong(0)) );
00570 }
00571 else // vertical help line
00572 {
00573 h->E.x =
00574 (e->v[0]->v.v().x + e->v[1]->v.v().x)/rational(ULong(2));
00575 h->E.y = far_maxy;
00576
00577 intersect_vert( h->E.x, e->l, h->B );
00578
00579 h->f[0].p = h->f[1].p = 0; // edge/side pairs belong to no contour
00580
00581 h->l = line( h->E, rational(ULong(0)), rational(ULong(1)) );
00582 }
00583
00584 cn->hseg = h; // remember the address of the created help line
00585 cn->hseg_firstref = true;
00586
00587 /*
00588 DumpPS<float>::dump_segment( h );
00589 */
00590
00591 laste = e;
00592 lastseg = h;
00593 }
00594 else
00595 {
00596 cn->hseg = lastseg; // remember the address of the created help line
00597 cn->hseg_firstref = false;
00598
00599 /*
00600 DumpPS<float>::dump_segment( lastseg );
00601 */
00602 }
00603 }
00604
00605 if( e->f[1].p )
00606 {
00607 cn = new contour_node(0); // new contour
00608 contours.Append(cn);
00609 cn->seg = (segment *)e->reserved[2].p;
00610
00611 RightSideContour( e, E, cn );
00612
00613 if( e != laste )
00614 {
00615 // construct a help line for each contour for classifying it
00616 // later with an odd/even winding rule
00617
00618 hn = new ListNode<segment>;
00619 outsegs.Append(hn);
00620 h = &hn->el;
00621
00622 if( !e->l.IsHorizontal() ) // horizontal help line
00623 {
00624 h->E.y =
00625 (e->v[0]->v.v().y + e->v[1]->v.v().y)/rational(ULong(2));
00626 h->E.x = far_maxx;
00627
00628 intersect_horiz( h->E.y, e->l, h->B );
00629
00630 h->f[0].p = h->f[1].p = 0; // edge/side pairs belong to no contour
00631 h->l = line( h->E, rational(ULong(1)), rational(ULong(0)) );
00632 }
00633 else // vertical help line
00634 {
00635 h->E.x =
00636 (e->v[0]->v.v().x + e->v[1]->v.v().x)/rational(ULong(2));
00637 h->E.y = far_maxy;
00638
00639 intersect_vert( h->E.x, e->l, h->B );
00640
00641 h->f[0].p = h->f[1].p = 0; // edge/side pairs belong to no contour
00642
00643 h->l = line( h->E, rational(ULong(0)), rational(ULong(1)) );
00644 }
00645 cn->hseg = h; // remember the address of the created help line
00646 cn->hseg_firstref = true;
00647
00648 /*
00649 DumpPS<float>::dump_segment( h );
00650 */
00651
00652 laste = e;
00653 lastseg = h;
00654 }
00655 else
00656 {
00657 cn->hseg = lastseg; // remember the address of the created help line
00658 cn->hseg_firstref = false;
00659
00660 /*
00661 DumpPS<float>::dump_segment( lastseg );
00662 */
00663 }
00664 }
00665
00666 e = e->next;
00667 }
00668 }
|
|
||||||||||||||||||||
|
Definition at line 332 of file gugr_split.cpp.
00334 {
00335 int mid,right,left,sign;
00336
00337 if( nA == 0 ) {found = false; return -1;}
00338
00339 sign = compare( A[0].val, x );
00340 if( sign >= 0 )
00341 {
00342 if( sign > 0 ) {found = false; return -1;}
00343 found = true; return 0;
00344 }
00345
00346 sign = compare( A[nA-1].val, x );
00347 if( sign <= 0 )
00348 {
00349 if( sign < 0 ) {found = false; return nA-1;}
00350 found = true; return nA-1;
00351 }
00352
00353 left = 0;
00354 right = nA;
00355 mid = (left+right)/2;
00356
00357 while( (mid!=left) && (mid!=right) )
00358 {
00359 sign = compare( A[mid].val, x );
00360
00361 if( sign == 0 )
00362 break;
00363 else if( sign > 0 )
00364 {
00365 right = mid;
00366 mid = (left+right)>>1;
00367 }
00368 else
00369 {
00370 left = mid;
00371 mid = (left+right)>>1;
00372 }
00373 }
00374
00375 found = (sign == 0);
00376 return mid;
00377 }
|
|
||||||||||||||||||||||||||||
|
Definition at line 246 of file gugr_planesweep.cpp.
00249 {
00250 ListNode<segment *> *segref = L->S.First();
00251 segment *seg;
00252 int side;
00253 intersection *i,*i1,*i2;
00254 intersectionseg *is;
00255 RefMap<intersection>::Node irnode,irnode1;
00256 Ptr<intersection *> I;
00257 int nI,j;
00258 segtree SegTr;
00259 int left,right,mid,iB,iE,sign,nLf;
00260 Ptr<segnode *> Lf;
00261 segnode *snode;
00262 RefMap<segment>::Node segnod;
00263 graph_edge *e;
00264 RefMap<void>::Node leftowner,rightowner,leftowner1,rightowner1;
00265 RefMap<void> *leftowners,*rightowners;
00266 List< ListNode< ListNodeInfo< ListNode<graph_edge *> > > > *ownerrecs;
00267 ListNode< ListNodeInfo< ListNode<graph_edge *> > > *orec;
00268 ListNode<graph_edge *> *erec;
00269
00270 while( segref != 0 )
00271 {
00272 seg = segref->el;
00273
00274 /* --- add segment endpoints as intersections --- */
00275
00276 side = L->I.SearchNode( &seg->B, hcompare_point_to_intersection,
00277 &irnode );
00278 if( side != 0 )
00279 {
00280 i = new intersection( seg->B );
00281 Ipts->Append(i);
00282
00283 irnode1 = L->I.NewNode(i);
00284 L->I.InsertNode( irnode1, irnode, side );
00285 }
00286
00287 side = L->I.SearchNode( &seg->E, hcompare_point_to_intersection,
00288 &irnode );
00289 if( side != 0 )
00290 {
00291 i = new intersection( seg->E );
00292 Ipts->Append(i);
00293
00294 irnode1 = L->I.NewNode(i);
00295 L->I.InsertNode( irnode1, irnode, side );
00296 }
00297
00298 segref = segref->next;
00299 }
00300
00301 nI = L->I.ConvertToArray( &I );
00302
00303 SegTr.init( nI, I );
00304
00305 segref = L->S.First();
00306
00307 while( segref != 0 )
00308 {
00309 seg = segref->el;
00310
00311 left = 0;
00312 right = nI;
00313 mid = (left+right)/2;
00314
00315 for(;;)
00316 {
00317 sign = compare( seg->B.x, I[mid]->I.x );
00318 if( sign == 0 )
00319 break;
00320 else if( sign < 0 )
00321 {
00322 right = mid;
00323 mid = (left+right)/2;
00324 }
00325 else
00326 {
00327 left = mid;
00328 mid = (left+right)/2;
00329 }
00330 }
00331 iB = mid;
00332
00333 left = 0;
00334 right = nI;
00335 mid = (left+right)/2;
00336
00337 for(;;)
00338 {
00339 sign = compare( seg->E.x, I[mid]->I.x );
00340 if( sign == 0 )
00341 break;
00342 else if( sign < 0 )
00343 {
00344 right = mid;
00345 mid = (left+right)/2;
00346 }
00347 else
00348 {
00349 left = mid;
00350 mid = (left+right)/2;
00351 }
00352 }
00353 iE = mid;
00354
00355 SegTr.insert( iB, iE, seg );
00356
00357 segref = segref->next;
00358 }
00359
00360 nLf = SegTr.leaves_to_array( &Lf );
00361
00362 for( j = 0; j < nLf; j++ )
00363 {
00364 e = new graph_edge;
00365 E->Append(e);
00366
00367 i1 = SegTr.m_absz[Lf[j]->m_il];
00368 if( i1->v == 0 )
00369 {
00370 i1->v = new graph_vertex( i1->I, 0 );
00371 V->Append(i1->v);
00372 }
00373 i2 = SegTr.m_absz[Lf[j]->m_ir];
00374 if( i2->v == 0 )
00375 {
00376 i2->v = new graph_vertex( i2->I, 0 );
00377 V->Append(i2->v);
00378 }
00379 e->v[0] = i1->v;
00380 e->v[1] = i2->v;
00381 e->l = L->l;
00382
00383 /* --- set owner lists of intersections --- */
00384
00385 is = new intersectionseg(e);
00386 Isegs->Append(is);
00387
00388 /* initialize sets of owners of left and right side of the edge */
00389
00390 leftowners = new RefMap<void>;
00391 rightowners = new RefMap<void>;
00392 e->f[0].p = leftowners;
00393 e->f[1].p = rightowners;
00394 e->reserved[0].set_i(0);
00395 ownerrecs = new List< ListNode< ListNodeInfo< ListNode<graph_edge *> > > >;
00396 e->reserved[1].p = ownerrecs;
00397
00398 snode = Lf[j];
00399 while( snode )
00400 {
00401 segnod = snode->m_segs.First();
00402
00403 while( !segnod.IsEmpty() )
00404 {
00405 // increment number of owners by the multiplicity of the segments
00406 // which contain the edge
00407
00408 e->reserved[0].i += segnod.key()->m;
00409
00410 /* add owner to the set of owners of the left side of the edge */
00411
00412 side = leftowners->SearchNode( (void *)segnod.key()->f[0].p,
00413 compare_pointer_to_pointer, &leftowner );
00414 if( side != 0 )
00415 {
00416 leftowner1 = leftowners->NewNode((void *)segnod.key()->f[0].p);
00417 leftowners->InsertNode( leftowner1, leftowner, side );
00418 }
00419
00420 /* add owner to the set of owners of the right side of the edge */
00421
00422 side = rightowners->SearchNode( (void *)segnod.key()->f[1].p,
00423 compare_pointer_to_pointer, &rightowner );
00424 if( side != 0 )
00425 {
00426 rightowner1 = rightowners->NewNode((void *)segnod.key()->f[1].p);
00427 rightowners->InsertNode( rightowner1, rightowner, side );
00428 }
00429
00430 /* add edge to the list of edges for the original input segment */
00431
00432 erec = new ListNode<graph_edge *>(e);
00433 segnod.key()->e.Append( erec );
00434
00435 /* add a backpointer to the corresponding edge record in the edge
00436 list of the input segment; this makes it later possible to remove
00437 all references to an edge from all input segments */
00438
00439 orec = new ListNode< ListNodeInfo< ListNode<graph_edge *> > >(
00440 ListNodeInfo< ListNode<graph_edge *> >(&segnod.key()->e, erec) );
00441 ownerrecs->Append(orec);
00442
00443 /* the owner lists of the intersection records are only for debugging */
00444 /*
00445 owner = new ListNode<segment *>(segnod.key());
00446 i1->S.Append(owner);
00447 owner = new ListNode<segment *>(segnod.key());
00448 is->S.Append(owner);
00449 */
00450 segnod = snode->m_segs.Successor(segnod);
00451 }
00452 snode = snode->m_parent;
00453 }
00454
00455 OrientEdge( e );
00456 ConnectEdge( e, maxE );
00457 }
00458
00459 /* --- set owner list of endpoint - intersection --- */
00460 /*
00461 if( (j=nLf-1) >= 0 )
00462 {
00463 snode = Lf[j];
00464 while( snode )
00465 {
00466 segnod = snode->m_segs.First();
00467 while( !segnod.IsEmpty() )
00468 {
00469 owner = new ListNode<segment *>(segnod.key());
00470 i2->S.Append(owner);
00471 segnod = snode->m_segs.Successor(segnod);
00472 }
00473 snode = snode->m_parent;
00474 }
00475 }
00476 */
00477 }
|
|
||||||||||||||||||||||||||||
|
Definition at line 489 of file gugr_planesweep.cpp.
00492 {
00493 ListNode<segment *> *segref = L->S.First();
00494 segment *seg;
00495 int side;
00496 intersection *i,*i1,*i2;
00497 intersectionseg *is;
00498 RefMap<intersection>::Node irnode,irnode1;
00499 Ptr<intersection *> I;
00500 int nI,j;
00501 segtree SegTr;
00502 int left,right,mid,iB,iE,sign,nLf;
00503 Ptr<segnode *> Lf;
00504 segnode *snode;
00505 RefMap<segment>::Node segnod;
00506 graph_edge *e;
00507 RefMap<void>::Node leftowner,rightowner,leftowner1,rightowner1;
00508 RefMap<void> *leftowners,*rightowners;
00509 List< ListNode< ListNodeInfo< ListNode<graph_edge *> > > > *ownerrecs;
00510 ListNode< ListNodeInfo< ListNode<graph_edge *> > > *orec;
00511 ListNode<graph_edge *> *erec;
00512
00513 while( segref != 0 )
00514 {
00515 seg = segref->el;
00516
00517 /* --- add segment endpoints as intersections --- */
00518
00519 side = L->I.SearchNode( &seg->B, vcompare_point_to_intersection,
00520 &irnode );
00521 if( side != 0 )
00522 {
00523 i = new intersection( seg->B );
00524 Ipts->Append(i);
00525
00526 irnode1 = L->I.NewNode(i);
00527 L->I.InsertNode( irnode1, irnode, side );
00528 }
00529
00530 side = L->I.SearchNode( &seg->E, vcompare_point_to_intersection,
00531 &irnode );
00532 if( side != 0 )
00533 {
00534 i = new intersection( seg->E );
00535 Ipts->Append(i);
00536
00537 irnode1 = L->I.NewNode(i);
00538 L->I.InsertNode( irnode1, irnode, side );
00539 }
00540
00541 segref = segref->next;
00542 }
00543
00544 nI = L->I.ConvertToArray( &I );
00545
00546 SegTr.init( nI, I );
00547
00548 segref = L->S.First();
00549
00550 while( segref != 0 )
00551 {
00552 seg = segref->el;
00553
00554 left = 0;
00555 right = nI;
00556 mid = (left+right)/2;
00557
00558 for(;;)
00559 {
00560 sign = compare( seg->B.y, I[mid]->I.y );
00561 if( sign == 0 )
00562 break;
00563 else if( sign < 0 )
00564 {
00565 right = mid;
00566 mid = (left+right)/2;
00567 }
00568 else
00569 {
00570 left = mid;
00571 mid = (left+right)/2;
00572 }
00573 }
00574 iB = mid;
00575
00576 left = 0;
00577 right = nI;
00578 mid = (left+right)/2;
00579
00580 for(;;)
00581 {
00582 sign = compare( seg->E.y, I[mid]->I.y );
00583 if( sign == 0 )
00584 break;
00585 else if( sign < 0 )
00586 {
00587 right = mid;
00588 mid = (left+right)/2;
00589 }
00590 else
00591 {
00592 left = mid;
00593 mid = (left+right)/2;
00594 }
00595 }
00596 iE = mid;
00597
00598 SegTr.insert( iB, iE, seg );
00599
00600 segref = segref->next;
00601 }
00602
00603 nLf = SegTr.leaves_to_array( &Lf );
00604
00605 for( j = 0; j < nLf; j++ )
00606 {
00607 e = new graph_edge;
00608 E->Append(e);
00609
00610 i1 = SegTr.m_absz[Lf[j]->m_il];
00611 if( i1->v == 0 )
00612 {
00613 i1->v = new graph_vertex( i1->I, 0 );
00614 V->Append(i1->v);
00615 }
00616 i2 = SegTr.m_absz[Lf[j]->m_ir];
00617 if( i2->v == 0 )
00618 {
00619 i2->v = new graph_vertex( i2->I, 0 );
00620 V->Append(i2->v);
00621 }
00622 e->v[0] = i1->v;
00623 e->v[1] = i2->v;
00624 e->l = L->l;
00625
00626 /* --- set owner lists of intersections --- */
00627
00628 is = new intersectionseg(e);
00629 Isegs->Append(is);
00630
00631 /* initialize sets of owners of left and right side of the edge */
00632
00633 leftowners = new RefMap<void>;
00634 rightowners = new RefMap<void>;
00635 e->f[0].p = leftowners;
00636 e->f[1].p = rightowners;
00637 e->reserved[0].set_i(0);
00638 ownerrecs = new List< ListNode< ListNodeInfo< ListNode<graph_edge *> > > >;
00639 e->reserved[1].p = ownerrecs;
00640
00641 snode = Lf[j];
00642 while( snode )
00643 {
00644 segnod = snode->m_segs.First();
00645
00646 while( !segnod.IsEmpty() )
00647 {
00648 // increment number of owners by the multiplicity of the segments
00649 // which contain the edge
00650
00651 e->reserved[0].i += segnod.key()->m;
00652
00653 /* add owner to the set of owners of the left side of the edge */
00654
00655 side = leftowners->SearchNode( (void *)segnod.key()->f[0].p,
00656 compare_pointer_to_pointer, &leftowner );
00657 if( side != 0 )
00658 {
00659 leftowner1 = leftowners->NewNode((void *)segnod.key()->f[0].p );
00660 leftowners->InsertNode( leftowner1, leftowner, side );
00661 }
00662
00663 /* add owner to the set of owners of the right side of the edge */
00664
00665 side = rightowners->SearchNode( (void *)segnod.key()->f[1].p,
00666 compare_pointer_to_pointer, &rightowner );
00667 if( side != 0 )
00668 {
00669 rightowner1 = rightowners->NewNode((void *)segnod.key()->f[1].p);
00670 rightowners->InsertNode( rightowner1, rightowner, side );
00671 }
00672
00673 /* add edge to the list of edges for the original input segment */
00674
00675 erec = new ListNode<graph_edge *>(e);
00676 segnod.key()->e.Append( erec );
00677
00678 /* add a backpointer to the corresponding edge record in the edge
00679 list of the input segment; this makes it later possible to remove
00680 all references to an edge from all input segments */
00681
00682 orec = new ListNode< ListNodeInfo< ListNode<graph_edge *> > >(
00683 ListNodeInfo< ListNode<graph_edge *> >(&segnod.key()->e, erec) );
00684 ownerrecs->Append(orec);
00685
00686 /* the owner lists of the intersection records are only for debugging */
00687 /*
00688 owner = new ListNode<segment *>(segnod.key());
00689 i1->S.Append(owner);
00690 owner = new ListNode<segment *>(segnod.key());
00691 is->S.Append(owner);
00692 */
00693
00694 segnod = snode->m_segs.Successor(segnod);
00695 }
00696 snode = snode->m_parent;
00697 }
00698
00699 OrientEdge( e );
00700 ConnectEdge( e, maxE );
00701 }
00702
00703 /* --- set owner list of endpoint - intersection --- */
00704 /*
00705 if( (j=nLf-1) >= 0 )
00706 {
00707 snode = Lf[j];
00708 while( snode )
00709 {
00710 segnod = snode->m_segs.First();
00711 while( !segnod.IsEmpty() )
00712 {
00713 owner = new ListNode<segment *>(segnod.key());
00714 i2->S.Append(owner);
00715 segnod = snode->m_segs.Successor(segnod);
00716 }
00717 snode = snode->m_parent;
00718 }
00719 }
00720 */
00721 }
|
|
||||||||||||
|
Definition at line 87 of file gugr_planesweep.cpp.
00088 {
00089 return compare( C->x, R->I.x );
00090 }
|
|
||||||||||||
|
Definition at line 341 of file gugr_basics.cpp.
00342 {
00343 graph_edge *a0,*a;
00344 int i;
00345
00346 a = A[0] = a0 = v->e;
00347 if( !a ) return 0;
00348
00349 if( a->v[0] == v )
00350 a = a->e[0];
00351 else
00352 a = a->e[1];
00353
00354 i = 1;
00355 while( a != a0 )
00356 {
00357 A[i] = a;
00358 i++;
00359
00360 if( a->v[0] == v )
00361 a = a->e[0];
00362 else
00363 a = a->e[1];
00364 }
00365
00366 return(i);
00367 }
|
|
||||||||||||||||||||||||||||||||||||
|
|
|
||||||||||||||||||||||||||||||||||||
|
|
|
||||||||||||||||||||||||||||||||||||||||
|
Definition at line 1748 of file gugr_split.cpp.
01753 {
01754
01755 graph_vertex *Vy1Sl, *Vy1Sr, *Vy2Sl, *Vy2Sr, *Vx1Sa, *Vx1Sb, *Vx2Sa, *Vx2Sb;
01756 graph_vertex *hvLeftT, *hvRightT;
01757 graph_edge *e, *el, **hE;
01758 graph_vertex *v, *v0;
01759 int nhE, nMaxE;
01760 Ptr< cut_info > CutsX, CutsY;
01761
01762 rational& MinX = Gconv->MinX; // short aliases
01763 rational& MaxX = Gconv->MaxX;
01764 rational& FarMinX = Gconv->FarMinX;
01765 rational& FarMaxX = Gconv->FarMaxX;
01766 rational& MinY = Gconv->MinY;
01767 rational& MaxY = Gconv->MaxY;
01768 rational& FarMinY = Gconv->FarMinY;
01769 rational& FarMaxY = Gconv->FarMaxY;
01770
01771 CutsX.reserve_place( reserve_stack(cut_info,3), 3 );
01772 CutsY.reserve_place( reserve_stack(cut_info,3), 3 );
01773
01774 CutsX[1].val = X1;
01775 CutsX[2].val = X2;
01776
01777 CutsY[1].val = Y1;
01778 CutsY[2].val = Y2;
01779
01780 nMaxE = 10 * E->nElems; // this is a hack, but its enough even in the
01781 // worst case
01782 hE = (graph_edge **)alloca( sizeof(graph_edge *) * nMaxE );
01783
01784 /*
01785 cout << "input graph\n";
01786 cout << "***********\n";
01787 gugr::Dump<T>::dump_vertices( V->head );
01788 gugr::Dump<T>::dump_edges( E->head );
01789 */
01790 // split graph into vertical strips
01791 IntersectWithVerticals( E, V, 3, CutsX );
01792
01793 // isolate first vertical strip and discard it
01794 DivideVerticalStrips( &CutsX[2], &CutsX[1], nMaxE,
01795 MinY, MaxY, FarMinY, FarMaxY,
01796 &Vy1Sr, &Vy1Sl, &Vy2Sr, &Vy2Sl );
01797 /*
01798 cout << "after disconnecting X-Strip " << 2 << " and " << 1 << "\n";
01799 cout << "*******************************************************\n";
01800 for( int k = 2; k >= 0; k-- )
01801 {
01802 cout << "X-Strip " << k << "\n";
01803 gugr::Dump<T>::dump_vertices( CutsX[k].V.head );
01804 gugr::Dump<T>::dump_edges( CutsX[k].E.head );
01805 }
01806 */
01807
01808 CutsX[2].R.DeleteElems();
01809 CutsX[2].E.DeleteElems();
01810 CutsX[2].V.DeleteElems();
01811
01812 DivideVerticalStrips( &CutsX[1], &CutsX[0], nMaxE,
01813 MinY, MaxY, FarMinY, FarMaxY,
01814 &Vy1Sr, &Vy1Sl, &Vy2Sr, &Vy2Sl );
01815 /*
01816 cout << "after disconnecting X-Strip " << 1 << " and " << 0 << "\n";
01817 cout << "*******************************************************\n";
01818 for( int k = 1; k >= 0; k-- )
01819 {
01820 cout << "X-Strip " << k << "\n";
01821 gugr::Dump<T>::dump_vertices( CutsX[k].V.head );
01822 gugr::Dump<T>::dump_edges( CutsX[k].E.head );
01823 }
01824 */
01825 // split vertical strips into horizontal strips
01826 IntersectWithHorizontals( &CutsX[1].E, &CutsX[1].V, 3, CutsY );
01827
01828 // isolate first strip and discard it
01829 DivideHorizontalStrips( &CutsY[2], &CutsY[1], nMaxE,
01830 MinX, MaxX, FarMinX, FarMaxX,
01831 &Vx1Sa, &Vx1Sb, &Vx2Sa, &Vx2Sb );
01832 /*
01833 cout << "after disconnecting Y-Strip " << 2 << " and " << 1 << "\n";
01834 cout << "*******************************************************\n";
01835 for( int k = 2; k >= 0; k-- )
01836 {
01837 cout << "Y-Strip " << k << "\n";
01838 gugr::Dump<T>::dump_vertices( CutsY[k].V.head );
01839 gugr::Dump<T>::dump_edges( CutsY[k].E.head );
01840 }
01841 */
01842 CutsY[2].R.DeleteElems();
01843 CutsY[2].E.DeleteElems();
01844 CutsY[2].V.DeleteElems();
01845
01846 hvLeftT = Vx1Sb; hvRightT = Vx2Sb; // for next strip
01847
01848 // divide vertical strips into horizontal strips
01849 DivideHorizontalStrips( &CutsY[1], &CutsY[0], nMaxE,
01850 MinX, MaxX, FarMinX, FarMaxX,
01851 &Vx1Sa, &Vx1Sb, &Vx2Sa, &Vx2Sb );
01852 /*
01853 cout << "after disconnecting Y-Strip " << 1 << " and " << 0 << "\n";
01854 cout << "*******************************************************\n";
01855 for( int k = 1; k >= 0; k-- )
01856 {
01857 cout << "Y-Strip " << k << "\n";
01858 gugr::Dump<T>::dump_vertices( CutsY[k].V.head );
01859 gugr::Dump<T>::dump_edges( CutsY[k].E.head );
01860 }
01861 */
01862
01863 v0 = hvLeftT; // remove help edges from the corner edge cycles
01864 e = v0->e;
01865 G->face = e->e[0]->f[1].i; // face index of quad, if it is
01866 v = e->v[0]; // not divided
01867 G->P[1][0] = v;
01868 nhE = EdgeCycle( e, v, hE );
01869 el = hE[nhE-1];
01870 if( el->v[0] == v ) el->e[0] = e->e[0]; else el->e[1] = e->e[0];
01871 v->e = el;
01872 CutsY[1].V.Remove(v0); CutsY[1].E.Remove(e);
01873 delete v0; delete e;
01874
01875 v0 = hvRightT;
01876 e = v0->e;
01877 v = e->v[1];
01878 G->P[1][1] = v;
01879 nhE = EdgeCycle( e, v, hE );
01880 el = hE[nhE-1];
01881 if( el->v[0] == v ) el->e[0] = e->e[1]; else el->e[1] = e->e[1];
01882 v->e = el;
01883 CutsY[1].V.Remove(v0); CutsY[1].E.Remove(e);
01884 delete v0; delete e;
01885
01886 v0 = Vx2Sa;
01887 e = v0->e;
01888 v = e->v[1];
01889 G->P[0][1] = v;
01890 nhE = EdgeCycle( e, v, hE );
01891 el = hE[nhE-1];
01892 if( el->v[0] == v ) el->e[0] = e->e[1]; else el->e[1] = e->e[1];
01893 v->e = el;
01894 CutsY[1].V.Remove(v0); CutsY[1].E.Remove(e);
01895 delete v0; delete e;
01896
01897 v0 = Vx1Sa;
01898 e = v0->e;
01899 v = e->v[0];
01900 G->P[0][0] = v;
01901 nhE = EdgeCycle( e, v, hE );
01902 el = hE[nhE-1];
01903 if( el->v[0] == v ) el->e[0] = e->e[0]; else el->e[1] = e->e[0];
01904 v->e = el;
01905 CutsY[1].V.Remove(v0); CutsY[1].E.Remove(e);
01906 delete v0; delete e;
01907
01908 CutsY[1].R.DeleteElems(); // free cut records only
01909
01910 G->E += CutsY[1].E;
01911 G->V += CutsY[1].V;
01912
01913 CutsY[0].R.DeleteElems();
01914 CutsY[0].E.DeleteElems();
01915 CutsY[0].V.DeleteElems();
01916
01917 CutsX[1].R.DeleteElems();
01918 CutsX[1].E.DeleteElems();
01919 CutsX[1].V.DeleteElems();
01920
01921 CutsX[0].R.DeleteElems();
01922 CutsX[0].E.DeleteElems();
01923 CutsX[0].V.DeleteElems();
01924 }
|
|
||||||||||||||||||||
|
Definition at line 176 of file gugr_split.cpp.
00180 {
00181 cut_record_list Recs;
00182 cut_record *rec;
00183 int nhE,L,R,match,cR,cL,ivh,ivl,maxE;
00184 graph_edge *e,*eh,*el,**hE;
00185 graph_vertex *lv;
00186 vertex *lowerleft = &P11->v;
00187 vertex *upperright = &P22->v;
00188 line lin;
00189
00190 IntersectWithAscendant( P11->v.v(), P22->v.v(), *E, *V, lin, Recs );
00191
00192 maxE = 3*E->nElems + V->nElems;
00193 hE = (graph_edge **)alloca( sizeof(graph_edge *)*maxE );
00194 if( hE == NULL ) throw AllocError();
00195
00196 rec = Recs.head;
00197 lv = rec->v;
00198 gul::Assert<InternalError>( ndebug || (lv == P11) );
00199 rec = rec->next;
00200
00201 while( rec != NULL )
00202 {
00203 if( rec->e == NULL ) /* vertex on diagonal */
00204 {
00205 nhE = IncidentEdges( rec->v, hE );
00206 match = EdgeInsertPosition( rec->v->v, *lowerleft, nhE, hE,
00207 &L, &R, &cL, &cR );
00208 if( cR != 2 ) // have to create a new edge
00209 {
00210 e = new graph_edge();
00211 E->Append(e);
00212
00213 e->v[0] = lv;
00214 e->v[1] = rec->v;
00215
00216 if( hE[L]->v[0] == rec->v ) // connect upper end of new edge
00217 {
00218 e->e[1] = hE[L]->e[0];
00219 hE[L]->e[0] = e;
00220 e->f[0] = e->f[1] = hE[L]->f[0];
00221 }
00222 else
00223 {
00224 e->e[1] = hE[L]->e[1];
00225 hE[L]->e[1] = e;
00226 e->f[0] = e->f[1] = hE[L]->f[1];
00227 }
00228
00229 nhE = IncidentEdges( lv, hE );
00230 match = EdgeInsertPosition( lv->v, *upperright, nhE, hE,
00231 &L, &R, &cL, &cR );
00232 if( hE[L]->v[0] == lv ) // connect lower end of new edge
00233 {
00234 e->e[0] = hE[L]->e[0];
00235 hE[L]->e[0] = e;
00236 }
00237 else
00238 {
00239 e->e[0] = hE[L]->e[1];
00240 hE[L]->e[1] = e;
00241 }
00242 }
00243 }
00244 else /* diagonal intersects an edge */
00245 {
00246 el = rec->e;
00247
00248 eh = new graph_edge(); // new edge for half of edge above diagonal
00249 E->Append(eh);
00250 rec->v->e = eh; // give new vertex an incident edge
00251 V->Append(rec->v); // append it to vertex list
00252
00253 if( el->v[0]->reserved[1].i > 0 ) // part with v0 above diagonal
00254 {
00255 ivh = 0;
00256 ivl = 1;
00257 }
00258 else // part with v1 above diagonal
00259 {
00260 ivh = 1;
00261 ivl = 0;
00262 }
00263 eh->v[ivl] = rec->v;
00264 eh->v[ivh] = el->v[ivh];
00265 eh->f[0] = el->f[0];
00266 eh->f[1] = el->f[1];
00267
00268 nhE = EdgeCycle( el, el->v[ivh], hE );
00269 if( nhE > 1 )
00270 {
00271 eh->e[ivh] = el->e[ivh];
00272 if( hE[nhE-1]->e[0] == el )
00273 hE[nhE-1]->e[0] = eh;
00274 else
00275 hE[nhE-1]->e[1] = eh;
00276 }
00277 else
00278 eh->e[ivh] = eh;
00279
00280 el->v[ivh]->e = eh; // eh replaces original edge in upper edge cycle
00281 el->v[ivh] = rec->v; // shorten intersecting edge to lower half
00282
00283 /* ---- create new edge for diagonal ---- */
00284 e = new graph_edge();
00285 E->Append(e);
00286 e->v[0] = lv;
00287 e->v[1] = rec->v;
00288 e->f[0] = e->f[1] = el->f[ivl];
00289
00290 nhE = IncidentEdges( lv, hE );
00291 match = EdgeInsertPosition( lv->v, *upperright, nhE, hE,
00292 &L, &R, &cL, &cR );
00293 if( hE[L]->v[0] == lv ) // connect lower end of new edge
00294 {
00295 e->e[0] = hE[L]->e[0];
00296 hE[L]->e[0] = e;
00297 }
00298 else
00299 {
00300 e->e[0] = hE[L]->e[1];
00301 hE[L]->e[1] = e;
00302 }
00303 eh->e[ivl] = e;
00304 e->e[1] = el;
00305 el->e[ivh] = eh;
00306 }
00307 lv = rec->v;
00308 rec = rec->next;
00309 }
00310 gul::Assert<InternalError>( ndebug || (lv == P22) );
00311
00312 Recs.DeleteElems();
00313 }
|
|
||||||||||||||||||||||||
|
Definition at line 112 of file gugr_planesweep.cpp.
00115 {
00116 const rational& x0 = L1.key()->l.v().x;
00117 const rational& y0 = L1.key()->l.v().y;
00118 const rational& dy = L1.key()->l.dy();
00119 const rational& e = L1.key()->E.x;
00120 const rational& X0 = L2.key()->l.v().x;
00121 const rational& Y0 = L2.key()->l.v().y;
00122 const rational& DY = L2.key()->l.dy();
00123 const rational& E = L2.key()->E.x;
00124 rational d;
00125 point2<rational> I;
00126 int sign,bsign,side1,side2;
00127 RefMap<intersection>::Node irnode1, irnode2, irnode;
00128 intersection *i;
00129 int side;
00130 Map<eventrec>::Node enode,enode1;
00131
00132 d = DY - dy;
00133 sign = d.test();
00134 if( sign == 0 ) return 0;
00135
00136 I.x = (y0 - Y0 + X0*DY - x0*dy) / d;
00137
00138 bsign = compare( I.x, xleft );
00139 if( bsign < 0 ) return 0;
00140 sign = compare( I.x, e );
00141 if( sign > 0 ) return 0;
00142 sign = compare( I.x, E );
00143 if( sign > 0 ) return 0;
00144
00145 I.y = y0 + (I.x-x0)*dy;
00146
00147 side1 = L1.key()->I.SearchNode(
00148 &I, hcompare_point_to_intersection, &irnode1 );
00149 side2 = L2.key()->I.SearchNode(
00150 &I, hcompare_point_to_intersection, &irnode2 );
00151 if( side1 == 0 )
00152 i = irnode1.key();
00153 else if( side2 == 0 )
00154 i = irnode2.key();
00155 else
00156 {
00157 i = new intersection( I );
00158 Ipts->Append(i);
00159 }
00160
00161 if( side1 != 0 )
00162 {
00163 irnode = L1.key()->I.NewNode(i);
00164 L1.key()->I.InsertNode( irnode, irnode1, side1 );
00165 }
00166 if( side2 != 0 )
00167 {
00168 irnode = L2.key()->I.NewNode(i);
00169 L2.key()->I.InsertNode( irnode, irnode2, side2 );
00170 }
00171
00172 if( bsign == 0 ) return i;
00173
00174 side = EvQ->SearchNode( &I, compare_point_to_eventrec, &enode );
00175 if( side != 0 )
00176 {
00177 enode1 = EvQ->NewNode( I );
00178 EvQ->InsertNode( enode1, enode, side );
00179 enode = enode1;
00180 }
00181 enode.key()->I.Append( new ListNode<linepair>( linepair(L1,L2) ) );
00182
00183 return i;
00184 }
|
|
||||||||||||||||
|
Definition at line 105 of file gugr_basics.cpp.
00106 {
00107 if( a.IsVertical() )
00108 {
00109 if( b.IsVertical() ) return false;
00110 return intersect_vert( a.v().x, b, I );
00111 }
00112 else if( a.IsHorizontal() )
00113 {
00114 if( b.IsHorizontal() ) return false;
00115 return intersect_horiz( a.v().y, b, I );
00116 }
00117
00118 if( b.IsVertical() )
00119 return intersect_vert( b.v().x, a, I );
00120 else if( b.IsHorizontal() )
00121 return intersect_horiz( b.v().y, a, I );
00122
00123 return intersect_nonvert( a, b, I );
00124 }
|
|
||||||||||||||||
|
Definition at line 89 of file gugr_basics.cpp.
00090 {
00091 const rational& X0 = b.v().x;
00092 const rational& Y0 = b.v().y;
00093 const rational& DX = b.dx();
00094
00095 if( b.IsHorizontal() ) return false;
00096 if( b.IsVertical() )
00097 I.x = X0;
00098 else
00099 I.x = X0 + (y0 - Y0)*DX;
00100 I.y = y0;
00101
00102 return true;
00103 }
|
|
||||||||||||||||
|
Definition at line 50 of file gugr_basics.cpp.
00051 {
00052 const rational& x0 = a.v().x;
00053 const rational& y0 = a.v().y;
00054 const rational& dy = a.dy();
00055 const rational& X0 = b.v().x;
00056 const rational& Y0 = b.v().y;
00057 const rational& DY = b.dy();
00058 rational d;
00059 int sign;
00060
00061 if( a.IsVertical() || b.IsVertical() ) return false;
00062
00063 d = DY - dy;
00064 sign = d.test();
00065 if( sign == 0 ) return false;
00066
00067 I.x = (y0 - Y0 + X0*DY - x0*dy) / d;
00068 I.y = y0 + (I.x-x0)*dy;
00069
00070 return true;
00071 }
|
|
||||||||||||||||
|
Definition at line 187 of file gugr_planesweep.cpp.
00189 {
00190 const rational& X0 = L.key()->l.v().x;
00191 const rational& Y0 = L.key()->l.v().y;
00192 const rational& DY = L.key()->l.dy();
00193 const rational& yleft = vL->B.y;
00194 const rational& yright = vL->E.y;
00195 const rational& x0 = vL->l.v().x;
00196
00197 point2<rational> I;
00198 int sign,side1,side2;
00199 RefMap<intersection>::Node irnode1, irnode2, irnode;
00200 intersection *i;
00201
00202 I.y = Y0 + (x0 - X0)*DY;
00203
00204 sign = compare( I.y, yleft );
00205 if( sign < 0 ) return 0;
00206 sign = compare( I.y, yright );
00207 if( sign > 0 ) return 0;
00208
00209 I.x = x0;
00210
00211 side1 = vL->I.SearchNode(
00212 &I, vcompare_point_to_intersection, &irnode1 );
00213 side2 = L.key()->I.SearchNode(
00214 &I, hcompare_point_to_intersection, &irnode2 );
00215 if( side1 == 0 )
00216 i = irnode1.key();
00217 else if( side2 == 0 )
00218 i = irnode2.key();
00219 else
00220 {
00221 i = new intersection( I );
00222 Ipts->Append(i);
00223 }
00224
00225 if( side1 != 0 )
00226 {
00227 irnode = vL->I.NewNode(i);
00228 vL->I.InsertNode( irnode, irnode1, side1 );
00229 }
00230 if( side2 != 0 )
00231 {
00232 irnode = L.key()->I.NewNode(i);
00233 L.key()->I.InsertNode( irnode, irnode2, side2 );
00234 }
00235
00236 return i;
00237 }
|
|
||||||||||||||||
|
Definition at line 73 of file gugr_basics.cpp.
00074 {
00075 const rational& X0 = b.v().x;
00076 const rational& Y0 = b.v().y;
00077 const rational& DY = b.dy();
00078
00079 if( b.IsVertical() ) return false;
00080 if( b.IsHorizontal() )
00081 I.y = Y0;
00082 else
00083 I.y = Y0 + (x0 - X0)*DY;
00084 I.x = x0;
00085
00086 return true;
00087 }
|
|
||||||||||||||||||||
|
Definition at line 87 of file gugr_bool.h.
00091 {
00092 T minx,miny,scale;
00093 rational far_x,far_y;
00094 gul::List<gul::ListNode<gugr::polyline> > PA,PB;
00095 gul::List<gul::ListNode<gul::polyline<gul::point2<rational> > > > PC;
00096
00097 ConvertToRationalPolys(fPA,fPB,&minx,&miny,&scale,&far_x,&far_y,PA,PB);
00098 DoIntersection(PA,PB,far_x,far_y,PC);
00099 ConvertToFloatPoly(PC,minx,miny,scale,fPC);
00100 }
|
|
||||||||||||||||||||||||
|
Definition at line 309 of file gugr_bool.cpp.
00311 {
00312 ListNode<gul::polyline<point2<rational> > > *pln;
00313 gul::ptr_int_union UA,UB;
00314 gul::RefMap<void>::Node cn;
00315 bool store;
00316
00317 UA.set_i(InA);
00318 UB.set_i(InB);
00319 store = false;
00320
00321 if( oset == (InA|InB) )
00322 {
00323 if( C->hasOwner(UA.p) )
00324 oset ^= InA;
00325
00326 if( C->hasOwner(UB.p) )
00327 oset ^= InB;
00328
00329 if( oset != (InA|InB) )
00330 store = true;
00331 }
00332 else
00333 {
00334 if( C->hasOwner(UA.p) )
00335 oset ^= InA;
00336
00337 if( C->hasOwner(UB.p) )
00338 oset ^= InB;
00339
00340 if( oset == (InA|InB) )
00341 store = true;
00342 }
00343
00344 if( store )
00345 {
00346 pln = new ListNode<gul::polyline<point2<rational> > >();
00347 C->get_polyline_joined( pln->el );
00348 pl.Append(pln);
00349 }
00350
00351 // travert children
00352 cn = C->childs.First();
00353 while( !cn.IsEmpty() )
00354 {
00355 IntersectionSubTree( (contour_node *)cn.key(), oset, InA, InB, pl );
00356 cn = C->childs.Successor( cn );
00357 }
00358 }
|
|
||||||||||||||||||||
|
Definition at line 780 of file gugr_planesweep.h.
00783 {
00784 gul::Map<eventrec> EvQ;
00785 int side;
00786 gul::Map<eventrec>::Node enode,enode1;
00787 segment *s;
00788 ListNode<segment> *sn;
00789
00790 /*--- initialize event queue with the lines leftmost endpoints ---*/
00791
00792 // gugr::DumpPS<float>::dump_segments( segs );
00793
00794 sn = segs.First();
00795
00796 while( sn )
00797 {
00798 s = &sn->el;
00799
00800 side = EvQ.SearchNode( &s->B, compare_point_to_eventrec, &enode );
00801 if( side != 0 )
00802 {
00803 enode1 = EvQ.NewNode( s->B );
00804 EvQ.InsertNode( enode1, enode, side );
00805 enode = enode1;
00806 }
00807 if( s->l.IsVertical() )
00808 enode.key()->BV.Append( new ListNode<segment *>(s) );
00809 else
00810 enode.key()->B.Append( new ListNode<segment *>(s) );
00811
00812 sn = sn->next;
00813 }
00814
00815 DoIntersectSegments( segs.nElems, EvQ, E, V );
00816
00817 if( !need_backpointers )
00818 {
00819 ISDeleteBackpointers( *E );
00820 }
00821 }
|
|
||||||||||||||||||||
|
Definition at line 441 of file gugr_planesweep.h.
00443 {
00444 gul::Map<eventrec> EvQ;
00445 int i,side;
00446 gul::Map<eventrec>::Node enode,enode1;
00447
00448 /*
00449 cout << "PLANESWEEP\n";
00450 cout << "==========\n";
00451 cout << "INPUT SEGMENTS\n";
00452 for( i = 0; i < nsegs; i++ )
00453 DumpPS<float>::dump_segment( &segs[i] );
00454 */
00455
00456 /*--- initialize event queue with the lines leftmost endpoints ---*/
00457
00458 for( i = 0; i < nsegs; i++ )
00459 {
00460 side = EvQ.SearchNode( &segs[i].B, compare_point_to_eventrec, &enode );
00461 if( side != 0 )
00462 {
00463 enode1 = EvQ.NewNode( segs[i].B );
00464 EvQ.InsertNode( enode1, enode, side );
00465 enode = enode1;
00466 }
00467 if( segs[i].l.IsVertical() )
00468 enode.key()->BV.Append( new ListNode<segment *>(&segs[i]) );
00469 else
00470 enode.key()->B.Append( new ListNode<segment *>(&segs[i]) );
00471 }
00472
00473 DoIntersectSegments( nsegs, EvQ, E, V );
00474 }
|
|
||||||||||||||||||||||||||||
|
Definition at line 95 of file gugr_split.cpp.
00099 {
00100 rational y;
00101 graph_edge *e;
00102 graph_vertex *v;
00103 int i,k,sign;
00104 cut_record *rec, **tmpR;
00105 point2<rational> AB,X;
00106
00107 AB.x = B.x - A.x;
00108 AB.y = B.y - A.y;
00109 L = line(A,B);
00110
00111 v = V.head;
00112 while( v != NULL )
00113 {
00114 sign = DetermineOrientationPV( A, AB, v->v.v() );
00115 v->reserved[1].set_i(sign);
00116 if( sign == 0 ) // new record, when on diagonal
00117 {
00118 rec = new cut_record();
00119 R.Append( rec );
00120 rec->v = v;
00121 rec->e = NULL;
00122 rec->val = v->v.v().y;
00123 }
00124 v = v->next;
00125 }
00126
00127 e = E.head;
00128 while( e != NULL )
00129 {
00130 i = e->v[0]->reserved[1].i;
00131 k = e->v[1]->reserved[1].i;
00132
00133 if( k*i < 0 ) // edge intersects diagonal
00134 {
00135 if( e->l.IsNULL() )
00136 e->CalcLine();
00137
00138 intersect( e->l, L, X );
00139
00140 rec = new cut_record();
00141 R.Append( rec );
00142 rec->v = new graph_vertex( X, NULL );
00143 rec->v->reserved[1].set_i(0); // on diagonal
00144 rec->e = e;
00145 rec->val = X.y;
00146 }
00147 e = e->next;
00148 }
00149 /* --- sort cut_records (on y) ---- */
00150 tmpR = (cut_record **)alloca( sizeof(cut_record *)*R.nElems );
00151 if( !tmpR ) throw AllocError();
00152
00153 rec = R.head;
00154 for( i = 0; i < R.nElems; i++ )
00155 {
00156 tmpR[i] = rec;
00157 rec = rec->next;
00158 }
00159 guma::PtrHeapSort( R.nElems,(void **)tmpR, compare_cut_records,NULL);
00160
00161 R.head = tmpR[0];
00162 tmpR[0]->prev = NULL;
00163 for( i = 1; i < R.nElems; i++ )
00164 {
00165 tmpR[i-1]->next = tmpR[i];
00166 tmpR[i]->prev = tmpR[i-1];
00167 }
00168 tmpR[R.nElems-1]->next = NULL;
00169 }
|
|
||||||||||||||||||||
|
Definition at line 381 of file gugr_split.cpp.
00384 {
00385 int ns = nS-1, i,j,k,nA;
00386 graph_vertex *v,*v_next;
00387 graph_edge *e, *e_next;
00388 rational y,x0,y0,x,dx;
00389 bool rz;
00390 cut_record *rec;
00391 Ptr< cut_info > A;
00392
00393 v = V->head;
00394
00395 nA = nS-1;
00396 A.use_pointer( &S[1], nS-1 ); // used for binary search
00397
00398 while( v != NULL )
00399 {
00400 v_next = v->next;
00401
00402 y = v->v.v().y;
00403
00404 i = FindCutInfo( y, nA, A, rz ) + 1;
00405
00406 v->reserved[0].set_i(i);
00407 v->reserved[1].set_i(rz);
00408
00409 V->Remove( v );
00410 S[i].V.Append( v );
00411
00412 if( rz )
00413 {
00414 rec = new cut_record();
00415 S[i].R.Append( rec );
00416
00417 rec->v = v;
00418 rec->e = NULL;
00419 rec->val = v->v.v().x;
00420 }
00421
00422 v = v_next;
00423 }
00424
00425 e = E->head;
00426
00427 while( e != NULL )
00428 {
00429 e_next = e->next;
00430
00431 i = e->v[0]->reserved[0].i;
00432 k = e->v[1]->reserved[0].i;
00433
00434 E->Remove( e );
00435 S[k].E.Append( e );
00436
00437 if( i != k )
00438 {
00439 if( e->l.IsNULL() )
00440 {
00441 e->CalcLine();
00442 }
00443
00444 x0 = e->l.v().x;
00445 y0 = e->l.v().y;
00446
00447 dx = e->l.dx();
00448
00449 if( e->v[1]->reserved[1].i ) k--;
00450
00451 for( j = i+1; j <= k; j++ )
00452 {
00453 if( !dx.is_zero() )
00454 x = x0 + (S[j].val-y0)*dx;
00455 else
00456 x = x0;
00457
00458 rec = new cut_record();
00459 S[j].R.Append( rec );
00460
00461 rec->v = NULL;
00462 rec->e = e;
00463 rec->val = x;
00464 }
00465 }
00466
00467 e = e_next;
00468 }
00469
00470 sort_cut_records( ns, S );
00471 }
|
|
||||||||||||||||||||
|
Definition at line 904 of file gugr_split.cpp.
00907 {
00908 int ns = nS-1, i,j,k,ii,ik,sign,nA;
00909 graph_vertex *v,*v_next;
00910 graph_edge *e, *e_next;
00911 rational y,x0,y0,x,dx,dy;
00912 bool rz;
00913 cut_record *rec;
00914 Ptr< cut_info > A;
00915
00916 v = V->head;
00917
00918 nA = nS-1;
00919 A.use_pointer( &S[1], nS-1 ); // used for binary search
00920
00921 while( v != NULL )
00922 {
00923 v_next = v->next;
00924
00925 x = v->v.v().x;
00926
00927 i = FindCutInfo( x, nA, A, rz ) + 1;
00928
00929 v->reserved[0].set_i(i);
00930 v->reserved[1].set_i(rz);
00931
00932 V->Remove( v );
00933 S[i].V.Append( v );
00934
00935 if( rz )
00936 {
00937 rec = new cut_record();
00938 S[i].R.Append( rec );
00939
00940 rec->v = v;
00941 rec->e = NULL;
00942 rec->val = v->v.v().y;
00943 }
00944
00945 v = v_next;
00946 }
00947
00948 e = E->head;
00949
00950 while( e != NULL )
00951 {
00952 e_next = e->next;
00953
00954 sign = compare(e->v[1]->v.v().x, e->v[0]->v.v().x);
00955 if( sign >= 0 ) {
00956 ii = 0;
00957 ik = 1;
00958 } else {
00959 ii = 1;
00960 ik = 0;
00961 }
00962
00963 i = e->v[ii]->reserved[0].i;
00964 k = e->v[ik]->reserved[0].i;
00965
00966 E->Remove( e );
00967 S[k].E.Append( e );
00968
00969 if( i != k )
00970 {
00971 if( e->l.IsNULL() )
00972 {
00973 e->CalcLine();
00974 }
00975
00976 x0 = e->l.v().x;
00977 y0 = e->l.v().y;
00978
00979 dy = e->l.dy();
00980
00981 if( e->v[ik]->reserved[1].i ) k--;
00982
00983 for( j = i+1; j <= k; j++ )
00984 {
00985 if( !dy.is_zero() )
00986 y = y0 + (S[j].val-x0)*dy;
00987 else
00988 y = y0;
00989
00990 rec = new cut_record();
00991 S[j].R.Append( rec );
00992
00993 rec->v = NULL;
00994 rec->e = e;
00995 rec->val = y;
00996 }
00997 }
00998
00999 e = e_next;
01000 }
01001
01002 sort_cut_records( ns, S );
01003 }
|
|
|
Definition at line 491 of file gugr_planesweep.h.
00492 {
00493 graph_edge *e;
00494 gul::List< gul::ListNode< gul::ListNodeInfo< gul::ListNode<graph_edge *>
00495 > > > *L;
00496
00497 e = E.First();
00498 while( e ) // delete backpointer lists
00499 {
00500 L = (gul::List< gul::ListNode< gul::ListNodeInfo<
00501 gul::ListNode<graph_edge *> > > > *)e->reserved[1].p;
00502 L->DeleteElems();
00503 delete L;
00504 e->reserved[1].p = 0;
00505
00506 e = e->next;
00507 }
00508 }
|
|
|
Definition at line 476 of file gugr_planesweep.h.
00477 {
00478 graph_edge *e = E.First();
00479
00480 while( e )
00481 {
00482 delete (gul::RefMap<void> *)e->f[0].p;
00483 e->f[0].p = 0;
00484 delete (gul::RefMap<void> *)e->f[1].p;
00485 e->f[1].p = 0;
00486
00487 e = e->next;
00488 }
00489 }
|
|
||||||||||||||||
|
Definition at line 193 of file gugr_contour.cpp.
00194 {
00195 graph_edge **TE;
00196 graph_vertex *v0,*v;
00197 List< ListNode<graph_vertex *> > vlist;
00198 List< ListNode<graph_edge *> > elist;
00199 ListNode<graph_vertex *> *vn,*vn_next;
00200 ListNode<graph_edge *> *en,*en_next;
00201 int curside,n,side,nVerts,i;
00202 RefMap<void> *owners,*eowners;
00203 RefMap<void>::Node eowner,parent,owner;
00204 Ptr<vertex> verts;
00205 Ptr<line> lines;
00206 segment *seg;
00207
00208 TE = (graph_edge **)alloca(sizeof(graph_edge *)*E.nElems);
00209
00210 v0 = e->v[0]; // first vertice of contour
00211 vn = new ListNode<graph_vertex *>(v0);
00212 vlist.Append(vn);
00213 en = new ListNode<graph_edge *>(e);
00214 elist.Append(en);
00215
00216 v = e->v[1]; // second vertice of contour
00217 vn = new ListNode<graph_vertex *>(v);
00218 vlist.Append(vn);
00219
00220 curside = 0; // begin with the left side of the edge/side pair
00221 owners = (RefMap<void> *)e->f[0].p; // initialize owner set
00222 e->f[0].p = 0; // mark this edge/side pair as processed
00223
00224 // set owner of corresponding segment to current contour
00225 seg = (segment *)e->reserved[2].p;
00226 if( e->l.IsHorizontal() || (e->l.dx().test() < 0) )
00227 seg->f[1].p = cn; // segment orientation different
00228 else
00229 seg->f[0].p = cn;
00230
00231 for(;;)
00232 {
00233 n = EdgeCycle( e, v, TE );
00234 e = TE[n-1];
00235
00236 // each edge has a backpointer to a segment for the second planesweep;
00237 // the face fields of these segments are initialized here (the planesweep
00238 // algo uses another edge orientation scheme then the rest of the graph
00239 // functions do !)
00240
00241 seg = (segment *)e->reserved[2].p;
00242
00243 if( e->v[0] == v )
00244 {
00245 curside = 0; // use owners on the left side of the edge
00246 v = e->v[1];
00247
00248 if( e->l.IsHorizontal() || (e->l.dx().test() < 0) )
00249 seg->f[1].p = cn; // segment orientation different
00250 else
00251 seg->f[0].p = cn;
00252 }
00253 else
00254 {
00255 curside = 1; // use owners on the right side of the edge
00256 v = e->v[0];
00257
00258 if( e->l.IsHorizontal() || (e->l.dx().test() < 0) )
00259 seg->f[0].p = cn; // segment orientation different
00260 else
00261 seg->f[1].p = cn;
00262 }
00263
00264 // add the owners of current edge/side pair to the contour owner set
00265
00266 eowners = (RefMap<void> *)e->f[curside].p;
00267 eowner = eowners->First();
00268 while( !eowner.IsEmpty() )
00269 {
00270 side = owners->SearchNode( eowner.key(), compare_pointer_to_pointer,
00271 &parent );
00272 if( side != 0 ) // new owner
00273 {
00274 owner = owners->NewNode( eowner.key() );
00275 owners->InsertNode( owner, parent, side );
00276 }
00277 eowner = eowners->Successor( eowner );
00278 }
00279 delete eowners; // edge/side owners not needed anymore
00280 e->f[curside].p = 0; // mark edge/side pair as processed
00281
00282 en = new ListNode<graph_edge *>(e);
00283 elist.Append(en);
00284
00285 if( v != v0 )
00286 {
00287 vn = new ListNode<graph_vertex *>(v);
00288 vlist.Append(vn);
00289 }
00290 else
00291 break;
00292 }
00293
00294 // convert vertex list to array and delete it
00295
00296 nVerts = vlist.nElems;
00297 verts.reserve_pool(nVerts);
00298 lines.reserve_pool(nVerts);
00299
00300 vn = vlist.First();
00301 vlist.ReleaseElems();
00302 en = elist.First();
00303 elist.ReleaseElems();
00304
00305 for( i = nVerts-1; i >= 0; i-- )
00306 {
00307 verts[i] = vn->el->v;
00308 vn_next = vn->next;
00309 delete vn;
00310 vn = vn_next;
00311
00312 lines[i] = en->el->l;
00313 en_next = en->next;
00314 delete en;
00315 en = en_next;
00316 }
00317 // convert owner set to array and delete it
00318
00319 cn->nOwners = owners->ConvertToArray( &cn->owners );
00320 delete owners;
00321
00322 cn->nVerts = nVerts;
00323 cn->verts = verts;
00324 cn->lines = lines;
00325 return;
00326 }
|
|
||||||||||||
|
|
|
||||||||||||||||||||||||||||||||||||
|
Definition at line 961 of file gugr_contour.cpp.
00967 {
00968 ListNode<polyline> *inc;
00969 List< ListNode<segment> > segs;
00970
00971 E.DeleteElems(); // clear output lists
00972 V.DeleteElems();
00973 outsegs.DeleteElems();
00974
00975 inc = inC.First();
00976 while( inc )
00977 {
00978 AppendContour( &inc->el, 1, 2, segs );
00979 inc = inc->next;
00980 }
00981
00982 /*
00983 cout << "PLANESWEEP\n";
00984 cout << "==========\n";
00985 cout << "INPUT SEGMENTS\n";
00986 for( hn = segs.First(); hn != 0; hn = hn->next )
00987 DumpPS<float>::dump_segment( &hn->el );
00988 */
00989
00990 IntersectSegments( segs, &E, &V, false ); // backpointers are not needed,
00991 // since 'segs' is not used
00992
00993 /*
00994 cout << "EDGES AFTER FIRST PLANESWEEP\n";
00995 cout << "============================\n";
00996 DumpPS<float>::dump_edges( E );
00997 cout << "\n";
00998 Dump<float>::dump_edges( E.head );
00999 cout << "\n";
01000 */
01001
01002 segs.DeleteElems(); // delete input segments (not needed)
01003
01004 RemoveUnnecessaryEdges( E, V, far_maxx, far_maxy, key_inside, key_outside,
01005 outsegs );
01006 }
|
|
||||||||||||
|
Definition at line 283 of file gugr_io.h.
|
|
||||||||||||
|
Definition at line 246 of file gugr_io.h.
00247 {
00248 g.dump_vertices(g.m_VL->First(),s);
00249 g.dump_edges(g.m_EL->First(),s);
00250
00251 return s << "\n";
00252 }
|
|
||||||||||||
|
Definition at line 190 of file gugr_basics.h.
00191 {
00192 return( a.m_rep == b.m_rep );
00193 }
|
|
|
Definition at line 404 of file gugr_basics.cpp.
00405 {
00406 graph_edge *tmpe;
00407 graph_vertex *tmpv;
00408 gul::ptr_int_union tmpf;
00409 int sign;
00410
00411 if( e != NULL )
00412 {
00413 sign = compare( e->v[0]->v.v().y, e->v[1]->v.v().y );
00414 if( !sign ) sign = -compare( e->v[0]->v.v().x, e->v[1]->v.v().x );
00415
00416 if( sign > 0 ) /* v1 > v2 */
00417 {
00418 tmpv = e->v[0];
00419 e->v[0] = e->v[1];
00420 e->v[1] = tmpv;
00421
00422 tmpe = e->e[0];
00423 e->e[0] = e->e[1];
00424 e->e[1] = tmpe;
00425
00426 tmpf = e->f[0];
00427 e->f[0] = e->f[1];
00428 e->f[1] = tmpf;
00429 }
00430 }
00431 }
|
|
|
Definition at line 437 of file gugr_basics.cpp.
00438 {
00439 graph_edge *e, *tmpe;
00440 graph_vertex *tmpv;
00441 gul::ptr_int_union tmpf;
00442 int sign;
00443
00444 e = E;
00445 while( e != NULL )
00446 {
00447 sign = compare( e->v[0]->v.v().y, e->v[1]->v.v().y );
00448 if( !sign ) sign = -compare( e->v[0]->v.v().x, e->v[1]->v.v().x );
00449
00450 if( sign > 0 ) /* v1 > v2 */
00451 {
00452 tmpv = e->v[0];
00453 e->v[0] = e->v[1];
00454 e->v[1] = tmpv;
00455
00456 tmpe = e->e[0];
00457 e->e[0] = e->e[1];
00458 e->e[1] = tmpe;
00459
00460 tmpf = e->f[0];
00461 e->f[0] = e->f[1];
00462 e->f[1] = tmpf;
00463 }
00464
00465 e = e->next;
00466 }
00467 }
|
|
||||||||||||
|
Definition at line 260 of file gugr_basics.h.
00261 {
00262 if( a.IsHorizontal() )
00263 return b.IsHorizontal();
00264 else if( a.IsVertical() )
00265 return b.IsVertical();
00266
00267 if( b.IsHorizontal() || b.IsVertical() )
00268 return false;
00269
00270 return compare( a.dy(), b.dy() ) == 0;
00271 }
|
|
||||||||||||||||
|
|
|
||||||||||||||||
|
|
|
||||||||||||||||||||
|
Definition at line 398 of file gugr_face.cpp.
00402 {
00403 ListNode< gul::polyline< point<T> > > *c3;
00404 ListNode< gul::polyline< point2<T> > > *c2;
00405 int i;
00406 Ptr<T> v3,v2;
00407
00408 v3.reserve_pool(4);
00409 v2.reserve_pool(4);
00410
00411 c3 = C3.First();
00412 while( c3 )
00413 {
00414 c2 = new ListNode< gul::polyline< point2<T> > >;
00415 C2.Append( c2 );
00416
00417 c2->el.n = c3->el.n;
00418 c2->el.P.reserve_pool( c3->el.n );
00419
00420 for( i = 0; i < c3->el.n; i++ )
00421 {
00422 v3[0] = c3->el.P[i].x;
00423 v3[1] = c3->el.P[i].y;
00424 v3[2] = c3->el.P[i].z;
00425 v3[3] = (T)1;
00426
00427 VMProduct(4,4,v3,Ti,v2);
00428
00429 c2->el.P[i].x = v2[0];
00430 c2->el.P[i].y = v2[1];
00431 }
00432
00433 c3 = c3->next;
00434 }
00435 }
|
|
||||||||||||||||||||||||||||||||||||||||||||
|
|
|
||||||||||||||||||||||||||||||||||||||||||||
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
|
Definition at line 196 of file gugr_basics.cpp.
00202 {
00203 graph_vertex *v, *vend, vdummy;
00204 graph_edge *e = 0, *eend, edummy;
00205 int i;
00206 T x,y;
00207 graph_vertex_list hv;
00208 graph_edge_list he;
00209 unsigned long *cbuf = (unsigned long *)alloca(gul::rtr<T>::mantissa_length());
00210
00211 he.head = eend = &edummy;
00212 hv.head = vend = &vdummy;
00213
00214 for( i=0; i<n; i++ )
00215 {
00216 x = (P[i].x - orgx)/scalex;
00217 y = (P[i].y - orgy)/scaley;
00218
00219 e = new graph_edge();
00220 he.Append(e);
00221
00222 v = new graph_vertex( point2<rational>(
00223 rational(coord2int(x,cbuf),cbuf),
00224 rational(coord2int(y,cbuf),cbuf) ), e );
00225 hv.Append(v);
00226
00227 e->f[0].set_i(fleft);
00228 e->f[1].set_i(fright);
00229
00230 e->v[0] = v;
00231 e->e[0] = e->next;
00232
00233 e->next->v[1] = v;
00234 e->next->e[1] = e;
00235 }
00236 e->v[1] = vend->prev;
00237 e->e[1] = eend->prev;
00238 eend->prev->e[0] = e;
00239
00240 vend->prev->next = V->head;
00241 eend->prev->next = E->head;
00242 if( V->head != NULL ) V->head->prev = vend->prev;
00243 if( E->head != NULL ) E->head->prev = eend->prev;
00244
00245 E->head = he.head; E->nElems += n;
00246 V->head = hv.head; V->nElems += n;
00247 he.ReleaseElems();
00248 hv.ReleaseElems();
00249 }
|
|
||||||||||||||||||||||||||||||||||||||||||||
|
|
|
||||||||||||||||||||||||||||||||||||||||||||
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
|
Definition at line 267 of file gugr_basics.cpp.
00273 {
00274 graph_vertex *v, *vend, vdummy;
00275 graph_edge *e = 0, *eend, edummy;
00276 int i;
00277 T x,y;
00278 graph_vertex_list hv;
00279 graph_edge_list he;
00280 unsigned long *cbuf = (unsigned long *)alloca(gul::rtr<T>::mantissa_length());
00281
00282 he.head = eend = &edummy;
00283 hv.head = vend = &vdummy;
00284
00285 for( i=0; i<n; i++ )
00286 {
00287 x = (P[i].x - orgx)/scalex;
00288 y = (P[i].y - orgy)/scaley;
00289
00290 e = new graph_edge();
00291 he.Append(e);
00292
00293 v = new graph_vertex( point2<rational>(
00294 rational(coord2int(x,cbuf),cbuf),
00295 rational(coord2int(y,cbuf),cbuf) ), e );
00296 hv.Append(v);
00297 v->v.m_rep->reserved.i = i; // enumber vertices
00298
00299 e->f[0].set_i(fleft);
00300 e->f[1].set_i(fright);
00301
00302 e->v[0] = v;
00303 e->e[0] = e->next;
00304
00305 e->next->v[1] = v;
00306 e->next->e[1] = e;
00307 }
00308 e->v[1] = vend->prev;
00309 e->e[1] = eend->prev;
00310 eend->prev->e[0] = e;
00311
00312 vend->prev->next = V->head;
00313 eend->prev->next = E->head;
00314 if( V->head != NULL ) V->head->prev = vend->prev;
00315 if( E->head != NULL ) E->head->prev = eend->prev;
00316
00317 E->head = he.head; E->nElems += n;
00318 V->head = hv.head; V->nElems += n;
00319 he.ReleaseElems();
00320 hv.ReleaseElems();
00321 }
|
|
||||||||||||
|
|
|
||||||||||||
|
Definition at line 290 of file gugr_regularize.cpp.
00291 {
00292 edge_interval_tree Status;
00293 BBTNode *node,*node1,*node2;
00294 edge_interval *I;
00295 graph_edge **TE, *edge,*a,*r;
00296 graph_vertex *v0,*vmax,*vmin,*v;
00297 int nTE,sign,regular,j,side;
00298
00299 TE = (graph_edge **)alloca( sizeof(graph_edge *)*(3*E->nElems) );
00300 if( !TE ) throw AllocError();
00301
00302 vmax = SortVertices( V );
00303 vmin = V->head;
00304
00305 /*--- tree of intervalls bounded by two edges for status info -------------*/
00306
00307 node = Status.NewNode();
00308
00309 I = (edge_interval *)node->key;
00310 I->l = EDGE_NEG_INF;
00311 I->r = EDGE_POS_INF;
00312 I->v = NULL;
00313
00314 Status.InsertNode( node, &Status.root, 1 );
00315 // Status.Dump(); Status.DumpNodes();
00316
00317 /****************** Top-Down Sweep **********************************/
00318
00319 v0 = vmax;
00320 while( v0 != NULL )
00321 {
00322 nTE = IncidentEdges( v0, TE );
00323
00324 regular = 0;
00325 for( j = 0; j < nTE; j++ )
00326 {
00327 a = TE[j];
00328 if( a->v[0] == v0 ) /* edge starts in v0 (then v0 cannot be maximum */
00329 { /* of graph) */
00330 regular = 1;
00331
00332 sign = compare( a->v[1]->v.v().y, v0->v.v().y );
00333 if( sign == 0 ) continue; /* nothing to do for horizontal edges */
00334
00335 /* replace the two intervalls [l,a],[a,r] with [l,r] */
00336 node1 = (BBTNode *)a->reserved[0].p;
00337 node2 = (BBTNode *)a->reserved[1].p;
00338
00339 edge = ((edge_interval *)(node2->key))->r;
00340 edge->reserved[0].p = (void *)node1;
00341
00342 ((edge_interval *)(node1->key))->r = edge;
00343 ((edge_interval *)(node1->key))->v = v0;
00344
00345 Status.RemoveNode( node2 );
00346 Status.FreeNode( node2 );
00347 // Status.Dump(); Status.DumpNodes();
00348
00349 }
00350 }
00351
00352 if( (!regular) && (v0 != vmax) )
00353 {
00354 side = Status.SearchNode( (void *)(v0->e), compare_edge_to_intervalTD,
00355 &node );
00356 if( side != 0 ) throw InternalError();
00357
00358 v = ((edge_interval *)node->key)->v;
00359
00360 edge = new graph_edge();
00361 E->Append(edge);
00362
00363 edge->v[1] = v;
00364 edge->v[0] = v0;
00365
00366 EdgeInsert( edge, E->nElems );
00367 }
00368
00369 for( j = 0; j < nTE; j++ )
00370 {
00371 a = TE[j];
00372 if( a->v[1] == v0 ) /* edge ends in v0 */
00373 {
00374 side = Status.SearchNode( (void *)a, compare_edge_to_intervalTD,
00375 &node1 );
00376 if( side != 0 ) throw InternalError();
00377
00378 sign = compare( a->v[0]->v.v().y, v0->v.v().y );
00379 if( sign == 0 ) /*special case: horizontal edge */
00380 {
00381 ((edge_interval *)(node1->key))->v = a->v[0];
00382 }
00383 else
00384 {
00385 r = ((edge_interval *)node1->key)->r;
00386 ((edge_interval *)node1->key)->r = a;
00387 ((edge_interval *)node1->key)->v = v0;
00388 a->reserved[0].p = (void *)node1;
00389
00390 node2 = Status.NewNode();
00391
00392 ((edge_interval *)node2->key)->l = a;
00393 ((edge_interval *)node2->key)->r = r;
00394 ((edge_interval *)node2->key)->v = v0;
00395 a->reserved[1].p = (void *)node2;
00396 r->reserved[0].p = (void *)node2;
00397
00398 side = Status.SearchNode( (void *)a, compare_edge_to_intervalTD,
00399 &node );
00400 if( side == 0 ) throw InternalError();
00401
00402 Status.InsertNode( node2, node, side );
00403 // Status.Dump(); Status.DumpNodes();
00404
00405 }
00406 }
00407 }
00408
00409 v0 = v0->prev;
00410 }
00411
00412
00413 /********* Bottom Up Sweep ****************************************/
00414
00415 node = Status.Head();
00416
00417 I = (edge_interval *)node->key;
00418 I->v = NULL;
00419
00420 gul::Assert<InternalError>( ndebug ||
00421 ((node->left == NULL) || (node->right == NULL) ||
00422 (I->l == EDGE_NEG_INF) || (I->r == EDGE_POS_INF)) );
00423 v0 = vmin;
00424 while( v0 != NULL )
00425 {
00426 nTE = IncidentEdges( v0, TE );
00427
00428 regular = 0;
00429 for( j = 0; j < nTE; j++ )
00430 {
00431 a = TE[j];
00432 if( a->v[1] == v0 ) /* edge ends in v0 (then v0 cannot be minimum */
00433 { /* of graph) */
00434 regular = 1;
00435
00436 sign = compare( a->v[0]->v.v().y, v0->v.v().y );
00437 if( sign == 0 ) continue; /* nothing to do for horizontal edges */
00438
00439 /* replace the two intervalls [l,a],[a,r] with [l,r] */
00440 node1 = (BBTNode *)a->reserved[0].p;
00441 node2 = (BBTNode *)a->reserved[1].p;
00442
00443 edge = ((edge_interval *)(node2->key))->r;
00444 edge->reserved[0].p = (void *)node1;
00445
00446 ((edge_interval *)(node1->key))->r = edge;
00447 ((edge_interval *)(node1->key))->v = v0;
00448
00449 Status.RemoveNode( node2 );
00450 Status.FreeNode( node2 );
00451 }
00452 }
00453
00454 if( (!regular) && (v0 != vmin) )
00455 {
00456 side = Status.SearchNode( (void *)(v0->e), compare_edge_to_intervalBU,
00457 &node );
00458 if( side != 0 ) throw InternalError();
00459
00460 v = ((edge_interval *)node->key)->v;
00461
00462 edge = new graph_edge();
00463 E->Append(edge);
00464
00465 edge->v[1] = v0;
00466 edge->v[0] = v;
00467
00468 EdgeInsert( edge, E->nElems );
00469 }
00470
00471 for( j = 0; j < nTE; j++ )
00472 {
00473 a = TE[j];
00474 if( a->v[0] == v0 ) /* edge starts in v0 */
00475 {
00476 side = Status.SearchNode( (void *)a, compare_edge_to_intervalBU,
00477 &node1 );
00478 if( side != 0 ) throw InternalError();
00479
00480 sign = compare( a->v[1]->v.v().y, v0->v.v().y );
00481 if( sign == 0 ) /*special case: horizontal edge */
00482 {
00483 ((edge_interval *)(node1->key))->v = a->v[1];
00484 }
00485 else
00486 {
00487 r = ((edge_interval *)node1->key)->r;
00488 ((edge_interval *)node1->key)->r = a;
00489 ((edge_interval *)node1->key)->v = v0;
00490 a->reserved[0].p = (void *)node1;
00491
00492 node2 = Status.NewNode();
00493
00494 ((edge_interval *)node2->key)->l = a;
00495 ((edge_interval *)node2->key)->r = r;
00496 ((edge_interval *)node2->key)->v = v0;
00497 a->reserved[1].p = (void *)node2;
00498 r->reserved[0].p = (void *)node2;
00499
00500 side = Status.SearchNode( (void *)a, compare_edge_to_intervalBU,
00501 &node );
00502 if( side == 0 ) throw InternalError();
00503
00504 Status.InsertNode( node2, node, side );
00505 }
00506 }
00507 }
00508
00509 v0 = v0->next;
00510 }
00511
00512 node = Status.Head();
00513
00514 I = (edge_interval *)node->key;
00515 gul::Assert<InternalError>( ndebug ||
00516 ((node->left == NULL) || (node->right == NULL) ||
00517 (I->l == EDGE_NEG_INF) || (I->r == EDGE_POS_INF)) );
00518
00519 Status.RemoveNode( node );
00520 Status.FreeNode( node );
00521 }
|
|
||||||||||||||||||||||||||||||||
|
Definition at line 688 of file gugr_contour.cpp.
00693 {
00694 gugr::graph_edge_list E2;
00695 gugr::graph_vertex_list V2;
00696 graph_edge *e,*e_next;
00697 ListNode<segment> *sn;
00698 List<contour_node> contours;
00699 contour_node *cn,*C0,*C1;
00700 segment *seg;
00701 int m,i,n,nEdges,side;
00702 bool end;
00703 Ptr<void *> edges;
00704 graph_edge **TE;
00705 ListNode<graph_edge *> *en;
00706 RefMap<void> *M;
00707 RefMap<void>::Node parent;
00708 int left,right,isolated;
00709 List< ListNode< ListNodeInfo< ListNode<graph_edge *> > > > *L;
00710 ListNode< ListNodeInfo< ListNode<graph_edge *> > > *bptr, *bptr_next;
00711
00712
00713 FindContours( E, V, far_maxx, far_maxy, outsegs, contours );
00714
00715 /* ------ second planesweep ------------------------------- */
00716
00717 /*
00718 cout << "PLANESWEEP\n";
00719 cout << "==========\n";
00720 cout << "INPUT SEGMENTS\n";
00721 for( hn = segs.First(); hn != 0; hn = hn->next )
00722 DumpPS<float>::dump_segment( &hn->el );
00723 */
00724
00725 IntersectSegments( outsegs, &E2, &V2, false );
00726
00727 /*
00728 cout << "EDGES AFTER SECOND PLANESWEEP\n";
00729 cout << "============================\n";
00730 DumpPS<float>::dump_edges( E2 );
00731 cout << "\n";
00732 Dump<float>::dump_edges( E2.head );
00733 cout << "\n";
00734 cout.flush();
00735 */
00736
00737 // travert the help lines to classify the regions as loops or holes
00738
00739 TE = (graph_edge **)alloca(sizeof(graph_edge *)*E2.nElems);
00740 edges.reserve_pool(E2.nElems);
00741
00742 for( cn = contours.First(); cn != 0; cn = cn->next ) // travert contours
00743 {
00744 m = 0;
00745
00746 en = cn->hseg->e.First();
00747 if( en )
00748 {
00749 e = en->el;
00750
00751 if( e->l.IsHorizontal() || (e->l.dx().test() < 0) )
00752 end = 1;
00753 else
00754 end = 0;
00755 }
00756
00757 while( en )
00758 {
00759 en = en->next;
00760 if( !en ) break; // special treatment for the last edge
00761
00762 n = EdgeCycle( e, e->v[end], TE );
00763
00764 for( i = 1; TE[i] != en->el; i++ ) // edges above help line (or left of
00765 { // vertical help line)
00766 m += (int)TE[i]->reserved[0].i; // count the number of intersections
00767 }
00768
00769 e = en->el; // next edge
00770 }
00771
00772 // last edge, its endpoint lies on the segment of the contour which
00773 // shall be classified
00774
00775 nEdges = cn->seg->e.nElems;
00776 for( en = cn->seg->e.First(), i=0; en != 0; en = en->next, i++ )
00777 edges[i] = en->el;
00778 heapsort( nEdges, edges );
00779
00780 n = EdgeCycle( e, e->v[end], TE );
00781
00782 for( i = 1; ; i++ ) // edges above help line until edge on segment reached
00783 {
00784 if( BinarySearch( (void *)TE[i], nEdges, edges ) >= 0 )
00785 break;
00786
00787 m += (int)TE[i]->reserved[0].i; // count the number of intersections
00788 }
00789
00790 // if the contour lies on the opposite site of the segment edge add its
00791 // multiplicity too
00792
00793 if( TE[i]->v[0] == e->v[end] )
00794 M = (RefMap<void> *)TE[i]->f[0].p;
00795 else
00796 M = (RefMap<void> *)TE[i]->f[1].p;
00797
00798 side = M->SearchNode( (void *)cn, compare_pointer_to_pointer, &parent );
00799 if( side == 0 )
00800 {
00801 m += (int)TE[i]->reserved[0].i; // count the number of intersections
00802 }
00803
00804 cn->hole = ((m & 1) == 0);
00805 }
00806
00807 // cleanup
00808 ISDeleteOwnerMaps(E2);
00809 E2.DeleteElems();
00810 V2.DeleteElems();
00811
00812 /*
00813 cn = contours.First();
00814 i = 0;
00815 while( cn )
00816 {
00817 i++;
00818 cout << "CONTOUR #" << i << " (" << (void *)cn << ")\n";
00819 cout << "hole = " << cn->hole << "\n";
00820 cout << dump_vector<int>(cn->nOwners, cn->owners);
00821 for( i = 0; i < cn->nVerts; i++ )
00822 Dump<float>::dump_vert( cn->verts[i] );
00823 cn = cn->next;
00824 }
00825 */
00826
00827 // remove unnecessary edges which have holes or loops on both sides
00828
00829 e = E.First();
00830 while( e )
00831 {
00832 seg = (segment *)e->reserved[2].p;
00833 C0 = (contour_node *)seg->f[0].p;
00834 C1 = (contour_node *)seg->f[1].p;
00835
00836 if( C0->hole == C1->hole )
00837 {
00838 /*
00839 cout << "removing edge " << (void *)e << "\n";
00840 */
00841
00842 // some dangerous pointer arithmetic to get the segment node address
00843 gul::Assert<InternalError>( ndebug ||
00844 (outsegs.First() == (ListNode<segment> *)&outsegs.First()->el) );
00845
00846 /*
00847 cout << (void *)esegs.First() << " == " <<
00848 (void *)&esegs.First()->el << "\n";
00849 */
00850
00851 sn = (ListNode<segment> *)seg;
00852 outsegs.Remove( sn );
00853 delete sn;
00854
00855 isolated = DisconnectEdge(e,E.nElems);
00856 if( (isolated & 1) )
00857 {
00858 V.Remove(e->v[0]);
00859 delete e->v[0];
00860 }
00861 if( (isolated & 2) )
00862 {
00863 V.Remove(e->v[1]);
00864 delete e->v[1];
00865 }
00866
00867 // remove edge from the edge lists of backpointed segments
00868 if( e->reserved[1].p )
00869 {
00870 L = (List< ListNode< ListNodeInfo< ListNode<graph_edge *> > > > *)
00871 e->reserved[1].p;
00872 bptr = L->First();
00873 L->ReleaseElems(); // will be deleted manually in the following
00874 delete L;
00875
00876 while( bptr )
00877 {
00878 bptr->el.m_L->Remove( bptr->el.m_n );
00879 bptr_next = bptr->next;
00880 delete bptr;
00881 bptr = bptr_next;
00882 }
00883 }
00884
00885 e_next = e->next;
00886 E.Remove(e);
00887 delete e;
00888 e = e_next;
00889 }
00890 else
00891 {
00892 // set the edge side flags. after this the graph is ready for
00893 // triangulation
00894
00895 if( C0->hole )
00896 {
00897 left = key_outside;
00898 right = key_inside;
00899 }
00900 else
00901 {
00902 left = key_inside;
00903 right = key_outside;
00904 }
00905
00906 if( e->l.IsHorizontal() || (e->l.dx().test() < 0) )
00907 {
00908 e->f[0].set_i(right); // segment orientation different
00909 e->f[1].set_i(left);
00910 }
00911 else
00912 {
00913 e->f[0].set_i(left);
00914 e->f[1].set_i(right);
00915 }
00916
00917 // set the side flags of the segments; after this the segment list can be
00918 // used as the input for building the new contours (without the
00919 // unnecessary edges) and their containment tree for elimination of
00920 // unnecessary contours (like holes within holes)
00921
00922 seg->f[0].set_i(left);
00923 seg->f[1].set_i(right);
00924 seg->e.DeleteElems(); // these are meaningless since they point into E2
00925
00926 e = e->next;
00927 }
00928 }
00929
00930 // cleanup
00931
00932 for( cn = contours.First(); cn != 0; cn = cn->next ) // remove help lines
00933 {
00934 if( cn->hseg_firstref )
00935 {
00936 sn = (ListNode<segment> *)cn->hseg;
00937 outsegs.Remove( sn );
00938 delete sn;
00939 }
00940 }
00941
00942 /*
00943 cout << "EDGES AFTER REMOVAL\n";
00944 cout << "===================\n";
00945 Dump<float>::dump_edges( E.head );
00946 cout << "\n";
00947
00948 cout << "SEGMENTS AFTER REMOVAL\n";
00949 cout << "===================\n";
00950 for( hn = esegs.First(); hn != 0; hn = hn->next )
00951 DumpPS<float>::dump_segment( &hn->el );
00952 */
00953
00954 contours.DeleteElems();
00955 }
|
|
||||||||||||||||
|
Definition at line 328 of file gugr_contour.cpp.
00329 {
00330 graph_edge **TE;
00331 graph_vertex *v0,*v;
00332 List< ListNode<graph_vertex *> > vlist;
00333 List< ListNode<graph_edge *> > elist;
00334 ListNode<graph_vertex *> *vn,*vn_next;
00335 ListNode<graph_edge *> *en,*en_next;
00336 int curside,n,side,nVerts,i;
00337 RefMap<void> *owners,*eowners;
00338 RefMap<void>::Node eowner,parent,owner;
00339 Ptr<vertex> verts;
00340 Ptr<line> lines;
00341 segment *seg;
00342
00343 TE = (graph_edge **)alloca(sizeof(graph_edge *)*E.nElems);
00344
00345 v0 = e->v[0]; // first vertice of contour
00346 vn = new ListNode<graph_vertex *>(v0);
00347 vlist.Append(vn);
00348 en = new ListNode<graph_edge *>(e);
00349 elist.Append(en);
00350
00351 v = e->v[1]; // second vertice of contour
00352 vn = new ListNode<graph_vertex *>(v);
00353 vlist.Append(vn);
00354
00355 curside = 1; // begin with the right side of the edge/side pair
00356 owners = (RefMap<void> *)e->f[1].p; // initialize owner set
00357 e->f[1].p = 0; // mark this edge/side pair as processed
00358
00359 // set owner of corresponding segment to current contour
00360 seg = (segment *)e->reserved[2].p;
00361 if( e->l.IsHorizontal() || (e->l.dx().test() < 0) )
00362 seg->f[0].p = cn; // segment orientation different
00363 else
00364 seg->f[1].p = cn;
00365
00366 for(;;)
00367 {
00368 n = EdgeCycle( e, v, TE );
00369 e = TE[1];
00370
00371 // each edge has a backpointer to a segment for the second planesweep;
00372 // the face fields of these segments are initialized here (the planesweep
00373 // algo uses another edge orientation scheme then the rest of the graph
00374 // functions too !)
00375
00376 seg = (segment *)e->reserved[2].p;
00377
00378 if( e->v[0] == v )
00379 {
00380 curside = 1; // use owners on the right side of the edge
00381 v = e->v[1];
00382
00383 if( e->l.IsHorizontal() || (e->l.dx().test() < 0) )
00384 seg->f[0].p = cn; // segment orientation different
00385 else
00386 seg->f[1].p = cn;
00387 }
00388 else
00389 {
00390 curside = 0; // use owners on the left side of the edge
00391 v = e->v[0];
00392
00393 if( e->l.IsHorizontal() || (e->l.dx().test() < 0) )
00394 seg->f[1].p = cn; // segment orientation different
00395 else
00396 seg->f[0].p = cn;
00397 }
00398 // add the owners of current edge/side pair to the contour owner set
00399
00400 eowners = (RefMap<void> *)e->f[curside].p;
00401 eowner = eowners->First();
00402 while( !eowner.IsEmpty() )
00403 {
00404 side = owners->SearchNode( eowner.key(), compare_pointer_to_pointer,
00405 &parent );
00406 if( side != 0 ) // new owner
00407 {
00408 owner = owners->NewNode( eowner.key() );
00409 owners->InsertNode( owner, parent, side );
00410 }
00411 eowner = eowners->Successor( eowner );
00412 }
00413 delete eowners; // edge/side owners not needed anymore
00414 e->f[curside].p = 0; // mark edge/side pair as processed
00415
00416 en = new ListNode<graph_edge *>(e);
00417 elist.Append(en);
00418
00419 if( v != v0 )
00420 {
00421 vn = new ListNode<graph_vertex *>(v);
00422 vlist.Append(vn);
00423 }
00424 else
00425 break;
00426 }
00427
00428 // convert vertex list to array and delete it
00429
00430 nVerts = vlist.nElems;
00431 verts.reserve_pool(nVerts);
00432 lines.reserve_pool(nVerts);
00433
00434 vn = vlist.First();
00435 vlist.ReleaseElems();
00436 en = elist.First();
00437 elist.ReleaseElems();
00438
00439 for( i = nVerts-1; i >= 0; i-- )
00440 {
00441 verts[i] = vn->el->v;
00442 vn_next = vn->next;
00443 delete vn;
00444 vn = vn_next;
00445
00446 lines[i] = en->el->l;
00447 en_next = en->next;
00448 delete en;
00449 en = en_next;
00450 }
00451
00452 // convert owner set to array and delete it
00453
00454 cn->nOwners = owners->ConvertToArray( &cn->owners );
00455 delete owners;
00456
00457 cn->nVerts = nVerts;
00458 cn->verts = verts;
00459 cn->lines = lines;
00460 return;
00461 }
|
|
||||||||||||
|
Definition at line 54 of file gugr_split.cpp.
00055 {
00056 cut_record *rec, **tmpR;
00057 int i,j,max_nR;
00058
00059 max_nR = 0;
00060 for( i = 1; i <= ns; i++ )
00061 if( S[i].R.nElems > max_nR ) max_nR = S[i].R.nElems;
00062
00063 if( max_nR > 0 )
00064 {
00065 tmpR = (cut_record **)alloca( sizeof(cut_record *)*max_nR );
00066 if( !tmpR ) throw AllocError();
00067 }
00068 else tmpR = 0; // make compiler happy :)
00069
00070 for( i = 1; i <= ns; i++ )
00071 {
00072 if( S[i].R.nElems > 1 )
00073 {
00074 rec = S[i].R.head;
00075 for( j = 0; j < S[i].R.nElems; j++ )
00076 {
00077 tmpR[j] = rec;
00078 rec = rec->next;
00079 }
00080 guma::PtrHeapSort( S[i].R.nElems,(void **)tmpR, compare_cut_records,NULL);
00081
00082 S[i].R.head = tmpR[0];
00083 tmpR[0]->prev = NULL;
00084 for( j = 1; j < S[i].R.nElems; j++ )
00085 {
00086 tmpR[j-1]->next = tmpR[j];
00087 tmpR[j]->prev = tmpR[j-1];
00088 }
00089 tmpR[S[i].R.nElems-1]->next = NULL;
00090 }
00091 }
00092 }
|
|
|
Definition at line 58 of file gugr_regularize.cpp.
00059 {
00060 graph_vertex **tmpV,*v;
00061 int i,j;
00062
00063 tmpV = (graph_vertex **)alloca( sizeof(graph_vertex *)*V->nElems );
00064 if( !tmpV ) throw AllocError();
00065
00066 v = V->head;
00067 for( i = 0; i < V->nElems; i++ )
00068 {
00069 tmpV[i] = v;
00070 v = v->next;
00071 }
00072
00073 PtrHeapSort( V->nElems, (void **)tmpV, compare_vertices, NULL );
00074
00075 V->head = tmpV[0];
00076 tmpV[0]->prev = NULL;
00077 for( j = 1; j < V->nElems; j++ )
00078 {
00079 tmpV[j-1]->next = tmpV[j];
00080 tmpV[j]->prev = tmpV[j-1];
00081 }
00082 tmpV[V->nElems-1]->next = NULL;
00083
00084 return(tmpV[V->nElems-1]); /* return last vertex in list */
00085 }
|
|
||||||||||||||||||||||||
|
|
|
||||||||||||||||||||||||
|
|
|
||||||||||||||||||||||||||||
|
Definition at line 1537 of file gugr_split.cpp.
01539 {
01540 graph_vertex *Vy1Sl, *Vy1Sr, *Vy2Sl, *Vy2Sr, *Vx1Sa, *Vx1Sb, *Vx2Sa, *Vx2Sb;
01541 graph_vertex *hvLeftT, *hvRightT;
01542 graph_edge *e, *el, **hE;
01543 graph_vertex *v, *v0;
01544 int nhE, nMaxE, i, j;
01545 rational X1,X2,X3;
01546 rational Y1,Y2,Y3;
01547 unsigned long *cbuf = (unsigned long *)alloca(gul::rtr<double>::mantissa_length());
01548 T y2,x2;
01549 Ptr< gugr::cut_info > CutsX, CutsY;
01550
01551 /*
01552 cout << "SPLITGRAPH: input graph\n";
01553 cout << "**********************\n";
01554 gugr::Dump<T>::dump_vertices( G->V.head );
01555 gugr::Dump<T>::dump_edges( G->E.head );
01556 */
01557
01558 rational& MinX = Gconv->MinX; // short aliases
01559 rational& MaxX = Gconv->MaxX;
01560 rational& FarMinX = Gconv->FarMinX;
01561 rational& FarMaxX = Gconv->FarMaxX;
01562 rational& MinY = Gconv->MinY;
01563 rational& MaxY = Gconv->MaxY;
01564 rational& FarMinY = Gconv->FarMinY;
01565 rational& FarMaxY = Gconv->FarMaxY;
01566
01567 CutsX.reserve_place( reserve_stack(cut_info,4), 4 );
01568 CutsY.reserve_place( reserve_stack(cut_info,4), 4 );
01569
01570 x2 = (xmed - Gconv->minx)/Gconv->scale;
01571 X2 = rational(coord2int(x2,cbuf),cbuf);
01572 y2 = (ymed - Gconv->miny)/Gconv->scale;
01573 Y2 = rational(coord2int(y2,cbuf),cbuf);
01574
01575 CutsX[1].val = X1 = G->P[0][0]->v.v().x;
01576 CutsX[2].val = X2;
01577 CutsX[3].val = X3 = G->P[0][1]->v.v().x;
01578
01579 CutsY[1].val = Y1 = G->P[0][0]->v.v().y;
01580 CutsY[2].val = Y2;
01581 CutsY[3].val = Y3 = G->P[1][0]->v.v().y;
01582
01583 nMaxE = 10*G->E.nElems; // this is a hack, but its enough even in the
01584 // in the worst case
01585 hE = (graph_edge **)alloca( sizeof(graph_edge *) * nMaxE );
01586
01587 // split graph into vertical strips
01588 IntersectWithVerticals( &G->E, &G->V, 4, CutsX );
01589
01590 // isolate first vertical strip and discard it
01591 DivideVerticalStrips( &CutsX[3], &CutsX[2], nMaxE,
01592 MinY, MaxY, FarMinY, FarMaxY,
01593 &Vy1Sr, &Vy1Sl, &Vy2Sr, &Vy2Sl );
01594
01595 /*
01596 cout << "after disconnecting X-Strip " << 3 << " and " << 2 << "\n";
01597 cout << "*******************************************************\n";
01598 for( int k = 3; k >= 0; k-- )
01599 {
01600 cout << "X-Strip " << k << "\n";
01601 gugr::Dump<T>::dump_vertices( CutsX[k].V.head );
01602 gugr::Dump<T>::dump_edges( CutsX[k].E.head );
01603 }
01604 */
01605
01606 CutsX[3].R.DeleteElems();
01607 CutsX[3].E.DeleteElems();
01608 CutsX[3].V.DeleteElems();
01609
01610 for( i = 2; i > 0; i-- )
01611 {
01612 DivideVerticalStrips( &CutsX[i], &CutsX[i-1], nMaxE,
01613 MinY, MaxY, FarMinY, FarMaxY,
01614 &Vy1Sr, &Vy1Sl, &Vy2Sr, &Vy2Sl );
01615
01616 /*
01617 cout << "after disconnecting X-Strip " << i << " and " << i-1 << "\n";
01618 cout << "*********************************************************\n";
01619 for( int k = i; k >= 0; k-- )
01620 {
01621 cout << "X-Strip " << k << "\n";
01622 gugr::Dump<T>::dump_vertices( CutsX[k].V.head );
01623 gugr::Dump<T>::dump_edges( CutsX[k].E.head );
01624 }
01625 */
01626 // split vertical strips into horizontal strips
01627 IntersectWithHorizontals( &CutsX[i].E, &CutsX[i].V, 4, CutsY );
01628
01629 // isolate first strip and discard it
01630 DivideHorizontalStrips( &CutsY[3], &CutsY[2], nMaxE,
01631 MinX, MaxX, FarMinX, FarMaxX,
01632 &Vx1Sa, &Vx1Sb, &Vx2Sa, &Vx2Sb );
01633
01634 /*
01635 cout << "after disconnecting Y-Strip " << 3 << " and " << 2 << "\n";
01636 cout << "*******************************************************\n";
01637 for( int k = 3; k >= 0; k-- )
01638 {
01639 cout << "Y-Strip " << k << "\n";
01640 gugr::Dump<T>::dump_vertices( CutsY[k].V.head );
01641 gugr::Dump<T>::dump_edges( CutsY[k].E.head );
01642 }
01643 */
01644
01645 CutsY[3].R.DeleteElems();
01646 CutsY[3].E.DeleteElems();
01647 CutsY[3].V.DeleteElems();
01648
01649 hvLeftT = Vx1Sb; hvRightT = Vx2Sb; // for next strip
01650
01651 // divide vertical strips into horizontal strips
01652 for( j = 2; j > 0; j-- )
01653 {
01654 DivideHorizontalStrips( &CutsY[j], &CutsY[j-1], nMaxE,
01655 MinX, MaxX, FarMinX, FarMaxX,
01656 &Vx1Sa, &Vx1Sb, &Vx2Sa, &Vx2Sb );
01657
01658 /*
01659 cout << "after disconnecting Y-Strip " << j << " and " << j-1 << "\n";
01660 cout << "*********************************************************\n";
01661 for( int k = j; k >= 0; k-- )
01662 {
01663 cout << "Y-Strip " << k << "\n";
01664 gugr::Dump<T>::dump_vertices( CutsY[k].V.head );
01665 gugr::Dump<T>::dump_edges( CutsY[k].E.head );
01666 }
01667 */
01668
01669 // remove help edges from the corner edge cycles
01670 v0 = hvLeftT;
01671 e = v0->e;
01672 sub[2*(j-1)+i-1]->face = e->e[0]->f[1].i; // face index of quad, if it is
01673 v = e->v[0]; // not divided
01674 sub[2*(j-1)+i-1]->P[1][0] = v;
01675 nhE = EdgeCycle( e, v, hE );
01676 el = hE[nhE-1];
01677 if( el->v[0] == v ) el->e[0] = e->e[0]; else el->e[1] = e->e[0];
01678 v->e = el;
01679 CutsY[j].V.Remove(v0); CutsY[j].E.Remove(e);
01680 delete v0; delete e;
01681
01682 v0 = hvRightT;
01683 e = v0->e;
01684 v = e->v[1];
01685 sub[2*(j-1)+i-1]->P[1][1] = v;
01686 nhE = EdgeCycle( e, v, hE );
01687 el = hE[nhE-1];
01688 if( el->v[0] == v ) el->e[0] = e->e[1]; else el->e[1] = e->e[1];
01689 v->e = el;
01690 CutsY[j].V.Remove(v0); CutsY[j].E.Remove(e);
01691 delete v0; delete e;
01692
01693 v0 = Vx2Sa;
01694 e = v0->e;
01695 v = e->v[1];
01696 sub[2*(j-1)+i-1]->P[0][1] = v;
01697 nhE = EdgeCycle( e, v, hE );
01698 el = hE[nhE-1];
01699 if( el->v[0] == v ) el->e[0] = e->e[1]; else el->e[1] = e->e[1];
01700 v->e = el;
01701 CutsY[j].V.Remove(v0); CutsY[j].E.Remove(e);
01702 delete v0; delete e;
01703
01704 v0 = Vx1Sa;
01705 e = v0->e;
01706 v = e->v[0];
01707 sub[2*(j-1)+i-1]->P[0][0] = v;
01708 nhE = EdgeCycle( e, v, hE );
01709 el = hE[nhE-1];
01710 if( el->v[0] == v ) el->e[0] = e->e[0]; else el->e[1] = e->e[0];
01711 v->e = el;
01712 CutsY[j].V.Remove(v0); CutsY[j].E.Remove(e);
01713 delete v0; delete e;
01714
01715 hvLeftT = Vx1Sb; hvRightT = Vx2Sb; // for next loop
01716
01717 CutsY[j].R.DeleteElems(); // free cut records only
01718 sub[2*(j-1)+i-1]->E += CutsY[j].E;
01719 sub[2*(j-1)+i-1]->V += CutsY[j].V;
01720 // CutsY[j].E.ReleaseElems(); // clear for next strip
01721 // CutsY[j].V.ReleaseElems();
01722 }
01723
01724 CutsY[0].R.DeleteElems();
01725 CutsY[0].E.DeleteElems();
01726 CutsY[0].V.DeleteElems();
01727
01728 CutsX[i].R.DeleteElems();
01729 CutsX[i].E.DeleteElems();
01730 CutsX[i].V.DeleteElems();
01731 }
01732
01733 CutsX[0].R.DeleteElems();
01734 CutsX[0].E.DeleteElems();
01735 CutsX[0].V.DeleteElems();
01736 }
|
|
||||||||||||||||||||
|
Definition at line 48 of file gugr_triangulate.cpp.
00050 {
00051 vertex farleft;
00052 graph_edge *e, *eb, *ea,*left,*right,**tmpE;
00053 graph_vertex *v;
00054 int ileft,iright,codel,coder,nE,Win,Wout,ie,iea,ieb;
00055 int nP,i;
00056 graph_edge *e1;
00057 monpoly_info *P,*tmpP;
00058 int li,ri;
00059
00060 tmpE = (graph_edge **)alloca( sizeof(graph_edge *)*(E->nElems) );
00061 if( !tmpE ) throw AllocError();
00062
00063 if( V->head != NULL ) v = V->head->next; /* second smallest vertex */
00064 else return;
00065 if( v->next == NULL ) return;
00066
00067 e = E->head;
00068 while( e != NULL ) /* initialize weights to 1 */
00069 { e->reserved[0].set_i(1); e = e->next; }
00070
00071 /* ---------- weight balancing, first pass ----------------------------- */
00072
00073 while( v->next != NULL )
00074 {
00075 nE = IncidentEdges( v, tmpE );
00076
00077 farleft = vertex( point2<rational>(far_left,v->v.v().y) );
00078 EdgeInsertPosition( v->v, farleft, nE, tmpE, &ileft, &iright,
00079 &codel, &coder );
00080 left = tmpE[ileft]; right = tmpE[iright];
00081
00082 if( right->v[0] == v ) /* => leftwards oriented horizontal edge */
00083 e = eb = right->e[0];
00084 else
00085 e = eb = right; /* eb = leftmost incoming edge */
00086
00087 Win = 0; /* sum of weights of incoming edges of v */
00088 while( e->v[1] == v )
00089 {
00090 Win += e->reserved[0].i;
00091 e = e->e[1];
00092 }
00093 Wout = 1; /* sum of weights of outgoing edges of v */
00094 while( e->e[0] != eb )
00095 {
00096 Wout++;
00097 e = e->e[0];
00098 }
00099 ea = e; /* ea = leftmost outgoing edge */
00100
00101 if( Win > Wout )
00102 ea->reserved[0].set_i(Win-Wout+1);
00103
00104 v = v->next;
00105 }
00106
00107 /***** second pass, combined with extraction of monotone polygons *********/
00108
00109 /* ------- initialize polygon slots at the maximum vertex -------- */
00110
00111 nP = 0;
00112
00113 nE = IncidentEdges( v, tmpE ); /* edges adjacent to maximum of graph */
00114
00115 farleft = vertex( point2<rational>(far_left,v->v.v().y) );
00116 EdgeInsertPosition( v->v, farleft, nE, tmpE, &ileft, &iright,
00117 &codel, &coder );
00118 e1 = right = tmpE[iright];
00119
00120 do
00121 {
00122 e1->reserved[1].set_i(nP); /* store index of the polygon on the right*/
00123 nP += e1->reserved[0].i; /* side of this edge */
00124 e1 = e1->e[1];
00125 }
00126 while( e1 != right );
00127 nP--;
00128
00129 P = tmpP = (monpoly_info *)alloca( sizeof(monpoly_info) * nP );
00130 if( P == NULL ) throw AllocError();
00131 // new(P) monpoly_info[nP];
00132 for( i = 0; i < nP; i++ ) new(tmpP++) monpoly_info;
00133
00134 /*
00135 std::cout << "number of monotone polygons = " << nP << "\n";
00136 */
00137
00138 /* ------- second pass of weight balancing -------- */
00139
00140 v = v->prev; /* v = second largest vertex */
00141
00142 while( v->prev != NULL )
00143 {
00144 nE = IncidentEdges( v, tmpE );
00145
00146 farleft = vertex( point2<rational>(far_left,v->v.v().y) );
00147 EdgeInsertPosition( v->v, farleft, nE, tmpE, &ileft, &iright,
00148 &codel, &coder );
00149 if( tmpE[iright]->v[0] == v ) /* => leftwards oriented horizontal edge */
00150 ie = iea = iright;
00151 else
00152 ie = iea = ileft; /* iea = index of leftmost outgoing edge */
00153
00154 Wout = 0; /* sum of weights of outgoing edges of v */
00155 do
00156 {
00157 Wout += tmpE[ie]->reserved[0].i;
00158
00159 /* ----- add edge to involved polygons ---------------- */
00160
00161 li = tmpE[ie]->reserved[1].i-1;
00162 if( (li >= 0) && (tmpE[ie]->f[0].i > 0) )
00163 {
00164 /*
00165 std::cout << "adding edge " << (void *)tmpE[ie] << " to polygon " <<
00166 li+1 << ", right chain\n";
00167 */
00168
00169 if( P[li].AppendRight(*v, *tmpE[ie]->v[1]) )
00170 {
00171 /*
00172 std::cout << "triangulating monotone polygon #" << li+1 << "\n";
00173 */
00174
00175 TriangulateMonotonePolygon( &P[li].Vl, &P[li].Vr, &P[li].E, T );
00176 }
00177 }
00178 ri = li + tmpE[ie]->reserved[0].i;
00179 if( (ri < nP) && (tmpE[ie]->f[1].i > 0) )
00180 {
00181 /*
00182 std::cout << "adding edge " << (void *)tmpE[ie] << " to polygon " <<
00183 ri+1 << ", left chain\n";
00184 */
00185
00186 if( P[ri].AppendLeft(*v, *tmpE[ie]->v[1]) )
00187 {
00188 /*
00189 std::cout << "triangulating monotone polygon #" << ri+1 << "\n";
00190 */
00191
00192 TriangulateMonotonePolygon( &P[ri].Vl, &P[ri].Vr, &P[ri].E, T );
00193 }
00194 }
00195
00196 /* ---------------------------------------------------- */
00197
00198 ie--; if(ie < 0) ie = nE-1;
00199 }
00200 while( tmpE[ie]->v[0] == v );
00201
00202 Win = 0; /* sum of weights of incoming edges of v */
00203 while( tmpE[ie] != tmpE[iea] )
00204 {
00205 Win += tmpE[ie]->reserved[0].i;
00206 ie--; if(ie < 0) ie = nE-1;
00207 }
00208 ieb = iea+1; /* ieb = index of leftmost incoming edge */
00209 if( ieb == nE ) ieb = 0;
00210
00211 if( Wout > Win )
00212 tmpE[ieb]->reserved[0].i += (Wout-Win);
00213
00214 /* -------- set polygon indices for incoming edges -------------------- */
00215
00216 i = tmpE[iea]->reserved[1].i; /* index of polygon to the right of */
00217 e = tmpE[ieb]; /* leftmost edges */
00218 e->reserved[1].set_i(i); /* give leftmost incoming edge this index */
00219 i += e->reserved[0].i; /* add multiplicity of edge */
00220 e = e->e[1]; /* next edge */
00221
00222 while( e->v[1] == v ) /* is next incoming edge */
00223 {
00224 e->reserved[1].set_i(i);
00225 i += e->reserved[0].i;
00226 e = e->e[1]; /* next edge */
00227 }
00228 /* -------------------------------------------------------------------- */
00229
00230 v = v->prev;
00231 }
00232
00233 /* process smallest vertex */
00234
00235 nE = IncidentEdges( v, tmpE ); /* incident edges to smallest vertex */
00236
00237 farleft = vertex( point2<rational>(far_left,v->v.v().y) );
00238 EdgeInsertPosition( v->v, farleft, nE, tmpE, &ileft, &iright,
00239 &codel, &coder );
00240 if( tmpE[iright]->IsHorizontal() ) /* => leftwards orient horizontal edge */
00241 ie = iea = iright;
00242 else
00243 ie = iea = ileft; /* iea = index of leftmost outgoing edge */
00244
00245 do /* add edges to involved polygons */
00246 {
00247 li = tmpE[ie]->reserved[1].i-1;
00248 if( (li >= 0) && (tmpE[ie]->f[0].i > 0) )
00249 {
00250 /*
00251 std::cout << "adding edge " << (void *)tmpE[ie] << " to polygon " <<
00252 li+1 << ", right chain\n";
00253 */
00254
00255 if( P[li].AppendRight(*v, *tmpE[ie]->v[1]) )
00256 {
00257 /*
00258 std::cout << "triangulating monotone polygon #" << li+1 << "\n";
00259 */
00260
00261 TriangulateMonotonePolygon( &P[li].Vl, &P[li].Vr, &P[li].E, T );
00262 }
00263 }
00264 ri = li + tmpE[ie]->reserved[0].i;
00265 if( (ri < nP) && (tmpE[ie]->f[1].i > 0) )
00266 {
00267 /*
00268 std::cout << "adding edge " << (void *)tmpE[ie] << " to polygon " <<
00269 ri+1 << ", left chain\n";
00270 */
00271
00272 if( P[ri].AppendLeft(*v, *tmpE[ie]->v[1]) )
00273 {
00274 /*
00275 std::cout << "triangulating monotone polygon #" << ri+1 << "\n";
00276 */
00277
00278 TriangulateMonotonePolygon( &P[ri].Vl, &P[ri].Vr, &P[ri].E, T );
00279 }
00280 }
00281
00282 ie--; if(ie < 0) ie = nE-1;
00283 }
00284 while( ie != iea );
00285
00286 for( i = 0; i < nP; i++ )
00287 {
00288 P[i].Vl.DeleteElems();
00289 P[i].Vr.DeleteElems();
00290 P[i].E.DeleteElems();
00291 }
00292 }
|
|
||||||||||||||||||||
|
Definition at line 303 of file gugr_triangulate.cpp.
00307 {
00308 graph_vertex_list2 Vq, S;
00309 graph_vertex *vh,*v1,*v2,*vi,*vi_1,*vs,*vt,*v,*vh1,*vh2;
00310 graph_edge *e;
00311 triangle *tri;
00312 int sign;
00313 graph_vertex_list V;
00314
00315 /*
00316 cout << "Triangulation of montone polygon\n";
00317 cout << "********************************\n";
00318 cout << "Vertices of left chain\n";
00319 cout << "======================\n";
00320 gugr::Dump<float>::dump_vertices( V1->head );
00321 cout << "Vertices of right chain\n";
00322 cout << "======================\n";
00323 gugr::Dump<float>::dump_vertices( V2->head );
00324 cout << "Edges (of both chains)\n";
00325 cout << "======================\n";
00326 gugr::Dump<float>::dump_edges( E->head );
00327 */
00328
00329 /* ----- merge together the vertices of both monotone chains ------------ */
00330
00331 vh1 = V1->Last(); /* first vertex of chain 1 */
00332 V1->Remove(vh1);
00333 V.Append(vh1);
00334
00335 vh2 = V2->Last(); /* first vertex of chain 2 */
00336 V2->Remove(vh2);
00337 V.Append(vh2);
00338
00339 v1 = V1->Last();
00340 V1->Remove(v1);
00341 v1->reserved[0].set_i(-1); /* element of left chain */
00342
00343 v2 = V2->Last();
00344 V2->Remove(v2);
00345 v2->reserved[0].set_i(+1); /* element of right chain */
00346
00347 if( (V1->Last() == NULL) && (V2->Last() == NULL) ) /* ready, no triangles */
00348 {
00349 delete v1; delete v2;
00350 V1->DeleteElems();
00351 V2->DeleteElems();
00352 V.DeleteElems();
00353 E->DeleteElems();
00354 return;
00355 }
00356 /* make first vertex of both chains have the same address */
00357 vh = new graph_vertex( vh2->v, NULL, vh2->reserved[1].i );
00358 Vq.AppendRight(vh);
00359 vh->reserved[0].set_i(0);
00360
00361 e = new graph_edge();
00362 E->Append(e);
00363 e->l = v1->e->l;
00364 e->v[0] = v1;
00365 e->v[1] = vh;
00366 v1->e = e;
00367
00368 e = new graph_edge();
00369 E->Append(e);
00370 e->l = v2->e->l;
00371 e->v[0] = v2;
00372 e->v[1] = vh;
00373 v2->e = e;
00374
00375 while( (v1 != NULL) || (v2 != NULL) )
00376 {
00377 if( v1 != NULL )
00378 {
00379 if( v2 != NULL )
00380 sign = compare( v1->v.v().y, v2->v.v().y );
00381 else
00382 sign = +1;
00383 }
00384 else sign = -1;
00385
00386 if( sign >= 0 )
00387 {
00388 if( v1->e->IsHorizontal() ) /* compress together horizontal edges */
00389 {
00390 vs = v1;
00391 vt = V1->Last();
00392 while( (vt != NULL) && (vt->e->IsHorizontal()) )
00393 {
00394 V1->Remove(vt);
00395 delete v1;
00396 v1 = vt;
00397 vt = V1->Last();
00398 }
00399 if( v1 != vs )
00400 {
00401 e = new graph_edge();
00402 E->Append(e);
00403 e->l = v1->e->l;
00404 e->v[0] = v1;
00405 e->v[1] = vh;
00406 v1->e = e;
00407 }
00408 }
00409 v1->reserved[0].set_i(-1);
00410 Vq.AppendRight(v1);
00411 vh = v1;
00412 v1 = V1->Last();
00413 if( v1 != NULL ) V1->Remove(v1);
00414 }
00415 else
00416 {
00417 if( v2->e->IsHorizontal() ) /* compress together horizontal edges */
00418 {
00419 vs = v2;
00420 vt = V2->Last();
00421 while( (vt != NULL) && (vt->e->IsHorizontal()) )
00422 {
00423 V2->Remove(vt);
00424 delete v2;
00425 v2 = vt;
00426 vt = V2->Last();
00427 }
00428 if( v2 != vs )
00429 {
00430 e = new graph_edge();
00431 E->Append(e);
00432 e->l = v2->e->l;
00433 e->v[0] = v2;
00434 e->v[1] = vh;
00435 v2->e = e;
00436 }
00437 }
00438
00439 v2->reserved[0].set_i(+1);
00440 Vq.AppendRight(v2);
00441 vh = v2;
00442 v2 = V2->Last();
00443 if( v2 != NULL ) V2->Remove(v2);
00444 }
00445 }
00446
00447 vh->prev->reserved[0].set_i(0); /* this is the last vertex */
00448 Vq.Remove(vh);
00449 delete vh;
00450
00451 /* ---- construct the triangles ------------------------------------------- */
00452
00453 v = Vq.First(); /* put first two vertices on stack */
00454 Vq.Remove(v);
00455 S.AppendRight(v);
00456
00457 v = Vq.First();
00458 Vq.Remove(v);
00459 S.AppendRight(v);
00460
00461 v = Vq.First();
00462 Vq.Remove(v);
00463
00464 while( v->reserved[0].i != 0 ) /* not the last vertex */
00465 {
00466 vi = S.Last();
00467 v1 = S.First();
00468
00469 e = v->e;
00470
00471 if( e->v[1] == vi ) /* adjacent to top of stack */
00472 {
00473 vi_1 = vi->prev;
00474
00475 sign = DetermineOrientation(v->v.v(),vi->v.v(),vi_1->v.v());
00476 sign *= v->reserved[0].i;
00477
00478 if( (sign == 0) && (v->e->IsHorizontal()) ) /* special case */
00479 {
00480 S.Remove(vi);
00481 V.Append(vi);
00482 S.AppendRight(v);
00483 }
00484 else
00485 {
00486 while( (sign > 0) && (S.nElems > 1) )
00487 {
00488 tri = new triangle();
00489 if( vi->reserved[0].i == +1 )
00490 {
00491 tri->v[0] = v->v; tri->code0 = v->reserved[1].i;
00492 tri->v[1] = vi->v; tri->code1 = vi->reserved[1].i;
00493 tri->v[2] = vi_1->v; tri->code2 = vi_1->reserved[1].i;
00494 /*
00495 cout << "TRIANGLE\n";
00496 Dump<float>::dump_vertice(v);
00497 Dump<float>::dump_vertice(vi);
00498 Dump<float>::dump_vertice(vi_1);
00499 */
00500 }
00501 else
00502 {
00503 tri->v[0] = v->v; tri->code0 = v->reserved[1].i;
00504 tri->v[1] = vi_1->v; tri->code1 = vi_1->reserved[1].i;
00505 tri->v[2] = vi->v; tri->code2 = vi->reserved[1].i;
00506 /*
00507 cout << "TRIANGLE\n";
00508 Dump<float>::dump_vertice(v);
00509 Dump<float>::dump_vertice(vi_1);
00510 Dump<float>::dump_vertice(vi);
00511 */
00512 }
00513 T->Append(tri);
00514
00515 S.Remove(vi);
00516 V.Append(vi);
00517 if( S.nElems > 1 )
00518 {
00519 vi = vi_1;
00520 vi_1 = vi->prev;
00521 sign = DetermineOrientation(v->v.v(),vi->v.v(),vi_1->v.v());
00522 sign *= v->reserved[0].i;
00523 }
00524 }
00525 S.AppendRight(v);
00526 }
00527 }
00528 else /* adjacent to bottom of stack */
00529 {
00530 gul::Assert<gul::InternalError>( ndebug || (e->v[1] == v1) );
00531
00532 if( v->e->IsHorizontal() ) /* special case */
00533 {
00534 gul::Assert<gul::InternalError>( ndebug || (S.nElems == 2) );
00535 S.Remove(v1);
00536 V.Append(v1);
00537 S.AppendRight(v);
00538 }
00539 else
00540 {
00541 v2 = v1->next;
00542 do
00543 {
00544 tri = new triangle();
00545 if( v2->reserved[0].i == +1 )
00546 {
00547 tri->v[0] = v->v; tri->code0 = v->reserved[1].i;
00548 tri->v[1] = v2->v; tri->code1 = v2->reserved[1].i;
00549 tri->v[2] = v1->v; tri->code2 = v1->reserved[1].i;
00550 /*
00551 cout << "TRIANGLE\n";
00552 Dump<float>::dump_vertice(v);
00553 Dump<float>::dump_vertice(v2);
00554 Dump<float>::dump_vertice(v1);
00555 */
00556 }
00557 else
00558 {
00559 tri->v[0] = v->v; tri->code0 = v->reserved[1].i;
00560 tri->v[1] = v1->v; tri->code1 = v1->reserved[1].i;
00561 tri->v[2] = v2->v; tri->code2 = v2->reserved[1].i;
00562 /*
00563 cout << "TRIANGLE\n";
00564 Dump<float>::dump_vertice(v);
00565 Dump<float>::dump_vertice(v1);
00566 Dump<float>::dump_vertice(v2);
00567 */
00568 }
00569 T->Append(tri);
00570
00571 S.Remove(v1);
00572 V.Append(v1);
00573 v1 = v2;
00574 v2 = v1->next;
00575 }
00576 while( v2 != NULL );
00577
00578 S.AppendRight(v);
00579 }
00580 }
00581
00582 v = Vq.First();
00583 Vq.Remove(v);
00584 }
00585
00586 /* last vertex */
00587
00588 v1 = S.First();
00589 do
00590 {
00591 v2 = v1->next;
00592
00593 tri = new triangle();
00594 if( (int)v2->reserved[0].i == +1 )
00595 {
00596 tri->v[0] = v->v; tri->code0 = v->reserved[1].i;
00597 tri->v[1] = v2->v; tri->code1 = v2->reserved[1].i;
00598 tri->v[2] = v1->v; tri->code2 = v1->reserved[1].i;
00599 /*
00600 cout << "TRIANGLE\n";
00601 Dump<float>::dump_vertice(v);
00602 Dump<float>::dump_vertice(v2);
00603 Dump<float>::dump_vertice(v1);
00604 */
00605 }
00606 else
00607 {
00608 tri->v[0] = v->v; tri->code0 = v->reserved[1].i;
00609 tri->v[1] = v1->v; tri->code1 = v1->reserved[1].i;
00610 tri->v[2] = v2->v; tri->code2 = v2->reserved[1].i;
00611 /*
00612 cout << "TRIANGLE\n";
00613 Dump<float>::dump_vertice(v);
00614 Dump<float>::dump_vertice(v1);
00615 Dump<float>::dump_vertice(v2);
00616 */
00617 }
00618 T->Append(tri);
00619
00620 S.Remove(v1);
00621 V.Append(v1);
00622 v1 = v2;
00623 v2 = v1->next;
00624 }
00625 while( v2 != NULL );
00626 S.Remove(v1);
00627 V.Append(v1);
00628
00629 delete v;
00630
00631 gul::Assert<gul::InternalError>( ndebug ||
00632 ((S.nElems == 0) && (Vq.nElems == 0) &&
00633 (V1->nElems == 0) && (V2->nElems == 0)) );
00634
00635 // S.DeleteElems();
00636 // Vq.DeleteElems();
00637 // V1->DeleteElems();
00638 // V2->DeleteElems();
00639 V.DeleteElems();
00640 E->DeleteElems();
00641 }
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
|
Definition at line 451 of file gugr_face.cpp.
00462 {
00463 T minx,maxx,miny,maxy;
00464 T dx,dy,scale,scalei;
00465 ListNode< gugr::polyline > *pn,*inc;
00466 ListNode< gul::polyline< point<T> > > *inF,*inN,*inT;
00467 List< ListNode< gul::polyline< point2<T> > > > C2;
00468 ListNode< gul::polyline< point2<T> > > *c2;
00469 List< ListNode<polyline> > Pl;
00470 List< ListNode<segment> > segs,outsegs;
00471 ListNode<segment> *seg;
00472 graph_edge_list E;
00473 graph_vertex_list V;
00474 rational far_minx,far_maxx,far_miny,far_maxy;
00475 unsigned long *cbuf =
00476 (unsigned long *)alloca(gul::rtr<T>::mantissa_length());
00477 int nv,i,nt;
00478 Ptr< point<T> > &sumF = F, &sumN = N, &sumT = Tx;
00479 Ptr<T> sumW;
00480 graph_vertex *vn;
00481 graph_edge *e;
00482 ListNode<graph_edge *> *en;
00483 Interval iu,iv;
00484 T u,v,u1,u2,v1,v2,su,sv,alpha,w,wi,giant;
00485 point<T> fB,nB,fE,nE,tB,tE,f,n,t;
00486 bool end;
00487 triangle_list tri;
00488 triangle *tr;
00489
00490 if( C3.nElems == 0 ) return;
00491
00492 giant = gul::rtr<T>::giant();
00493
00494 Polygon3dTo2d( C3, Ti, C2 );
00495
00496 c2 = C2.First();
00497 CalcBoundingBoxE( c2->el.n, c2->el.P, minx, maxx, miny, maxy );
00498 c2 = c2->next;
00499
00500 while( c2 )
00501 {
00502 UpdateBoundingBoxE( c2->el.n, c2->el.P, minx, maxx, miny, maxy );
00503 c2 = c2->next;
00504 }
00505
00506 dx = maxx - minx;
00507 dy = maxy - miny;
00508 scale = dx > dy ? dx : dy;
00509 minx -= scale;
00510 miny -= scale;
00511 scalei = (T)1.0/scale;
00512
00513 c2 = C2.First();
00514 while( c2 )
00515 {
00516 pn = new ListNode<gugr::polyline>();
00517 Pl.Append( pn );
00518 pn->el.init( c2->el.n, c2->el.P, minx, miny, scalei );
00519 c2 = c2->next;
00520 }
00521
00522 inc = Pl.First();
00523 inF = C3.First();
00524 inN = N3.First();
00525 inT = T3.First();
00526
00527 while( inc )
00528 {
00529 AppendContourFNT( &inc->el, inF->el.P, inN->el.P, inT->el.P, 0, 0, segs );
00530 inc = inc->next;
00531 inF = inF->next;
00532 inN = inN->next;
00533 inT = inT->next;
00534 }
00535
00536 IntersectSegments( segs, &E, &V, true );
00537
00538 far_miny = far_minx = rational( guar::ULong(0x100000), -1 );
00539 far_maxy = far_maxx = rational( coord2int((T)2,cbuf),cbuf) +
00540 rational( guar::ULong(0x100000) );
00541
00542 RemoveUnnecessaryEdges( E, V, far_maxx, far_maxy, 1, 0, outsegs );
00543
00544 ISDeleteBackpointers(E); // the backpointers were used to remove edge entries
00545 // from 'segs' in 'RemoveUnnecessaryEdges'
00546 outsegs.DeleteElems();
00547
00548 // if the contours intersect each other 3d points and normals must be
00549 // calculated at the intersections
00550
00551 nv = V.nElems;
00552 D.reserve_pool(nv);
00553 sumF.reserve_pool(nv);
00554 sumN.reserve_pool(nv);
00555 sumT.reserve_pool(nv);
00556 sumW.reserve_pool(nv);
00557
00558 i = 0;
00559 vn = V.First();
00560 while( vn )
00561 {
00562 vn->v.m_rep->reserved.i = i; // enumber vertices
00563
00564 iu = vn->v.v().x.get_bounds();
00565 iv = vn->v.v().y.get_bounds();
00566 u = (T)((iu.m_low+iu.m_high)/2.0);
00567 v = (T)((iv.m_low+iv.m_high)/2.0);
00568 u = gugr::cnv2coord(u)*scale + minx;
00569 v = gugr::cnv2coord(v)*scale + miny;
00570
00571 D[i].x = u;
00572 D[i].y = v;
00573 set( sumF[i], (T)0 );
00574 set( sumN[i], (T)0 );
00575 sumW[i] = (T)0;
00576
00577 i++;
00578 vn = vn->next;
00579 }
00580
00581 for( seg = segs.First(); seg != 0; seg = seg->next )
00582 {
00583 // get function value and normal of start and end point of segment
00584 fB = *((seg_point_info< point<T> > *)seg->el.reserved[0])->f;
00585 nB = *((seg_point_info< point<T> > *)seg->el.reserved[0])->n;
00586 tB = *((seg_point_info< point<T> > *)seg->el.reserved[0])->t;
00587 fE = *((seg_point_info< point<T> > *)seg->el.reserved[1])->f;
00588 nE = *((seg_point_info< point<T> > *)seg->el.reserved[1])->n;
00589 tE = *((seg_point_info< point<T> > *)seg->el.reserved[1])->t;
00590
00591 // get u,v of segment start point
00592 iu = seg->el.E.x.get_bounds();
00593 iv = seg->el.E.y.get_bounds();
00594 u = (T)((iu.m_low+iu.m_high)/2.0);
00595 v = (T)((iv.m_low+iv.m_high)/2.0);
00596 u2 = cnv2coord(u)*scale + minx;
00597 v2 = cnv2coord(v)*scale + miny;
00598
00599 // get u,v of segment end point
00600 iu = seg->el.B.x.get_bounds();
00601 iv = seg->el.B.y.get_bounds();
00602 u = (T)((iu.m_low+iu.m_high)/2.0);
00603 v = (T)((iv.m_low+iv.m_high)/2.0);
00604 u1 = cnv2coord(u)*scale + minx;
00605 v1 = cnv2coord(v)*scale + miny;
00606
00607 su = u2 - u1;
00608 sv = v2 - v1;
00609
00610 // travert edges on this segment
00611
00612 en = seg->el.e.First();
00613 if( !en ) continue;
00614 e = en->el;
00615 if( e->l.IsHorizontal() || (e->l.dx().test() < 0) )
00616 end = 0;
00617 else
00618 end = 1;
00619
00620 for( ; en != 0; en = en->next )
00621 {
00622 e = en->el;
00623
00624 /* ---- first point of edge --------------------------- */
00625
00626 vn = e->v[!end];
00627 i = vn->v.m_rep->reserved.i;
00628 u = D[i].x - u1;
00629 v = D[i].y - v1;
00630
00631 if( su > sv )
00632 alpha = u/su;
00633 else if( sv > (T)0 )
00634 alpha = v/sv;
00635 else
00636 alpha = (T)0;
00637
00638 if( (alpha == (T)0) || (alpha >= (T)1) )
00639 {
00640 wi = giant;
00641 }
00642 else
00643 {
00644 if( alpha > (T)0.5 )
00645 {
00646 u = u2 - D[i].x;
00647 v = v2 - D[i].y;
00648 }
00649 w = u*u + v*v;
00650 if( w > (T)0 ) wi = (T)1.0/w;
00651 else wi = giant;
00652 }
00653
00654 f = ((T)1.0-alpha)*fB + alpha*fE;
00655 n = ((T)1.0-alpha)*nB + alpha*nE;
00656 t = ((T)1.0-alpha)*tB + alpha*tE;
00657
00658 if( wi >= giant )
00659 {
00660 if( sumW[i] >= (T)0 )
00661 {
00662 sumW[i] = (T)-1.0;
00663 sumF[i] = -f;
00664 sumN[i] = -n;
00665 sumT[i] = -t;
00666 }
00667 else
00668 {
00669 sumW[i] -= (T)1.0;
00670 sumF[i] -= f;
00671 sumN[i] -= n;
00672 sumT[i] -= t;
00673 }
00674 }
00675 else
00676 {
00677 sumW[i] += wi;
00678 sumF[i] += wi*f;
00679 sumN[i] += wi*n;
00680 sumT[i] += wi*t;
00681 }
00682
00683 /* ---- second point of edge --------------------------- */
00684
00685 if( en->next && (en->next->el->v[!end] == e->v[end]) )
00686 continue; // will be processed with next edge
00687
00688 vn = e->v[end];
00689 i = vn->v.m_rep->reserved.i;
00690 u = D[i].x - u1;
00691 v = D[i].y - v1;
00692
00693 if( su > sv )
00694 alpha = u/su;
00695 else if( sv > (T)0 )
00696 alpha = v/sv;
00697 else
00698 alpha = (T)0;
00699
00700 if( (alpha == (T)0) || (alpha >= (T)1) )
00701 {
00702 wi = giant;
00703 }
00704 else
00705 {
00706 if( alpha > (T)0.5 )
00707 {
00708 u = u2 - D[i].x;
00709 v = v2 - D[i].y;
00710 }
00711 w = u*u + v*v;
00712 if( w > (T)0 ) wi = (T)1.0/w;
00713 else wi = giant;
00714 }
00715
00716 f = ((T)1.0-alpha)*fB + alpha*fE;
00717 n = ((T)1.0-alpha)*nB + alpha*nE;
00718 t = ((T)1.0-alpha)*tB + alpha*tE;
00719
00720 if( wi >= giant )
00721 {
00722 if( sumW[i] >= (T)0 )
00723 {
00724 sumW[i] = (T)-1;
00725 sumF[i] = -f;
00726 sumN[i] = -n;
00727 sumT[i] = -t;
00728 }
00729 else
00730 {
00731 sumW[i] -= (T)1;
00732 sumF[i] -= f;
00733 sumN[i] -= n;
00734 sumT[i] -= t;
00735 }
00736 }
00737 else
00738 {
00739 sumW[i] += wi;
00740 sumF[i] += wi*f;
00741 sumN[i] += wi*n;
00742 sumT[i] += wi*t;
00743 }
00744 }
00745 }
00746
00747 for( i = 0; i < nv; i++ )
00748 {
00749 wi = (T)1/sumW[i];
00750 sumF[i] *= wi;
00751 sumN[i] *= wi;
00752 sumT[i] *= wi;
00753 }
00754
00755 // delete not needed data
00756 segs.DeleteElems();
00757
00758 /* ---- finally, triangulate the graph ------------------- */
00759
00760 Regularize( &E, &V );
00761
00762 Triangulate( &E, &V, far_minx, &tri );
00763
00764 nt = tri.nElems;
00765 Tri.reserve_pool(nt);
00766 tr = tri.First();
00767
00768 for( i = 0; i < nt; i++ )
00769 {
00770 Tri[i].v[0] = tr->v[0].m_rep->reserved.i;
00771 Tri[i].v[1] = tr->v[1].m_rep->reserved.i;
00772 Tri[i].v[2] = tr->v[2].m_rep->reserved.i;
00773 tr = tr->next;
00774 }
00775 *nTri = nt;
00776 }
|
|
||||||||||||||||||||||||||||||||||||||||||||
|
|
|
||||||||||||||||||||||||||||||||||||||||||||
|
|
|
||||||||||||||||||||
|
Definition at line 106 of file gugr_bool.h.
00110 {
00111 T minx,miny,scale;
00112 rational far_x,far_y;
00113 gul::List<gul::ListNode<gugr::polyline> > PA,PB;
00114 gul::List<gul::ListNode<gul::polyline<gul::point2<rational> > > > PC;
00115
00116 ConvertToRationalPolys(fPA,fPB,&minx,&miny,&scale,&far_x,&far_y,PA,PB);
00117 DoUnion(PA,PB,far_x,far_y,PC);
00118 ConvertToFloatPoly(PC,minx,miny,scale,fPC);
00119 }
|
|
||||||||||||||||||||||||
|
Definition at line 362 of file gugr_bool.cpp.
00364 {
00365 ListNode<gul::polyline<point2<rational> > > *pln;
00366 gul::ptr_int_union UA,UB;
00367 gul::RefMap<void>::Node cn;
00368 bool store;
00369
00370 UA.set_i(OutA);
00371 UB.set_i(OutB);
00372 store = false;
00373
00374 if( (oset & (OutA|OutB)) != 0 )
00375 {
00376 if( C->hasOwner(UA.p) )
00377 oset ^= OutA;
00378
00379 if( C->hasOwner(UB.p) )
00380 oset ^= OutB;
00381
00382 if( (oset & (OutA|OutB)) == 0 )
00383 store = true;
00384 }
00385 else
00386 {
00387 if( C->hasOwner(UA.p) )
00388 oset ^= OutA;
00389
00390 if( C->hasOwner(UB.p) )
00391 oset ^= OutB;
00392
00393 if( (oset & (OutA|OutB)) != 0 )
00394 store = true;
00395 }
00396
00397 if( store )
00398 {
00399 pln = new ListNode<gul::polyline<point2<rational> > >();
00400 C->get_polyline_joined( pln->el );
00401 pl.Append(pln);
00402 }
00403
00404 // travert children
00405 cn = C->childs.First();
00406 while( !cn.IsEmpty() )
00407 {
00408 UnionSubTree( (contour_node *)cn.key(), oset, OutA, OutB, pl );
00409 cn = C->childs.Successor( cn );
00410 }
00411 }
|
|
||||||||||||
|
Definition at line 91 of file gugr_planesweep.cpp.
00092 {
00093 return compare( C->y, R->I.y );
00094 }
|
1.2.13.1 written by Dimitri van Heesch,
© 1997-2001