/*****************************************************************************/ /* */ /* Copyright (C) 2001-2025 M. Held */ /* */ /* This code is not in the public domain. All rights reserved! Please make */ /* sure to read the full copyright statement contained in "README.txt" or in */ /* the "main" file of this code, such as "main.cc". */ /* */ /*****************************************************************************/ /* */ /* Written by: Martin Held */ /* */ /* E-Mail: held@cs.sbg.ac.at */ /* Fax Mail: (+43 662) 8044-611 */ /* Voice Mail: (+43 662) 8044-6304 */ /* Snail Mail: Martin Held */ /* FB Informatik */ /* Universitaet Salzburg */ /* A-5020 Salzburg, Austria */ /* */ /*****************************************************************************/ /* */ /* get standard libraries */ /* */ #include #include #include #include #include /* */ /* get my header files */ /* */ #include "fpkernel.h" #include "vronivector.h" #include "vroni_object.h" #include "defs.h" #include "numerics.h" #include "wmat.h" #include "offset.h" #ifdef MAT #define ComputeContact(S, P, Q, A, B, T) \ {\ if (S) { \ P.x = Q.x - A * T; \ P.y = Q.y - B * T; \ } \ else { \ P.x = Q.x + A * T; \ P.y = Q.y + B * T; \ } \ } #define WmatErrorCheck(dist, wmat_dist_sq, ZERO, wmat_cosine, cosine, i, t, r1, r2) \ {\ if (gt(dist - wmat_dist_sq, ZERO) && gt(wmat_cosine - cosine, ZERO)) { \ if ((t < r1) || (t > r2)) { \ printf("WMAT violation I for edge %d and parameter %f\n", i, t); \ printf("wmat_cosine = %f, cosine = %f\n", wmat_cosine, cosine); \ printf("wmat_dist_sq = %20.16f, dist = %20.16f\n", wmat_dist_sq, dist); \ printf("r1 = %20.16f, r2 = %20.16f\n", r1, r2);\ } \ } \ else if ((t >= r1) && (t <= r2)) { \ if (lt(dist - wmat_dist_sq, ZERO) || lt(wmat_cosine - cosine, ZERO)) { \ printf("WMAT violation II for edge %d and parameter %f\n", i, t); \ printf("wmat_cosine = %f, cosine = %f\n", wmat_cosine, cosine); \ printf("wmat_dist_sq = %20.16f, dist = %20.16f\n", wmat_dist_sq, dist); \ printf("r1 = %20.16f, r2 = %20.16f\n", r1, r2);\ } \ } \ } /* */ /* the weighted medial axis (WMAT) is the subset of all those points P of */ /* the Voronoi diaram (VD) that meet the following requirements: */ /* (1) the clearance disk centered at P touches the input sites in at */ /* least two disjoint contact points C1 and C2. */ /* (2) the distance between C1 and C2 is greater than the (user-defined) */ /* threshold wmat_dist. */ /* (3) the angle formed by (C1,P,C2) is greater than the (user-defined) */ /* threshold wmat_angle. */ /* note that the WMAT is identical to the standard medial axis (MAT) for */ /* wmat_dist = wmat_angle = 0. see wmat.pdf in ../READMEs for a figure. */ /* */ /* for edge i of the VD, we store the WMAT data in the record */ /* edges[i].w_mat as follows: */ /* the vr_bool in_w_mat is true if a portion of this VD edge also belongs */ /* to the WMAT. */ /* r_min and r_max denote the minimum and maximum contour clearances of */ /* those points of this VD edge that belong to the WMAT. due to our specific */ /* parameterization of the VD edges, we have */ /* min{t1,t2} <= r_min <= r_max <= max{t1,t2}, where t1 and t2 are the */ /* contour clearances (radii) of the start node and end node of the VD edge. */ /* let P1 be the point on the VD edge that corresponds to the clearance */ /* radius r_min, and P2 the point that corresponds to r_max. the */ /* intersection (contact point) of the left defining site of the VD edge */ /* with a disk with radius r_min centered at P1 is stored in lft_mn_pnt,*/ /* and the intersection (contact point) of the right defining defining site */ /* of the VD edge with a disk with radius r_min centered at P1 is stored */ /* in rgt_mn_pnt. similar for P2 and lft_mx_pnt, rgt_mx_pnt. */ /* */ /* For closed contours, a one-sided computation of the WMAT may be requested */ /* by specifying the run-time options "--left_offset" or "--right_offset". */ /* */ vr_bool vroniObject::GetWMATStatus(void) { return WMAT_computed; } void vroniObject::ResetWMATStatus(void) { int i, num_edges; num_edges = GetNumberOfEdges(); for (i = 0; i < num_edges; ++i) { SetWmatEdge(i, false); } WMAT_computed = false; return; } #ifdef WMAT void vroniObject::CheckWMAT(double wmat_dist, double wmat_angle) { int num_edges, i, j, n1, n2, lft, rgt; t_site t_lft, t_rgt; double t, t1, t2, t3, r1, r2, a1, a2, b1, b2, c1, c2; coord p1, p2, q1, q2, u1, u2; double delta, wmat_dist_sq, wmat_cosine, cosine, dist; vr_bool s1, s2; num_edges = GetNumberOfEdges(); wmat_cosine = cos(wmat_angle); wmat_dist_sq = wmat_dist * wmat_dist; delta = 0.1 * wmat_dist; // if (lt(delta, SMALL)) delta = SMALL; /* must not be equal to 0.0!!!! */ // KO ? if ( delta < SMALL) delta = SMALL; /* must not be equal to 0.0!!!! */ for (i = 4; i < num_edges; ++i) { if (IsWmatEdge(i)) { n1 = GetStartNode(i); n2 = GetEndNode(i); GetNodeData(n1, &p1, &t1); GetNodeData(n2, &p2, &t2); if (t1 > t2) { VroniSwap(t1, t2, r1); } else { p1 = p2; } r1 = GetWmatRMin(i); r2 = GetWmatRMax(i); GetLftSiteData(i, &lft, &t_lft); GetRgtSiteData(i, &rgt, &t_rgt); if ((t_lft == PNT) && (t_rgt == SEG)) { VroniSwap(lft, rgt, j); t_lft = SEG; t_rgt = PNT; } t3 = t2 + delta * 0.5; if (t_lft == SEG) { GetSegEqnData(lft, &a1, &b1, &c1); if (PntLineDist(a1, b1, c1, p1) >= 0.0) s1 = true; else s1 = false; if (t_rgt == SEG) { /* */ /* SEG-SEG: line bisector */ /* */ GetSegEqnData(rgt, &a2, &b2, &c2); if (PntLineDist(a2, b2, c2, p1) >= 0.0) { s2 = true; if (s1) cosine = a1 * a2 + b1 * b2; else cosine = - a1 * a2 - b1 * b2; } else { s2 = false; if (s1) cosine = - a1 * a2 - b1 * b2; else cosine = a1 * a2 + b1 * b2; } for (t = t1; t < t3; t += delta) { if (t > t2) t = t2; EvaluateLineData(i, t, &p2); ComputeContact(s1, q1, p2, a1, b1, t); ComputeContact(s2, q2, p2, a2, b2, t); dist = PntPntDistSq(q1, q2); WmatErrorCheck(dist, wmat_dist_sq, ZERO, wmat_cosine, cosine, i, t, r1, r2); } } else if (t_rgt == PNT) { /* */ /* SEG-PNT: parabola bisector */ /* */ assert(!(IsSegStartPnt(lft, rgt) || IsSegEndPnt(lft, rgt))); q2 = GetPntCoords(rgt); for (t = t1; t < t3; t += delta) { if (t > t2) t = t2; EvaluateParabolaData(i, lft, t, &p2); ComputeContact(s1, q1, p2, a1, b1, t); dist = PntPntDistSq(q1, q2); u2 = VecSub(p2, q2); if (s1) cosine = a1 * u2.x + b1 * u2.y; else cosine = - a1 * u2.x - b1 * u2.y; if (eq(t, TINY)) cosine = 1.0; else cosine /= t; WmatErrorCheck(dist, wmat_dist_sq, ZERO, wmat_cosine, cosine, i, t, r1, r2); } } else { throw std::runtime_error("VRONI error: CheckWMAT() - cannot handle this site type!"); } } else if (t_lft == PNT) { /* */ /* PNT-PNT: (hyperbola) line bisector */ /* */ q1 = GetPntCoords(lft); q2 = GetPntCoords(rgt); dist = PntPntDistSq(q1, q2); for (t = t1; t < t3; t += delta) { if (t > t2) t = t2; EvaluateHyperbolaData(i, t, &p2); u1 = VecSub(p2, q1); u2 = VecSub(p2, q2); if (eq(t, TINY)) cosine = 1.0; else cosine = VecDotProd(u1, u2) / (t * t); WmatErrorCheck(dist, wmat_dist_sq, ZERO, wmat_cosine, cosine, i, t, r1, r2); } } else { throw std::runtime_error("VRONI error: CheckWMAT() - cannot handle this site type!"); } } } return; } #endif #ifdef WMAT void vroniObject::ComputeWMATParabola(int i, int i1, int i2, double_arg wmat_cosine, double_arg wmat_dist_sq) #else void vroniObject::ComputeWMATParabola(int i, int i1, int i2) #endif { int n1, n2; coord p1, p2, p; double t1, t2, t_min, delta; t_site site2 = PNT; #ifdef WMAT double a1, b1, c1, d, t_max; coord q1, q2; vr_bool s1; #endif assert(InEdgesList(i)); assert(InSegsList(i1)); assert(InPntsList(i2)); #ifdef GENUINE_ARCS GetLftSiteData(i, &n2, &site2); if (site2 == SEG) GetRgtSiteData(i, &n2, &site2); assert((site2 == PNT) || (site2 == ARC)); #endif if ((site2 == PNT) && (IsSegStartPnt(i1, i2) || IsSegEndPnt(i1, i2)) ) { SetWmatEdge(i, false); return; } n1 = GetStartNode(i); n2 = GetEndNode(i); GetNodeData(n1, &p1, &t1); GetNodeData(n2, &p2, &t2); if (t2 < t1) { VroniSwap(t1, t2, t_min); VroniSwap(p1, p2, p); } if (le(t2, ZERO)) { /* degenerate segment */ SetWmatEdge(i, false); return; } #ifdef WMAT GetSegEqnData(i1, &a1, &b1, &c1); q1 = GetPntCoords(i2); d = PntLineDist(a1, b1, c1, q1); if (d < 0.0) { s1 = false; d = -d; } else { s1 = true; } /* */ /* let delta be the distance between p1 and the contact point on the */ /* line segment, for a disk with clearance radius t. we get */ /* delta * delta = 2 * t * d ... yields lower bound for t. */ /* */ if (eq(d, ZERO)) { if (wmat_dist_sq == 0.0) { t_min = 0.0; } else { SetWmatEdge(i, false); return; } } else { t_min = wmat_dist_sq * 0.5 / d; } if (t_min >= t2) { /* distance too small */ SetWmatEdge(i, false); return; } /* */ /* d = t * (1 - cos(wmat_angle)) ... yields upper bound for t. */ /* */ delta = 1 - wmat_cosine; if (eq(delta, TINY)) t_max = DBL_MAX; else t_max = d / delta; t_min = VroniMax(t1, t_min); t_max = VroniMin(t2, t_max); if (t_max <= t_min) { /* angle too small */ SetWmatEdge(i, false); return; } SetWmatRMin(i, t_min); SetWmatRMax(i, t_max); /* */ /* make sure that the parameterization formula is initialized */ /* */ if (GetEdgeDataInit(i)) { CreateParabolaData(i); SetEdgeDataInit(i, false); } /* */ /* compute the contact points */ /* */ if (IsLftSite(i, i1, SEG)) { assert(IsRgtSite(i, i2, PNT)); EvaluateParabolaData(i, i1, t_min, &q1); ComputeContact(s1, p2, q1, a1, b1, t_min); SetWmatLftMnPnt(i, p2); SetWmatRgtMnPnt(i, p1); EvaluateParabolaData(i, i1, t_max, &q2); ComputeContact(s1, p2, q2, a1, b1, t_max); SetWmatLftMxPnt(i, p2); SetWmatRgtMxPnt(i, p1); } else { assert(IsRgtSite(i, i1, SEG)); assert(IsLftSite(i, i2, PNT)); EvaluateParabolaData(i, i2, t_min, &q1); ComputeContact(s1, p2, q1, a1, b1, t_min); SetWmatLftMnPnt(i, p1); SetWmatRgtMnPnt(i, p2); EvaluateParabolaData(i, i2, t_max, &q2); ComputeContact(s1, p2, q2, a1, b1, t_max); SetWmatLftMxPnt(i, p1); SetWmatRgtMxPnt(i, p2); } #endif if (t1 == 0.0) { delta = PntPntDist(p1, p2) - t2; if (gt(delta, ZERO)) { SetWmatEdge(i, true); } else { SetWmatEdge(i, false); } } else { SetWmatEdge(i, true); } return; } #ifdef WMAT void vroniObject::ComputeWMATHyperbola(int i, int i1, int i2, double_arg wmat_cosine, double_arg wmat_dist_sq) #else void vroniObject::ComputeWMATHyperbola(int i) #endif { int n1, n2; double t1, t2, t_max; coord p1, p2, p; double delta; #ifdef WMAT double d_sq; coord q1, q2; #endif assert(InEdgesList(i)); n1 = GetStartNode(i); n2 = GetEndNode(i); GetNodeData(n1, &p1, &t1); GetNodeData(n2, &p2, &t2); if (t2 < t1) { VroniSwap(t1, t2, t_max); VroniSwap(p1, p2, p); } if (le(t2, ZERO)) { /* degenerate segment */ SetWmatEdge(i, false); return; } #ifdef WMAT assert(InPntsList(i1)); assert(InPntsList(i2)); q1 = GetPntCoords(i1); q2 = GetPntCoords(i2); d_sq = PntPntDistSq(q1, q2); if (d_sq <= wmat_dist_sq) { /* distance is too small */ SetWmatEdge(i, false); return; } /* */ /* d_sq = 2 * t * t * (1 - cos(wmat_angle)) ... yields upper bound for t */ /* */ delta = 1 - wmat_cosine; if (eq(delta, TINY)) t_max = DBL_MAX; else t_max = sqrt(0.5 * d_sq / delta); if (t2 < t_max) { SetWmatRMax(i, t2); } else if (t_max <= t1) { SetWmatEdge(i, false); return; } else { SetWmatRMax(i, t_max); } SetWmatRMin(i, t1); /* */ /* store the contact points */ /* */ SetWmatLftMnPnt(i, q1); SetWmatLftMxPnt(i, q1); SetWmatRgtMnPnt(i, q2); SetWmatRgtMxPnt(i, q2); /* */ /* make sure that the parameterization formula is initialized */ /* */ if (GetEdgeDataInit(i)) { CreateHyperbolaData(i); SetEdgeDataInit(i, false); } #endif if (t1 == 0.0) { delta = PntPntDist(p1, p2) - t2; if (gt(delta, ZERO)) { SetWmatEdge(i, true); } else { SetWmatEdge(i, false); } } else { SetWmatEdge(i, true); } return; } #ifdef WMAT void vroniObject::ComputeWMATLine(int i, int i1, int i2, double wmat_cosine, double wmat_dist_sq) #else void vroniObject::ComputeWMATLine(int i) #endif { int n1, n2; double t1, t2, t_min, delta; coord p1, p2, q1; #ifdef WMAT double a1, b1, c1, a2, b2, c2, cosine; coord q2; vr_bool s1, s2; #endif assert(InEdgesList(i)); n1 = GetStartNode(i); n2 = GetEndNode(i); GetNodeData(n1, &p1, &t1); GetNodeData(n2, &p2, &t2); if (t1 <= t2) { q1 = p2; } else { q1 = p1; VroniSwap(t1, t2, t_min); } if (le(t2, ZERO)) { /* degnerate segment */ SetWmatEdge(i, false); return; } #ifdef WMAT assert(InSegsList(i1)); assert(InSegsList(i2)); GetSegEqnData(i1, &a1, &b1, &c1); GetSegEqnData(i2, &a2, &b2, &c2); /* */ /* compute the cosine of the angle between the normals; make sure that */ /* normals point into the correct direction. */ /* */ if (PntLineDist(a1, b1, c1, q1) >= 0.0) { s1 = true; if (PntLineDist(a2, b2, c2, q1) >= 0.0) { s2 = true; cosine = a1 * a2 + b1 * b2; } else { s2 = false; cosine = - a1 * a2 - b1 * b2; } } else { s1 = false; if (PntLineDist(a2, b2, c2, q1) >= 0.0) { s2 = true; cosine = - a1 * a2 - b1 * b2; } else { s2 = false; cosine = a1 * a2 + b1 * b2; } } if (cosine >= wmat_cosine) { /* angle is too small */ SetWmatEdge(i, false); return; } delta = 1 - cosine; if (eq(delta, TINY)) t_min = DBL_MAX; else t_min = sqrt(0.5 * wmat_dist_sq / delta); if (t_min >= t2) { SetWmatEdge(i, false); return; } else { t_min = VroniMax(t1, t_min); SetWmatRMin(i, t_min); } SetWmatRMax(i, t2); /* */ /* make sure that the parameterization formula is initialized */ /* */ if (GetEdgeDataInit(i)) { CreateLineData(i); SetEdgeDataInit(i, false); } /* */ /* compute the contact points */ /* */ assert(IsLftSite(i, i1, SEG)); assert(IsRgtSite(i, i2, SEG)); if (t1 == t2) q1 = p1; else EvaluateLineData(i, t_min, &q1); ComputeContact(s1, p1, q1, a1, b1, t_min); SetWmatLftMnPnt(i, p1); ComputeContact(s2, p2, q1, a2, b2, t_min); SetWmatRgtMnPnt(i, p2); if (t1 == t2) q2 = p2; else EvaluateLineData(i, t2, &q2); ComputeContact(s1, p1, q2, a1, b1, t2); SetWmatLftMxPnt(i, p1); ComputeContact(s2, p2, q2, a2, b2, t2); SetWmatRgtMxPnt(i, p2); #endif if (t1 == 0.0) { delta = PntPntDist(p1, p2) - t2; if (gt(delta, ZERO)) { SetWmatEdge(i, true); } else { SetWmatEdge(i, false); } } else { SetWmatEdge(i, true); } return; } #ifdef WMAT void vroniObject::ComputeWMATEdge(int e, double_arg wmat_cosine, double_arg wmat_dist_sq) #else void vroniObject::ComputeWMATEdge(int e) #endif { int i1, i2; t_site ltype, rtype; assert(InEdgesList(e)); GetLftSiteData(e, &i1, <ype); GetRgtSiteData(e, &i2, &rtype); switch(ltype) { case(PNT): switch(rtype) { case(PNT): /* PNT-PNT: line (hyperbolic) bisector */ #ifdef WMAT ComputeWMATHyperbola(e, i1, i2, wmat_cosine, wmat_dist_sq); #else ComputeWMATHyperbola(e); #endif break; case(SEG): /* PNT-SEG: parabola bisector */ #ifdef WMAT ComputeWMATParabola(e, i2, i1, wmat_cosine, wmat_dist_sq); #else ComputeWMATParabola(e, i2, i1); #endif break; case(ARC): #ifdef GENUINE_ARCS #ifndef WMAT ComputeWMATHyperbola(e); #endif #endif break; default: break; } break; case(SEG): switch(rtype) { case(PNT): /* SEG-PNT: parabola bisector */ #ifdef WMAT ComputeWMATParabola(e, i1, i2, wmat_cosine, wmat_dist_sq); #else ComputeWMATParabola(e, i1, i2); #endif break; case(SEG): /* SEG-SEG: line bisector */ #ifdef WMAT ComputeWMATLine(e, i1, i2, wmat_cosine, wmat_dist_sq); #else ComputeWMATLine(e); #endif break; case(ARC): #ifdef GENUINE_ARCS #ifndef WMAT ComputeWMATParabola(e,i1,i2); #endif #endif break; default: break; } break; case(ARC): #ifdef GENUINE_ARCS #ifndef WMAT switch(rtype) { case(PNT): ComputeWMATHyperbola(e); break; case(SEG): ComputeWMATParabola(e, i2, i1); break; case(ARC): ComputeWMATHyperbola(e); break; default: break; } #endif #endif break; default: break; } return; } void vroniObject::ComputeWMAT(double wmat_angle, double wmat_dist, vr_bool time, vr_bool left_wmat, vr_bool right_wmat) { int i, j, not_needed; vr_bool unrestricted; #ifdef WMAT double wmat_dist_sq, wmat_cosine; #endif assert(GetVDStatus()); assert(scale_factor > 0.0); if (GetNodesSqdFlag()) TakeSquareOfNodes(); if (!GetDeg2Flag()) InsertDegreeTwoNodes(); if (wmat_angle < 0.0) wmat_angle = 0.0; else if(wmat_angle > M_PI) wmat_angle = M_PI; if (wmat_dist < 0.0) wmat_dist = 0.0; #ifdef WMAT wmat_dist = ScaleV(wmat_dist); wmat_dist_sq = wmat_dist * wmat_dist; wmat_cosine = cos(wmat_angle); #endif if (left_wmat && right_wmat) { left_wmat = right_wmat = false; } /* */ /* first call to this function. allocate memory and initialize the */ /* flags for the edge data. */ /* */ #ifdef WMAT #ifdef GENUINE_ARCS if (num_arcs > 0) throw std::runtime_error("VRONI error: ComputeWMAT() - computation of wMAT not supported for circular arcs!"); #endif VD_Info("...computing weighted medial axis -- "); #else VD_Info("...computing medial axis -- "); #endif if (time) cpu_time_wmat = elapsed(); #ifdef GRAPHICS if (graphics) ResetCurBuffer(); #endif unrestricted = !(left_wmat || right_wmat); /* */ /* allocate memory and initialize the flags for the edge data. */ /* */ InitializeEdgeData(unrestricted, left_wmat, false, ¬_needed); /* */ /* let the user call some application-specific function */ /* */ ExtApplFuncWMATInit; j = -1; AdvanceActiveEdge(i, j, false); while (i != NIL) { /* */ /* compute the WMAT-data for this edge */ /* */ #ifdef WMAT ComputeWMATEdge(i, wmat_cosine, wmat_dist_sq); #else ComputeWMATEdge(i); #endif /* */ /* let the user call some application-specific function */ /* */ ExtApplFuncWMATLoop; AdvanceActiveEdge(i, j, false); } if (time) cpu_time_wmat = elapsed(); VD_Info("done!\n"); WMAT_computed = true; /* */ /* let the user call some application-specific function */ /* */ ExtApplFuncWMATComputed; #ifdef GRAPHICS if (graphics) { AddWMATToBuffer(); } #endif #ifdef WMAT #ifndef NDEBUG CheckWMAT(wmat_dist, wmat_angle); #endif #endif /* */ /* let the user call some application-specific function */ /* */ ExtApplFuncWMATDone; return; } /* */ /* this function adds the edges of the wMAT to VRONI's graphics buffer for */ /* subsequent graphics display. please note that all conic VD edges are */ /* approximated by straight-line segments relative to a heuristically chosen */ /* approximation threshold prior to output! */ /* */ #ifdef GRAPHICS void vroniObject::AddWMATToBuffer(void) { double delta_x, delta_y, delta; ///void SetStepSize(double_arg delta); t_site t_lft, t_rgt; int num_edges, i, lft, rgt; coord u, v; #ifdef WMAT double t1, t2; #else double t1, t2, t; int n1, n2; coord dummy; #endif num_edges = GetNumberOfEdges(); /* */ /* compute the discretization threshold for approximating non-linear */ /* bisectors. */ /* */ delta_x = bb_max.x - bb_min.x; delta_y = bb_max.y - bb_min.y; delta = VroniMax(delta_x, delta_y); if (le(delta, ZERO)) delta = ZERO; SetStepSize(delta); for (i = 4; i < num_edges; ++i) { if (IsWmatEdge(i)) { #ifdef WMAT t1 = GetWmatRMin(i); t2 = GetWmatRMax(i); #else n1 = GetStartNode(i); n2 = GetEndNode(i); GetNodeData(n1, &u, &t1); GetNodeData(n2, &v, &t2); if (t2 < t1) { VroniSwap(t1, t2, t); VroniSwap(u, v, dummy); } #endif GetLftSiteData(i, &lft, &t_lft); GetRgtSiteData(i, &rgt, &t_rgt); switch(t_lft) { case(PNT): switch(t_rgt) { case(PNT): /* PNT-PNT: line (hyperbola) bisector */ #ifdef WMAT EvaluateHyperbolaData(i, t1, &u); EvaluateHyperbolaData(i, t2, &v); #endif AddEdgeToBuffer(u.x, u.y, v.x, v.y, WMATColor); break; case(SEG): /* PNT-SEG: parabola bisector */ #ifdef WMAT if (IsSegStartPnt(rgt, lft) || IsSegEndPnt(rgt, lft)) { EvaluateLineData(i, t1, &u); EvaluateLineData(i, t2, &v); } else { EvaluateParabolaData(i, rgt, t1, &u); EvaluateParabolaData(i, rgt, t2, &v); } #endif AddParabolaToBuffer(i, t1, t2, u, v, WMATColor); break; case(ARC): #ifdef GENUINE_ARCS AddHyperbolaEllipseToBuffer(i, t1, t2, u, v, WMATColor); #endif break; default: break; } break; case(SEG): switch(t_rgt) { case(PNT): /* SEG-PNT: parabola bisector */ #ifdef WMAT if (IsSegStartPnt(lft, rgt) || IsSegEndPnt(lft, rgt)) { EvaluateLineData(i, t1, &u); EvaluateLineData(i, t2, &v); } else { EvaluateParabolaData(i, lft, t1, &u); EvaluateParabolaData(i, lft, t2, &v); } #endif AddParabolaToBuffer(i, t1, t2, u, v, WMATColor); break; case(SEG): /* SEG-SEG: line bisector */ #ifdef WMAT if (GetEdgeFlagDeg(i)) { GetNodeData(GetStartNode(i), &u, &t1); GetNodeData(GetEndNode(i), &v, &t2); } else { EvaluateLineData(i, t1, &u); EvaluateLineData(i, t2, &v); } #endif AddEdgeToBuffer(u.x, u.y, v.x, v.y, WMATColor); break; case(ARC): #ifdef GENUINE_ARCS AddParabolaToBuffer(i, t1, t2, u, v, WMATColor); #endif break; default: break; } break; case(ARC): #ifdef GENUINE_ARCS switch(t_rgt) { case(PNT): #ifdef WMAT if (IsArcStartPnt(lft, rgt) || IsArcEndPnt(lft, rgt)) { EvaluateLineData(i, t1, &u); EvaluateLineData(i, t2, &v); } else { EvaluateParabolaData(i, lft, t1, &u); EvaluateParabolaData(i, lft, t2, &v); } #endif AddHyperbolaEllipseToBuffer(i, t1, t2, u, v, WMATColor); break; case(SEG): #ifdef WMAT if (GetEdgeFlagDeg(i)) { GetNodeData(GetStartNode(i), &u, &t1); GetNodeData(GetEndNode(i), &v, &t2); } else { EvaluateLineData(i, t1, &u); EvaluateLineData(i, t2, &v); } #endif AddParabolaToBuffer(i, t1, t2, u, v, WMATColor); break; case(ARC): AddHyperbolaEllipseToBuffer(i, t1, t2, u, v, WMATColor); break; default: break; } #endif break; default: break; } } } return; } #endif #ifdef EXT_APPL_WMAT eam_type vroniObject::GetExtApplWMAT(int E) { assert(InEdgesList(E)); return edges[E].w_mat.ext_appl; } void vroniObject::SetExtApplWMAT(int E, eam_type ext_appl) { assert(InEdgesList(E)); edges[E].w_mat.ext_appl = ext_appl; return; } #endif #include "ext_appl_wmat.cc" #endif