Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members  

gugr Namespace Reference


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_vertexgraph_vertex_list
typedef List2< graph_vertexgraph_vertex_list2
typedef List< graph_edgegraph_edge_list
typedef gugr::_cut_record cut_record
typedef List< cut_recordcut_record_list
typedef gugr::_cut_info cut_info
typedef List< triangletriangle_list
typedef gul::List< gul::ListNode<
segment > > 
segment_list
typedef GraphInfoGraphInfo4 [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)
intersectionintersect (Map< linerec >::Node L1, Map< linerec >::Node L2, const rational &xleft, Map< eventrec > *EvQ, List< intersection > *Ipts)
intersectionintersect_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_vertexSortVertices (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)


Typedef Documentation

typedef struct gugr::_cut_info gugr::cut_info
 

typedef struct gugr::_cut_record gugr::cut_record
 

typedef List<cut_record> gugr::cut_record_list
 

Definition at line 408 of file gugr_basics.h.

Referenced by gugr::_cut_record::operator delete().

typedef List<graph_edge> gugr::graph_edge_list
 

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().

typedef List<graph_vertex> gugr::graph_vertex_list
 

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().

typedef List2<graph_vertex> gugr::graph_vertex_list2
 

Definition at line 333 of file gugr_basics.h.

Referenced by gugr::graph_vertex::operator delete().

typedef GraphInfo* gugr::GraphInfo4[4]
 

Definition at line 67 of file gugr_split.h.

Referenced by gugr::GraphInfo::operator delete().

typedef gul::List<gul::ListNode<segment> > gugr::segment_list
 

Definition at line 74 of file gugr_planesweep.h.

typedef List<triangle> gugr::triangle_list
 

Definition at line 442 of file gugr_basics.h.

Referenced by gugr::triangle::operator delete().


Function Documentation

void gugr::AppendContour polyline   c,
int    keyleft,
int    keyright,
List< ListNode< segment > > &    segs
 

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 }

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
 

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<class EP>
void gugr::AppendContourFNT polyline   c,
Ptr< EP > &    F,
Ptr< EP > &    N,
Ptr< EP > &    T,
int    keyleft,
int    keyright,
List< ListNode< segment > > &    segs
 

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 }

template GULAPI bool CalcPlane int    nVerts,
const Ptr< point< double > > &    Verts,
point< double > &    o,
point< double > &    b1,
point< double > &    b2,
point< double > &    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<class T>
GULAPI bool gugr::CalcPlane int    nVerts,
const Ptr< point< T > > &    Verts,
point< T > &    o,
point< T > &    b1,
point< T > &    b2,
point< T > &    b3
 

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 }

template GULAPI bool CheckLeftHandedness int    nP,
const Ptr< point< double > > &    P,
const Ptr< Ptr< double > > &    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<class T>
GULAPI bool gugr::CheckLeftHandedness int    nP,
const Ptr< point< T > > &    P,
const Ptr< Ptr< T > > &    Ti,
bool &    lefthanded,
bool &    selfintersect
 

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 }

template<class T>
T cnv2coord const T &    i
 

Definition at line 86 of file gugr_basics.h.

00087 {
00088   return i * gul::rtr<T>::epsilon() + (T)1.0;
00089 }

template<class T>
void cnv2coord_rnd rational &    f,
T *    ret
[inline]
 

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 }

int compare_cut_records void *    p1,
void *    p2,
void *    data
 

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 }

int compare_edge_to_intervalBU void *    p1,
void *    p2
 

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 }

int compare_edge_to_intervalTD void *    p1,
void *    p2
 

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 }

int compare_linerec_to_linerec linerec   L1,
linerec   L2
 

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 }

int gugr::compare_point_to_eventrec point2< rational > *    C,
eventrec   E
 

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 }

int compare_point_to_linerec point2< rational > *    P,
linerec   L
 

Definition at line 64 of file gugr_planesweep.cpp.

00065 {
00066   return DetermineOrientation( L->B, L->E, *P );
00067 }

int gugr::compare_pointer_to_pointer void *    p1,
void *    p2
 

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 }

int compare_segment_to_linerec segment   S,
linerec   L
 

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 }

int gugr::compare_vertices void *    p1,
void *    p2,
void *    data
 

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 }

int gugr::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
 

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 }

int CompareEdgesBU const graph_edge   A,
const graph_edge   B
 

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 }

int CompareEdgesTD const graph_edge   A,
const graph_edge   B
 

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 }

void gugr::ConnectEdge graph_edge   e,
int    maxE
 

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 }

void ContainmentTree List< ListNode< segment > > &    insegs,
const rational &    far_maxx,
const rational &    far_maxy,
gul::List< contour_node > &    contours,
contour_node   universe
 

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 }

template GULAPI void ConvertToFloatPoly List< ListNode< gul::polyline< point2< rational > > > > &    inA,
double    minx,
double    miny,
double    scale,
List< ListNode< gul::polyline< point2< double > > > > &    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<class T>
GULAPI void gugr::ConvertToFloatPoly List< ListNode< gul::polyline< point2< rational > > > > &    inA,
  minx,
  miny,
  scale,
List< ListNode< gul::polyline< point2< T > > > > &    outA
 

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 }

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 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<class T>
GULAPI void gugr::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
 

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 }

int coord2int float    f,
unsigned long *    buf
[inline]
 

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 }

int coord2int double    f,
unsigned long *    buf
[inline]
 

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 }

void CT_DoAboveEdge graph_edge   e,
graph_vertex   v,
contour_node **    pCA,
contour_node **    pCB
 

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 }

void CT_DoBelowEdge graph_edge   e,
graph_vertex   v,
contour_node **    pCA,
contour_node **    pCB
 

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 }

int gugr::DetermineOrientation const point2< rational > &    A,
const point2< rational > &    B,
const point2< rational > &    C
 

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 }

int gugr::DetermineOrientationPV const point2< rational > &    A,
const point2< rational > &    AB,
const point2< rational > &    C
 

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 }

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
[inline]
 

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 }

void DifferenceSubTree contour_node   C,
int    oset,
int    InA,
int    OutB,
List< ListNode< gul::polyline< point2< rational > > > > &    pl
 

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 }

int gugr::DisconnectEdge graph_edge   e,
int    maxE
 

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 }

void gugr::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
 

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 }

void gugr::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
 

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 }

GULAPI void gugr::DoDifference List< ListNode< polyline > > &    PA,
List< ListNode< polyline > > &    PB,
const rational &    far_x,
const rational &    far_y,
List< ListNode< gul::polyline< point2< rational > > > > &    C
 

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 }

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
 

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
 

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 }

void gugr::DoIntersectSegments int    nsegs,
Map< eventrec > &    EvQ,
gugr::graph_edge_list   E,
gugr::graph_vertex_list   V
 

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 }

GULAPI void gugr::DoUnion List< ListNode< polyline > > &    PA,
List< ListNode< polyline > > &    PB,
const rational &    far_x,
const rational &    far_y,
List< ListNode< gul::polyline< point2< rational > > > > &    C
 

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 }

void dump_segment segment   S,
std::ostream &    s
[inline]
 

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 }

int gugr::EdgeCycle graph_edge   e,
graph_vertex   v,
graph_edge **    A
 

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 }

void EdgeInsert graph_edge   e,
int    maxE
 

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 }

int gugr::EdgeInsertPosition const vertex   a,
const vertex   b,
int    nE,
graph_edge **    E,
int *    eleft,
int *    eright,
int *    code_left,
int *    code_right
 

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 }

void gugr::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
 

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 }

int FindCutInfo rational &    x,
int    nA,
const Ptr< cut_info > &    A,
bool &    found
 

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 }

void finish_line linerec   L,
graph_edge_list   E,
graph_vertex_list   V,
int    maxE,
List< intersection > *    Ipts,
List< intersectionseg > *    Isegs
 

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 }

void finish_vertline linerec   L,
graph_edge_list   E,
graph_vertex_list   V,
int    maxE,
List< intersection > *    Ipts,
List< intersectionseg > *    Isegs
 

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 }

int hcompare_point_to_intersection point2< rational > *    C,
intersection   R
 

Definition at line 87 of file gugr_planesweep.cpp.

00088 {
00089   return compare( C->x, R->I.x );
00090 }

int gugr::IncidentEdges const graph_vertex   v,
graph_edge **    A
 

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 }

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
 

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<class T>
void gugr::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
 

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 }

void gugr::InsertDiagonal graph_edge_list   E,
graph_vertex_list   V,
graph_vertex   P11,
graph_vertex   P22
 

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 }

intersection* intersect Map< linerec >::Node    L1,
Map< linerec >::Node    L2,
const rational &    xleft,
Map< eventrec > *    EvQ,
List< intersection > *    Ipts
 

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 }

bool gugr::intersect const line   a,
const line   b,
point2< rational > &    I
 

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 }

bool gugr::intersect_horiz const rational &    y0,
const line   b,
point2< rational > &    I
 

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 }

bool gugr::intersect_nonvert const line   a,
const line   b,
point2< rational > &    I
 

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 }

intersection* intersect_vert linerec   vL,
Map< linerec >::Node    L,
List< intersection > *    Ipts
 

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 }

bool gugr::intersect_vert const rational &    x0,
const line   b,
point2< rational > &    I
 

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 }

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
[inline]
 

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 }

void IntersectionSubTree contour_node   C,
int    oset,
int    InA,
int    InB,
List< ListNode< gul::polyline< point2< rational > > > > &    pl
 

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 }

void IntersectSegments gul::List< gul::ListNode< segment > > &    segs,
gugr::graph_edge_list   E,
gugr::graph_vertex_list   V,
bool    need_backpointers
[inline]
 

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 }

void IntersectSegments int    nsegs,
Ptr< segment   segs,
gugr::graph_edge_list   E,
gugr::graph_vertex_list   V
[inline]
 

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 }

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
 

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 }

void gugr::IntersectWithHorizontals graph_edge_list   E,
graph_vertex_list   V,
const int    nS,
gul::Ptr< cut_info   S
 

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 }

void gugr::IntersectWithVerticals graph_edge_list   E,
graph_vertex_list   V,
const int    nS,
gul::Ptr< cut_info   S
 

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 }

void ISDeleteBackpointers gugr::graph_edge_list   E [inline]
 

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 }

void ISDeleteOwnerMaps gugr::graph_edge_list   E [inline]
 

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 }

void gugr::LeftSideContour graph_edge   e,
graph_edge_list   E,
contour_node   cn
 

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 }

const graph_edge NegInf  ,
(graph_vertex  )(-1)
 

GULAPI void gugr::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
 

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 }

std::ostream& operator<< std::ostream &    s,
gugr::dump_segs   S
[inline]
 

Definition at line 283 of file gugr_io.h.

00284 {
00285   S.dump(S.m_S->First(),s);
00286   return s;
00287 } 

std::ostream& operator<< std::ostream &    s,
gugr::dump_graph   g
[inline]
 

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 } 

bool operator== const vertex   a,
const vertex   b
[inline]
 

Definition at line 190 of file gugr_basics.h.

00191 {
00192   return( a.m_rep == b.m_rep );
00193 }

void gugr::OrientEdge graph_edge   e
 

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 }

void gugr::OrientEdges graph_edge   E
 

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 }

bool parallel const line   a,
const line   b
[inline]
 

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 }

template void Polygon3dTo2d const List< ListNode< gul::polyline< point< double > > > > &    C3,
const Ptr< Ptr< double > > &    Ti,
List< ListNode< gul::polyline< point2< double > > > > &    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<class T>
void Polygon3dTo2d const List< ListNode< gul::polyline< point< T > > > > &    C3,
const Ptr< Ptr< T > > &    Ti,
List< ListNode< gul::polyline< point2< T > > > > &    C2
 

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 }

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 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<class T>
void gugr::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
 

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 }

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
 

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<class T>
void gugr::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
[inline]
 

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 }

const graph_edge PosInf  ,
(graph_vertex  )(+1)
 

void gugr::Regularize graph_edge_list   E,
graph_vertex_list   V
 

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 }

void gugr::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
 

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 }

void gugr::RightSideContour graph_edge   e,
graph_edge_list   E,
contour_node   cn
 

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 }

void sort_cut_records int    ns,
Ptr< cut_info   S
 

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 }

graph_vertex * gugr::SortVertices graph_vertex_list   V
 

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 }

template void SplitGraph GraphInfo   G,
double    xmed,
double    ymed,
GraphConvInfo< double > *    Gconv,
GraphInfo4   sub
 

template void SplitGraph GraphInfo   G,
float    xmed,
float    ymed,
GraphConvInfo< float > *    Gconv,
GraphInfo4   sub
 

template<class T>
void gugr::SplitGraph GraphInfo   G,
  xmed,
  ymed,
GraphConvInfo< T > *    Gconv,
GraphInfo4   sub
 

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 }

void gugr::Triangulate graph_edge_list   E,
graph_vertex_list   V,
const rational &    far_left,
triangle_list   T
 

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 }

void gugr::TriangulateMonotonePolygon graph_vertex_list2   V1,
graph_vertex_list2   V2,
graph_edge_list   E,
triangle_list   T
 

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 }

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
 

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
 

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 }

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 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<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
[inline]
 

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 }

void UnionSubTree contour_node   C,
int    oset,
int    OutA,
int    OutB,
List< ListNode< gul::polyline< point2< rational > > > > &    pl
 

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 }

int vcompare_point_to_intersection point2< rational > *    C,
intersection   R
 

Definition at line 91 of file gugr_planesweep.cpp.

00092 {
00093   return compare( C->y, R->I.y );
00094 }


Generated on Mon Jan 21 04:17:53 2002 for GUL 0.6 - Geometry Utility Library by doxygen1.2.13.1 written by Dimitri van Heesch, © 1997-2001