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