// Return orientation of the polygon by checking orientation of the left bottom corner of the polygon // using exact arithmetics. The input polygon must not contain duplicate points // (or at least the left bottom corner point must not have duplicates). static inline bool is_ccw(const Polygon &poly) { // The polygon shall be at least a triangle. assert(poly.points.size() >= 3); if (poly.points.size() < 3) return true; // 1) Find the lowest lexicographical point. unsigned int imin = 0; for (unsigned int i = 1; i < poly.points.size(); ++ i) { const Point &pmin = poly.points[imin]; const Point &p = poly.points[i]; if (p(0) < pmin(0) || (p(0) == pmin(0) && p(1) < pmin(1))) imin = i; } // 2) Detect the orientation of the corner imin. size_t iPrev = ((imin == 0) ? poly.points.size() : imin) - 1; size_t iNext = ((imin + 1 == poly.points.size()) ? 0 : imin + 1); Orientation o = orient(poly.points[iPrev], poly.points[imin], poly.points[iNext]); // The lowest bottom point must not be collinear if the polygon does not contain duplicate points // or overlapping segments. assert(o != ORIENTATION_COLINEAR); return o == ORIENTATION_CCW; }
// hmmm... copied from PPlot.cpp void PZoomInteraction::DoZoomIn (float inX1, float inX2, float inY1, float inY2) { if (!CheckRange (inX1, inX2)) { return; } if (!CheckRange (inY1, inY2)) { return; } // also use the following criterium that is used in PPlot::CalculateTickInfo to // avoid strange zoom in / zoom out behaviour float theYRange = fabs (inY1 - inY2); float theYMax = (inY1 > inY2) ? inY1 : inY2; if (fabs (theYRange / theYMax) < PPlot::kRangeVerySmall) { return; } StoreCurrentAxisSetup (); if (mZoomHistory.size()==1) mOriginalAxis = mZoomHistory.top(); if (IsZoomRegion () || IsZoomX ()) { mPPlot.mXAxisSetup.SetAutoScale (false); mPPlot.mXAxisSetup.mMin = pmin (inX1, inX2); mPPlot.mXAxisSetup.mMax = pmax (inX1, inX2); } if (IsZoomRegion () || IsZoomY ()) { mPPlot.mYAxisSetup.SetAutoScale (false); mPPlot.mYAxisSetup.mMin = pmin (inY1, inY2); mPPlot.mYAxisSetup.mMax = pmax (inY1, inY2); } mLastZoomIn = true; return; }
/*! \file \brief To display non Fary drawings */ void DrawPolrec(QPainter *p,pigalePaint *paint) {TopologicalGraph G(paint->GCP); Prop1<tstring> title(G.Set(),PROP_TITRE); Prop1<Tpoint> pmin(G.Set(),PROP_POINT_MIN); Prop<Tpoint> p1(G.Set(tvertex()),PROP_DRAW_POINT_1); Prop<Tpoint> p2(G.Set(tvertex()),PROP_DRAW_POINT_2); Prop<double> x1(G.Set(tedge()),PROP_DRAW_DBLE_1 ); Prop<double> x2(G.Set(tedge()),PROP_DRAW_DBLE_2 ); Prop<double> y1(G.Set(tedge()),PROP_DRAW_DBLE_3 ); Prop<double> y2(G.Set(tedge()),PROP_DRAW_DBLE_4); Prop<double> y(G.Set(tedge()),PROP_DRAW_DBLE_5); Prop<short> ecolor(G.Set(tedge()),PROP_COLOR); Prop<short> vcolor(G.Set(tvertex()),PROP_COLOR); Prop<bool> isTree(G.Set(tedge()),PROP_ISTREE); Prop<int> elabel(G.Set(tedge()),PROP_LABEL); Prop<int> ewidth(G.Set(tedge()),PROP_WIDTH); bool drawTextEdges = (G.ne() < 100); QString stitle(~title()); if(drawTextEdges)paint->DrawText(p,pmin().x(),pmin().y(),stitle); // draw vertices for(tvertex v = 1;v <= G.nv();v++) {double dx = (p2[v].x() - p1[v].x()) ; double x = p1[v].x() ; double y = p1[v].y(); paint->DrawText(p,x,y, dx,1.,v,vcolor[v]); } // draw edges Tpoint e1,e2,e3,e4; for(tedge e = 1;e <= G.ne();e++) {if(isTree[e]) {e1 = Tpoint(x1[e],y1[e]); e2 = Tpoint(x1[e],y2[e]); paint->DrawSeg(p,e1,e2,ecolor[e],ewidth[e]); } else // cotree edges (x1,y1) -> (x1,y) -> (x2,y) -> (x2,y2) {e1 = Tpoint(x1[e],y1[e]); e2 = Tpoint(x1[e],y[e]); e3 = Tpoint(x2[e],y[e]); e4 = Tpoint(x2[e],y2[e]); paint->DrawSeg(p,e1,e2,ecolor[e],ewidth[e]); paint->DrawSeg(p,e2,e3,ecolor[e],ewidth[e]); paint->DrawSeg(p,e3,e4,ecolor[e],ewidth[e]); if(drawTextEdges) {QString label=QString("%1").arg(elabel[e]); // text is drawn at position of lower edge occu paint->DrawText(p,x1[e],y[e],label); } } } }
//********************************************************************************************************************** vector<string> MGClusterCommand::setParameters(){ try { CommandParameter pblast("blast", "InputTypes", "", "", "none", "none", "none",false,true); parameters.push_back(pblast); CommandParameter pname("name", "InputTypes", "", "", "none", "none", "none",false,false); parameters.push_back(pname); CommandParameter plength("length", "Number", "", "5", "", "", "",false,false); parameters.push_back(plength); CommandParameter ppenalty("penalty", "Number", "", "0.10", "", "", "",false,false); parameters.push_back(ppenalty); CommandParameter pcutoff("cutoff", "Number", "", "0.70", "", "", "",false,false); parameters.push_back(pcutoff); CommandParameter pprecision("precision", "Number", "", "100", "", "", "",false,false); parameters.push_back(pprecision); CommandParameter pmethod("method", "Multiple", "furthest-nearest-average", "average", "", "", "",false,false); parameters.push_back(pmethod); CommandParameter phard("hard", "Boolean", "", "T", "", "", "",false,false); parameters.push_back(phard); CommandParameter pmin("min", "Boolean", "", "T", "", "", "",false,false); parameters.push_back(pmin); CommandParameter pmerge("merge", "Boolean", "", "T", "", "", "",false,false); parameters.push_back(pmerge); CommandParameter phcluster("hcluster", "Boolean", "", "F", "", "", "",false,false); parameters.push_back(phcluster); CommandParameter pinputdir("inputdir", "String", "", "", "", "", "",false,false); parameters.push_back(pinputdir); CommandParameter poutputdir("outputdir", "String", "", "", "", "", "",false,false); parameters.push_back(poutputdir); vector<string> myArray; for (int i = 0; i < parameters.size(); i++) { myArray.push_back(parameters[i].name); } return myArray; } catch(exception& e) { m->errorOut(e, "MGClusterCommand", "setParameters"); exit(1); } }
void main() { const vec4 bg = vec4(0.5,0.5,0.5,1.0); // use the secant method on this interval const float d = length(C); // These are pretty well fine-tuned for the torus, but they work well enough // for the sphere too. If I had more time I could probably get rid of the // discontinuities in the transition. float t = pmin( secant_method(d - 1.2, d - 1.19, 1e-13), secant_method(d + 1.1, d + 1.0, 1e-13) ); if (t < 0.0) { gl_FragColor = bg; } else { vec3 P = C + t * D; // point of intersection vec3 N = surfaceN(P, t, 0.01); vec3 L = normalize(vec3(3.0, 4.0, 5.0)); float c = clamp(dot(N,L),0.0,1.0); //gl_FragColor = vec4(clamp(N,0.0,1.0),1.0); gl_FragColor = vec4(c,c,c,1.0); } }
CSGeometry* NGInterface::loadCSG(string data) { strstream in; CSGeometry *geom; Point<3> pmin(minX,minY,minZ), pmax(maxX,maxY,maxZ); Box<3> box(pmin,pmax); in << data; try { geom = ParseCSG(in); } catch(...) { cerr << "Problem in CSG-file!" << endl; return NULL; } if (!geom) { cout << "geo-file should start with 'algebraic3d'" << endl; return NULL; } else geom->FindIdenticSurfaces(1e-8*geom->MaxSize()); geom->SetBoundingBox(box); geom->CalcTriangleApproximation(detail,facets); return (CSGeometry*)(geometry = geom); }
Position* RobotMemory::find(int type) { Position pmin(0,0); Position pmax(0,0); pmin.x = owner->getPosition()->x; pmin.y = owner->getPosition()->y; pmax.x = pmin.x; pmax.y = pmin.y; while((pmin.x > 0) || (pmin.y > 0) || (pmax.x < columns) || (pmax.y < rows)) { pmin.x --; pmin.y --; pmax.x ++; pmax.y ++; for(int i=pmin.x; i<=pmax.x; i++) for(int j=pmin.y; j<=pmax.y; j++) if (!((i < 0) || (i >= columns) || (j < 0) || (j >= rows))) if(map[i][j] == type) { TRACE("ZNALEZIONO OBIEKT. XY = %d %d \n",i,j); return new Position(i,j); } } return new Position(-1,-1); }
/// @brief OBB merge method when the centers of two smaller OBB are close inline OBB merge_smalldist(const OBB& b1, const OBB& b2) { OBB b; b.To = (b1.To + b2.To) * 0.5; Quaternion3f q0, q1; q0.fromAxes(b1.axis); q1.fromAxes(b2.axis); if(q0.dot(q1) < 0) q1 = -q1; Quaternion3f q = q0 + q1; FCL_REAL inv_length = 1.0 / std::sqrt(q.dot(q)); q = q * inv_length; q.toAxes(b.axis); Vec3f vertex[8], diff; FCL_REAL real_max = std::numeric_limits<FCL_REAL>::max(); Vec3f pmin(real_max, real_max, real_max); Vec3f pmax(-real_max, -real_max, -real_max); computeVertices(b1, vertex); for(int i = 0; i < 8; ++i) { diff = vertex[i] - b.To; for(int j = 0; j < 3; ++j) { FCL_REAL dot = diff.dot(b.axis[j]); if(dot > pmax[j]) pmax[j] = dot; else if(dot < pmin[j]) pmin[j] = dot; } } computeVertices(b2, vertex); for(int i = 0; i < 8; ++i) { diff = vertex[i] - b.To; for(int j = 0; j < 3; ++j) { FCL_REAL dot = diff.dot(b.axis[j]); if(dot > pmax[j]) pmax[j] = dot; else if(dot < pmin[j]) pmin[j] = dot; } } for(int j = 0; j < 3; ++j) { b.To += (b.axis[j] * (0.5 * (pmax[j] + pmin[j]))); b.extent[j] = 0.5 * (pmax[j] - pmin[j]); } return b; }
void MAPOBJECT::PaintSelected() { if(!m_selected || m_pDevice == NULL)return; BBOX bbox = GetBoundingBox(); //Bounding box in world space // Create 8 points according to the corners of the bounding box D3DXVECTOR3 corners[] = {D3DXVECTOR3(bbox.max.x, bbox.max.y, bbox.max.z), D3DXVECTOR3(bbox.max.x, bbox.max.y, bbox.min.z), D3DXVECTOR3(bbox.max.x, bbox.min.y, bbox.max.z), D3DXVECTOR3(bbox.max.x, bbox.min.y, bbox.min.z), D3DXVECTOR3(bbox.min.x, bbox.max.y, bbox.max.z), D3DXVECTOR3(bbox.min.x, bbox.max.y, bbox.min.z), D3DXVECTOR3(bbox.min.x, bbox.min.y, bbox.max.z), D3DXVECTOR3(bbox.min.x, bbox.min.y, bbox.min.z)}; // Find the max and min points of these // 8 offests points in screen space INTPOINT pmax(-10000, -10000), pmin(10000,10000); for(int i=0;i<8;i++) { INTPOINT screenPos = GetScreenPos(corners[i], m_pDevice); if(screenPos.x > pmax.x)pmax.x = screenPos.x; if(screenPos.y > pmax.y)pmax.y = screenPos.y; if(screenPos.x < pmin.x)pmin.x = screenPos.x; if(screenPos.y < pmin.y)pmin.y = screenPos.y; } RECT scr = {-20, -20, 820, 620}; // Check that the max and min point is within our viewport boundaries if(pmax.inRect(scr) || pmin.inRect(scr)) { float s = (pmax.x - pmin.x) / 3.0f; if((pmax.y - pmin.y) < (pmax.x - pmin.x))s = (pmax.y - pmin.y) / 3.0f; D3DXVECTOR2 corner1[] = {D3DXVECTOR2((float)pmin.x, (float)pmin.y + s), D3DXVECTOR2((float)pmin.x, (float)pmin.y), D3DXVECTOR2((float)pmin.x + s, (float)pmin.y)}; D3DXVECTOR2 corner2[] = {D3DXVECTOR2((float)pmax.x - s, (float)pmin.y), D3DXVECTOR2((float)pmax.x, (float)pmin.y), D3DXVECTOR2((float)pmax.x, (float)pmin.y + s)}; D3DXVECTOR2 corner3[] = {D3DXVECTOR2((float)pmax.x, (float)pmax.y - s), D3DXVECTOR2((float)pmax.x, (float)pmax.y), D3DXVECTOR2((float)pmax.x - s, (float)pmax.y)}; D3DXVECTOR2 corner4[] = {D3DXVECTOR2((float)pmin.x + s, (float)pmax.y), D3DXVECTOR2((float)pmin.x, (float)pmax.y), D3DXVECTOR2((float)pmin.x, (float)pmax.y - s)}; //Draw the 4 corners if(line != NULL) { line->SetWidth(2.0f); line->Begin(); line->Draw(corner1, 3, 0xffffffff); line->Draw(corner2, 3, 0xffffffff); line->Draw(corner3, 3, 0xffffffff); line->Draw(corner4, 3, 0xffffffff); line->End(); } } }
void pigalePaint::update(int i,bool newDrawing) {zoom = 1; index = i; if(newDrawing) // copy the graph GCP = mw->GC; TopologicalGraph G(GCP); Prop1<Tpoint> pmin(G.Set(),PROP_POINT_MIN); Prop1<Tpoint> pmax(G.Set(),PROP_POINT_MAX); xmin = pmin().x(); ymin = pmin().y(); xmax = pmax().x(); ymax = pmax().y(); Wx_max = this->width() - 2*border; Wy_max = this->height() - 2*border; xscale0 = xscale = Wx_max/(xmax - xmin); xtr0 = xtr = - xmin*xscale + border; yscale0 = yscale = Wy_max/(ymax - ymin); ytr0 = ytr = - ymin*yscale +border; mw->tabWidget->setTabText(mw->tabWidget->indexOf(this) ,qApp->translate("pigalePaint",DrawFunctions[index].name)); mw->tabWidget->setCurrentIndex(mw->tabWidget->indexOf(this)); }
void begin_memory_iteration_on_page(gc_heap* heap, gc_page* page, gc_memory_iterator* itr, os_pointer start, os_pointer end) { os_pointer page_base = pointer_for_page(heap, page); os_pointer page_limit = page_base + GC_PAGE_SIZE; itr->current_point = por(start, pointer_for_page(heap, page)); itr->limit_point = por(pmin(end, page_limit), page_limit); itr->current_page = page; }
void begin_bit_run_iteration_on_page(gc_heap* heap, gc_bit_table* table, gc_bit_run_iterator* itr, os_pointer start, os_pointer end) { gc_page* page = page_for_pointer(heap, start); os_pointer base = pointer_for_page(heap, page); os_pointer limit = end ? pmin(base + GC_PAGE_SIZE, end) : base + GC_PAGE_SIZE; long start_idx = bytes_to_words(start - heap->heap_memory); long limit_idx = bytes_to_words(limit - heap->heap_memory); begin_run_iteration(table, itr, start_idx, limit_idx); }
// arguments allow us to zoom out in X direction but change the Y-axis void PZoomInteraction::DoZoomOut (float inY1, float inY2) { if (mZoomHistory.size () == 0) { return; } PAxisInfo theInfo = mZoomHistory.top (); mZoomHistory.pop (); mPPlot.mXAxisSetup = theInfo.mXAxisSetup; if (inY1 != -1) { mPPlot.mYAxisSetup.mMin = pmin (inY1, inY2); mPPlot.mYAxisSetup.mMax = pmax (inY1, inY2); } else { mPPlot.mYAxisSetup = theInfo.mYAxisSetup; } mLastZoomIn = false; }
void DrawTriangle(QPainter *p,pigalePaint *paint) {TopologicalGraph G(paint->GCP); Prop1<Tpoint> pmin(G.Set(),PROP_POINT_MIN); Prop1<Tpoint> pmax(G.Set(),PROP_POINT_MAX); Prop<Tpoint> pleft(G.Set(tvertex()),PROP_DRAW_POINT_1); Prop<Tpoint> pright(G.Set(tvertex()),PROP_DRAW_POINT_2); Prop<Tpoint> ptop(G.Set(tvertex()),PROP_DRAW_POINT_3); Prop<short> vcolor(G.Set(tvertex()),PROP_COLOR); p->setFont(QFont("sans",Min((int)(Min(paint->xscale,paint->yscale) + .5),13))); for(tvertex iv = 1; iv <= G.nv();iv++) {paint->DrawTriangle(p,pleft[iv],pright[iv],ptop[iv],vcolor[iv]); Tpoint center = (pleft[iv]+pright[iv]+ptop[iv])/3.; paint->DrawText(p,center,iv,vcolor[iv],1); } }
Box3<Real> ContOrientedBox (int numPoints, const Vector3<Real>* points) { Box3<Real> box = GaussPointsFit3<Real>(numPoints, points); // Let C be the box center and let U0, U1, and U2 be the box axes. Each // input point is of the form X = C + y0*U0 + y1*U1 + y2*U2. The // following code computes min(y0), max(y0), min(y1), max(y1), min(y2), // and max(y2). The box center is then adjusted to be // C' = C + 0.5*(min(y0)+max(y0))*U0 + 0.5*(min(y1)+max(y1))*U1 + // 0.5*(min(y2)+max(y2))*U2 Vector3<Real> diff = points[0] - box.Center; Vector3<Real> pmin(diff.Dot(box.Axis[0]), diff.Dot(box.Axis[1]), diff.Dot(box.Axis[2])); Vector3<Real> pmax = pmin; for (int i = 1; i < numPoints; ++i) { diff = points[i] - box.Center; for (int j = 0; j < 3; ++j) { Real dot = diff.Dot(box.Axis[j]); if (dot < pmin[j]) { pmin[j] = dot; } else if (dot > pmax[j]) { pmax[j] = dot; } } } box.Center += (((Real)0.5)*(pmin[0] + pmax[0]))*box.Axis[0] + (((Real)0.5)*(pmin[1] + pmax[1]))*box.Axis[1] + (((Real)0.5)*(pmin[2] + pmax[2]))*box.Axis[2]; box.Extent[0] = ((Real)0.5)*(pmax[0] - pmin[0]); box.Extent[1] = ((Real)0.5)*(pmax[1] - pmin[1]); box.Extent[2] = ((Real)0.5)*(pmax[2] - pmin[2]); return box; }
Position RobotMemory::minCell(Position p) { Position temp(0,0); Position pmin(p.x,p.y); temp.x = p.x + 1; temp.y = p.y; if(checkPosition(temp)) if ((map2[temp.x][temp.y] < map2[pmin.x][pmin.y]) && (map2[temp.x][temp.y] != -1)) { pmin.x = temp.x; pmin.y = temp.y; } temp.x = p.x - 1; temp.y = p.y; if(checkPosition(temp)) if ((map2[temp.x][temp.y] < map2[pmin.x][pmin.y]) && (map2[temp.x][temp.y] != -1)) { pmin.x = temp.x; pmin.y = temp.y; } temp.x = p.x; temp.y = p.y + 1; if(checkPosition(temp)) if ((map2[temp.x][temp.y] < map2[pmin.x][pmin.y]) && (map2[temp.x][temp.y] != -1)) { pmin.x = temp.x; pmin.y = temp.y; } temp.x = p.x; temp.y = p.y - 1; if(checkPosition(temp)) if ((map2[temp.x][temp.y] < map2[pmin.x][pmin.y]) && (map2[temp.x][temp.y] != -1)) { pmin.x = temp.x; pmin.y = temp.y; } return pmin; }
void OrthoBrick :: Reduce (const BoxSphere<3> & box) { surfaceactive.Elem(1) = (box.PMin()(2) < pmin(2)) && (pmin(2) < box.PMax()(2)); surfaceactive.Elem(2) = (box.PMin()(2) < pmax(2)) && (pmax(2) < box.PMax()(2)); surfaceactive.Elem(3) = (box.PMin()(1) < pmin(1)) && (pmin(1) < box.PMax()(1)); surfaceactive.Elem(4) = (box.PMin()(1) < pmax(1)) && (pmax(1) < box.PMax()(1)); surfaceactive.Elem(5) = (box.PMin()(0) < pmin(0)) && (pmin(0) < box.PMax()(0)); surfaceactive.Elem(6) = (box.PMin()(0) < pmax(0)) && (pmax(0) < box.PMax()(0)); }
INSOLID_TYPE OrthoBrick :: BoxInSolid (const BoxSphere<3> & box) const { if (pmin(0) > box.PMax()(0) || pmin(1) > box.PMax()(1) || pmin(2) > box.PMax()(2) || pmax(0) < box.PMin()(0) || pmax(1) < box.PMin()(1) || pmax(2) < box.PMin()(2)) return IS_OUTSIDE; if (pmin(0) < box.PMin()(0) && pmin(1) < box.PMin()(1) && pmin(2) < box.PMin()(2) && pmax(0) > box.PMax()(0) && pmax(1) > box.PMax()(1) && pmax(2) > box.PMax()(2)) return IS_INSIDE; return DOES_INTERSECT; }
int lmder(custom_funcmult *funcmult, custom_jacobian *jacobian, double *x, int M, int N, double *fvec,double *fjac,int ldfjac,int maxfev,double *diag,int mode,double factor,int nprint, double eps,double ftol,double gtol,double xtol,int *nfev,int *njev,int *ipvt, double *qtf) { int info; int i,j,l,iter; double actred,delta,dirder,epsmch,fnorm,fnorm1,gnorm,one,par,pnorm,prered,p1,p5,p25,p75,p0001,ratio, sum,temp,temp1,temp2,xnorm,zero; double *wa1,*wa2,*wa3,*wa4; /* * * This routine is a C translation of Fortran Code by * argonne national laboratory. minpack project. march 1980. burton s. garbow, kenneth e. hillstrom, jorge j. more * M is a positive integer input variable set to the number c of functions. c c N is a positive integer input variable set to the number c of variables. N must not exceed M. c c x is an array of length N. on input x must contain c an initial estimate of the solution vector. on output x c contains the final estimate of the solution vector. c c fvec is an output array of length M which contains c the functions evaluated at the output x. c c fjac is an output M by N array. the upper N by N submatrix c of fjac contains an upper triangular matrix r with c diagonal elements of nonincreasing magnitude such that c c t t t c p *(jac *jac)*p = r *r, c c where p is a permutation matrix and jac is the final c calculated jacobian. column j of p is column ipvt(j) c (see below) of the identity matrix. the lower trapezoidal c part of fjac contains information generated during c the computation of r. c c ldfjac is a positive integer input variable not less than M c which specifies the leading dimension of the array fjac. c c ftol is a nonnegative input variable. termination c occurs when both the actual and predicted relative c reductions in the sum of squares are at most ftol. c therefore, ftol measures the relative error desired c in the sum of squares. c c xtol is a nonnegative input variable. termination c occurs when the relative error between two consecutive c iterates is at most xtol. therefore, xtol measures the c relative error desired in the approximate solution. c c gtol is a nonnegative input variable. termination c occurs when the cosine of the angle between fvec and c any column of the jacobian is at most gtol in absolute c value. therefore, gtol measures the orthogonality c desired between the function vector and the columns c of the jacobian. c c maxfev is a positive integer input variable. termination c occurs when the number of calls to fcn with iflag = 1 c has reached maxfev. c c diag is an array of length N. if mode = 1 (see c below), diag is internally set. if mode = 2, diag c must contain positive entries that serve as c multiplicative scale factors for the variables. c c mode is an integer input variable. if mode = 1, the c variables will be scaled internally. if mode = 2, c the scaling is specified by the input diag. other c values of mode are equivalent to mode = 1. c c factor is a positive input variable used in determining the c initial step bound. this bound is set to the product of c factor and the euclidean norm of diag*x if nonzero, or else c to factor itself. in most cases factor should lie in the c interval (.1,100.).100. is a generally recommended value. c c nprint is an integer input variable that enables controlled c printing of iterates if it is positive. in this case, c fcn is called with iflag = 0 at the beginning of the first c iteration and every nprint iterations thereafter and c immediately prior to return, with x, fvec, and fjac c available for printing. fvec and fjac should not be c altered. if nprint is not positive, no special calls c of fcn with iflag = 0 are made. c c info is an integer output variable. if the user has c terminated execution, info is set to the (negative) c value of iflag. see description of fcn. otherwise, c info is set as follows. c c info = 0 improper input parameters. c c info = 1 both actual and predicted relative reductions c in the sum of squares are at most ftol. c c info = 2 relative error between two consecutive iterates c is at most xtol. c c info = 3 conditions for info = 1 and info = 2 both hold. c c info = 4 the cosine of the angle between fvec and any c column of the jacobian is at most gtol in c absolute value. c c info = 5 number of calls to fcn with iflag = 1 has c reached maxfev. c c info = 6 ftol is too small. no further reduction in c the sum of squares is possible. c c info = 7 xtol is too small. no further improvement in c the approximate solution x is possible. c c info = 8 gtol is too small. fvec is orthogonal to the c columns of the jacobian to machine precision. c c nfev is an integer output variable set to the number of c calls to fcn with iflag = 1. c c njev is an integer output variable set to the number of c calls to fcn with iflag = 2. c c ipvt is an integer output array of length N. ipvt c defines a permutation matrix p such that jac*p = q*r, c where jac is the final calculated jacobian, q is c orthogonal (not stored), and r is upper triangular c with diagonal elements of nonincreasing magnitude. c column j of p is column ipvt(j) of the identity matrix. c c qtf is an output array of length N which contains c the first n elements of the vector (q transpose)*fvec. */ wa1 = (double*) malloc(sizeof(double) *N); wa2 = (double*) malloc(sizeof(double) *N); wa3 = (double*) malloc(sizeof(double) *N); wa4 = (double*) malloc(sizeof(double) *M); one = 1.0; zero = 0.0; p1 = 1.0e-1; p5 = 5.0e-1; p25 = 2.5e-1; p75 = 7.5e-1; p0001 = 1.0e-4; epsmch = eps; info = 0; *nfev = 0; *njev = 0; if (N <= 0 || M < N || ldfjac < M || ftol < zero || xtol < zero || gtol < zero || maxfev <= 0 || factor <= zero) { return info; } if (mode == 2) { for(j = 0; j < N; ++j) { if (diag[j] <= 0.0) { return info; } } } // evaluate the function at the starting point // and calculate its norm. FUNCMULT_EVAL(funcmult,x,M,N,fvec); *nfev= 1; fnorm = enorm(fvec,M); // initialize levenberg-marquardt parameter and iteration counter. par = zero; iter = 1; ratio = zero; // beginning of the outer loop. while(1) { // calculate the jacobian matrix. ratio = zero; JACOBIAN_EVAL(jacobian,x,M,N,fjac); *njev = *njev +1; // compute the qr factorization of the jacobian. qrfac(fjac,M,N,ldfjac,1,ipvt,N,wa1,wa2,eps); // on the first iteration and if mode is 1, scale according // to the norms of the columns of the initial jacobian. if (iter == 1) {//80 if (mode != 2) {//60 for(j = 0; j < N; ++j) { diag[j] = wa2[j]; if (wa2[j] == zero) { diag[j] = one; } } }//60 // on the first iteration, calculate the norm of the scaled x // and initialize the step bound delta. for(j = 0; j < N; ++j) { wa3[j] = diag[j]*x[j]; } xnorm = enorm(wa3,N); delta = factor*xnorm; if (delta == zero) { delta = factor; } }//80 // form (q transpose)*fvec and store the first n components in // qtf. for(i = 0; i < M; ++i) { wa4[i] = fvec[i]; } for(j = 0; j < N; ++j) { //130 if (fjac[j*N+j] != zero) {//120 sum = zero; for(i = j; i < M; ++i) { //100 sum = sum + fjac[i*N+j]*wa4[i]; }//100 temp = -sum/fjac[j*N+j]; for(i = j; i < M; ++i) { //110 wa4[i] = wa4[i] + fjac[i*N+j]*temp; }//110 }//120 fjac[j*N+j] = wa1[j]; qtf[j] = wa4[j]; }//130 // compute the norm of the scaled gradient. gnorm = zero; if (fnorm != zero) {//170 for(j = 0; j < N; ++j) { //160 l = ipvt[j]; if (wa2[l] != zero) {//150 sum = zero; for(i = 0; i <= j; ++i) { //140 sum = sum + fjac[i*N+j]*(qtf[i]/fnorm); }//140 gnorm = pmax(gnorm,fabs(sum/wa2[l])); }//150 }//160 }//170 // test for convergence of the gradient norm. if (gnorm <= gtol) { info = 4; } if (info != 0) { break; } // rescale if necessary. if (mode != 2) { //190 for(j = 0; j < N; ++j) { diag[j] = pmax(diag[j],wa2[j]); } }//190 // beginning of the inner loop. while(ratio < p0001) { // determine the levenberg-marquardt parameter. lmpar(fjac,ldfjac,N,ipvt,diag,qtf,delta,&par,wa1,wa2); // store the direction p and x + p. calculate the norm of p. for(j = 0; j < N; ++j) { wa1[j] = -wa1[j]; wa2[j] = x[j] + wa1[j]; wa3[j] = diag[j]*wa1[j]; } pnorm = enorm(wa3,N); // on the first iteration, adjust the initial step bound. if (iter == 1) { delta = pmin(delta,pnorm); } // evaluate the function at x + p and calculate its norm. FUNCMULT_EVAL(funcmult,wa2,M,N,wa4); *nfev = *nfev + 1; fnorm1 = enorm(wa4,M); // compute the scaled actual reduction. actred = -one; if (p1*fnorm1 < fnorm) { actred = one - (fnorm1/fnorm)*(fnorm1/fnorm); } // compute the scaled predicted reduction and // the scaled directional derivative. for(j = 0; j < N; ++j) { wa3[j] = zero; l = ipvt[j]; temp = wa1[l]; for(i = 0; i <= j; ++i) { wa3[i] = wa3[i] + fjac[i*N+j]*temp; } } temp1 = enorm(wa3,N); temp1 = temp1/fnorm; temp2 = (sqrt(par)*pnorm)/fnorm; prered = temp1*temp1 + temp2*temp2/p5; dirder = -(temp1*temp1 + temp2*temp2); // compute the ratio of the actual to the predicted // reduction. ratio = zero; if (prered != zero) { ratio = actred/prered; } // update the step bound. if (ratio <= p25) {//240 if (actred >= zero) { temp = p5; } if (actred < zero) { temp = p5*dirder/(dirder + p5*actred); } if (p1*fnorm1 >= fnorm || temp < p1) { temp = p1; } delta = temp*pmin(delta,pnorm/p1); par = par/temp; } else if (par == zero || ratio >= p75) { //240 - 260 delta = pnorm/p5; par = p5*par; }//260 // test for successful iteration. if (ratio >= p0001) {//290 // successful iteration. update x, fvec, and their norms. for(j = 0; j < N; ++j) { x[j] = wa2[j]; wa2[j] = diag[j]*x[j]; } for(i = 0; i < M; ++i) { fvec[i] = wa4[i]; } xnorm = enorm(wa2,N); fnorm = fnorm1; iter = iter + 1; }//290 // tests for convergence. if ((fabs(actred) <= ftol) && (prered <= ftol) && (p5*ratio <= one)) { info = 1; } if (delta <= xtol*xnorm) { info = 2; } if ((fabs(actred) <= ftol) && (prered <= ftol) && (p5*ratio <= one) && (info == 2)) { info = 3; } if (info != 0) { break; } // tests for termination and stringent tolerances. if (*nfev >= maxfev) { info = 5; } if ((fabs(actred) <= epsmch) && (prered <= epsmch) && (p5*ratio <= one)) { info = 6; } if (delta <= epsmch*xnorm) { info = 7; } if (gnorm <= epsmch) { info = 8; } if (info != 0) { break; } } if (info != 0) { break; } } free(wa1); free(wa2); free(wa3); free(wa4); return info; }
void lmpar(double *r,int ldr,int N,int *ipvt,double *diag,double *qtb,double delta,double *par,double *x,double *sdiag) { int i,iter,j,jm1,jp1,k,l,nsing; double dxnorm,dwarf,fp,gnorm,parc,parl,paru,p1,p001,sum,temp,zero; double *wa1,*wa2; /* * This routine is a C translation of Fortran Code by * argonne national laboratory. minpack project. march 1980. burton s. garbow, kenneth e. hillstrom, jorge j. more * N is a positive integer input variable set to the order of r. r is an N by N array. on input the full upper triangle must contain the full upper triangle of the matrix r. on output the full upper triangle is unaltered, and the strict lower triangle contains the strict upper triangle (transposed) of the upper triangular matrix s. ldr is a positive integer input variable not less than n which specifies the leading dimension of the array r. ipvt is an integer input array of length N which defines the permutation matrix p such that a*p = q*r. column j of p is column ipvt(j) of the identity matrix. diag is an input array of length N which must contain the diagonal elements of the matrix d. qtb is an input array of length N which must contain the first N elements of the vector (q transpose)*b. delta is a positive input variable which specifies an upper bound on the euclidean norm of d*x. par is a nonnegative variable. on input par contains an initial estimate of the levenberg-marquardt parameter. on output par contains the final estimate. x is an output array of length N which contains the least squares solution of the system a*x = b, sqrt(par)*d*x = 0, for the output par. sdiag is an output array of length N which contains the diagonal elements of the upper triangular matrix s. */ wa1 = (double*) malloc(sizeof(double) *N); wa2 = (double*) malloc(sizeof(double) *N); p1 = 1.0e-01; p001 = 1.0e-03; zero = 0.0; dwarf = 2.22507385852e-308; // compute and store in x the gauss-newton direction. if the // jacobian is rank-deficient, obtain a least squares solution. nsing = N; for(j = 1; j <= N; ++j) { wa1[j-1] = qtb[j-1]; if (r[(j-1)*N+j-1] == zero && nsing == N) { nsing = j - 1; } if (nsing < N) { wa1[j-1] = zero; } } if (nsing >= 1) {//50 for(k = 1; k <= nsing; ++k) { j = nsing - k + 1; wa1[j-1] = wa1[j-1]/r[(j-1)*N+j-1]; temp = wa1[j-1]; jm1 = j - 1; if (jm1 >= 1) { for(i = 1; i <= jm1; ++i) { wa1[i-1] = wa1[i-1] - r[(i-1)*N+j-1]*temp; } } } }//50 for (j = 0; j < N; ++j) { l = ipvt[j]; x[l] = wa1[j]; } // initialize the iteration counter. // evaluate the function at the origin, and test // for acceptance of the gauss-newton direction. iter = 0; for(j = 0; j < N; ++j) { wa2[j] = diag[j]*x[j]; } dxnorm = enorm(wa2,N); fp = dxnorm - delta; if (fp > p1*delta) {//220 // if the jacobian is not rank deficient, the newton // step provides a lower bound, parl, for the zero of // the function. otherwise set this bound to zero. parl = zero; if (nsing >= N) { //120 nsing only takes values upto N for(j = 0; j < N; ++j) { l = ipvt[j]; wa1[j] = diag[l]*(wa2[l]/dxnorm); } for(j = 0; j < N; ++j) { //110 sum = zero; jm1 = j - 1; if (jm1 >= 0) {//100 for(i = 0; i <= jm1; ++i) { //check sum = sum + r[i*N+j]*wa1[i]; } }//100 wa1[j] = (wa1[j] - sum)/r[j*N+j]; }//110 temp = enorm(wa1,N); parl = ((fp/delta)/temp)/temp; }//120 // calculate an upper bound, paru, for the zero of the function. for(j = 0; j < N; ++j) { //140 sum = zero; for(i = 0; i <= j; ++i) { //check sum = sum + r[i*N+j]*qtb[i]; } l = ipvt[j]; wa1[j] = sum/diag[l]; }//140 gnorm = enorm(wa1,N); paru = gnorm/delta; if (paru == zero) { paru = dwarf/pmin(delta,p1); } // if the input par lies outside of the interval (parl,paru), // set par to the closer endpoint. *par = pmax(*par,parl); *par = pmin(*par,paru); if (*par == zero) { *par = gnorm/dxnorm; } //Iteration begins while(1) { iter++; // evaluate the function at the current value of par. if (*par == zero) { *par = pmax(dwarf,p001*paru); } temp = sqrt(*par); for(j = 0; j < N; ++j) { wa1[j] = temp*diag[j]; } qrsolv(r,ldr,N,ipvt,wa1,qtb,x,sdiag); for(j = 0; j < N; ++j) { wa2[j] = diag[j]*x[j]; } dxnorm = enorm(wa2,N); temp = fp; fp = dxnorm - delta; // if the function is small enough, accept the current value // of par. also test for the exceptional cases where parl // is zero or the number of iterations has reached 10. if (fabs(fp) <= p1*delta) { break; } if (iter == 10) { break; } if (parl == zero && fp <= temp && temp < zero) { break; } // compute the newton correction. for(j = 0; j < N; ++j) { //180 l = ipvt[j]; wa1[j] = diag[l]*(wa2[l]/dxnorm); }//180 for(j = 0; j < N; ++j) { //210 wa1[j] = wa1[j]/sdiag[j]; temp = wa1[j]; jp1 = j + 1; if (N >= jp1+1) { for(i = jp1; i < N; ++i) { wa1[i] = wa1[i] - r[i*N+j]*temp; } } }//210 temp = enorm(wa1,N); parc = ((fp/delta)/temp)/temp; // depending on the sign of the function, update parl or paru. if (fp > zero) { parl = pmax(parl,*par); } if (fp < zero) { paru = pmin(paru,*par); } // compute an improved estimate for par. *par = pmax(parl,*par+parc); } }//220 if (iter == 0) { *par = zero; } free(wa1); free(wa2); }
bool ofxOBJModel::load(string path) { bHasNormals = false; bHasTexCoords = false; filePath = path; path = ofToDataPath(path, true); string line; for(int i = 0; i < meshes.size(); i++) { delete meshes[i]; } meshes.clear(); ObjMesh *currMesh = NULL; // this is a list of all points // that we can drop after parsing vector<ofPoint> points; vector<ofPoint> normals; vector<ofPoint> texCoords; // obj file format vertexes are 1-indexed points.push_back(ofPoint()); normals.push_back(ofPoint()); texCoords.push_back(ofPoint()); ifstream myfile (path.c_str()); if (myfile.is_open()) { while (! myfile.eof()) { getline (myfile,line); // parse the obj format here. // // the only things we're interested in is // lines beginning with 'g' - this says start of new object // lines beginning with 'v ' - coordinate of a vertex // lines beginning with 'vn ' - vertex normals -- todo // lines beginning with 'vt ' - texcoords (either 2 or 3 values) -- todo // lines beginning with 'f ' - specifies a face of a shape // we take each number before the slash as the index // of the vertex to join up to create a face. if(line.find("g ")==0) { // new object definition currMesh = new ObjMesh(line.substr(2)); meshes.push_back(currMesh); } else if(line.find("v ")==0) { // new vertex points.push_back(parseCoords(line)); } else if(line.find("vn ")==0) { bHasNormals = true; normals.push_back(parseCoords(line)); } else if(line.find("vt ")==0) { bHasTexCoords = true; texCoords.push_back(parseCoords(line)); } else if(line.find("f ")==0) { // face definition if(currMesh!=NULL) { line = line.substr(2); // lop off "f " vector<string> indices = split(line, ' '); // remove any texcoords (/xxx's) ObjFace *face = new ObjFace(); for(int i = 0; i < indices.size(); i++) { vector<string> parts = ofSplitString(indices[i], "/"); // first index is always a point face->points.push_back(points[atoi(parts[0].c_str())]); if(parts.size()==2) { face->texCoords.push_back(texCoords[atoi(parts[1].c_str())]); } else if(parts.size()==3) { face->normals.push_back(normals[atoi(parts[2].c_str())]); if(parts[1]!="") { face->texCoords.push_back(texCoords[atoi(parts[1].c_str())]); } } } currMesh->addFace(face); } } } myfile.close(); //#define NORMALIZE_TEXCOORDS #ifdef NORMALIZE_TEXCOORDS ofPoint pmin(FLT_MAX, FLT_MAX); ofPoint pmax(FLT_MIN, FLT_MIN); for(int i = 0; i < texCoords.size(); i++) { if(texCoords[i].x<pmin.x) pmin.x = texCoords[i].x; if(texCoords[i].y<pmin.y) pmin.y = texCoords[i].y; if(texCoords[i].x>pmax.x) pmax.x = texCoords[i].x; if(texCoords[i].y>pmax.y) pmax.y = texCoords[i].y; } for(int k = 0; k < meshes.size(); k++) for(int i = 0; i < meshes[k]->faces.size(); i++) for(int j = 0; j < meshes[k]->faces[i]->texCoords.size(); j++) { ofPoint p = meshes[k]->faces[i]->texCoords[j]; p.x = ofMap(p.x, pmin.x, pmax.x, 0, 1); p.y = ofMap(p.y, pmin.y, pmax.y, 0, 1); meshes[k]->faces[i]->texCoords[j] = p; } #endif loadVbo(); ofLog(OF_LOG_NOTICE, "Successfully loaded %s\n-----\nVertices: %d\nMeshes: %d\nNormals: %d\nTexCoords: %d\n", path.c_str(), points.size(), meshes.size(), normals.size(), texCoords.size()); return true; } else { ofLog(OF_LOG_ERROR, "Couldn't find the OBJ file %s\n", path.c_str()); return false; } }
int cvsrch(custom_function *funcpt, custom_gradient *funcgrad, double *x, double *f, double *g, double *stp, double *s, int N, double *dx, double maxstep, int MAXITER,double eps2,double ftol, double gtol, double xtol) { int info,i,siter,nfev; int infoc, j, brackt, stage1; double dg, dgm, dginit, dgtest, dgx, dgxm, dgy, dgym, finit, ftest1, fm, fx, fxm, fy, fym, p5, p66, stx, sty, stmin, stmax, width, width1, xtrapf; double nlen,den,rell,stepmin; double *rcheck,*wa; rcheck = (double*)malloc(sizeof(double)*N); wa = (double*)malloc(sizeof(double)*N); nlen = 0.0; p5 = 0.5; p66 = 0.66; xtrapf = 4.0; info = 0; infoc = 1; siter = MAXITER; if (N <= 0 || *stp <= 0.0 || ftol < 0.0 || gtol < 0.0 || xtol < 0.0) { return info; } for (i = 0; i < N; ++i) { nlen += dx[i] * s[i] * dx[i] * s[i]; } nlen = sqrt(nlen); for (i = 0; i < N; ++i) { if (fabs(x[i]) > 1.0 / fabs(dx[i])) { den = fabs(x[i]); } else { den = 1.0 / fabs(dx[i]); } rcheck[i] = s[i] / den; } rell = array_max_abs(rcheck, N); stepmin = ftol / rell; dginit = 0.0; for (j = 0; j < N; ++j) { dginit += g[j] * s[j]; } if (dginit >= 0.0) { return info; } brackt = 0; stage1 = 1; finit = *f; nfev = 0; dgtest = ftol*dginit; width = maxstep - stepmin; width1 = width / 0.5; for (j = 0; j < N; ++j) { wa[j] = x[j]; } /* The variables stx, fx, dgx contain the values of the step, function, and directional derivative at the best step. The variables sty, fy, dgy contain the value of the step, function, and derivative at the other endpoint of the interval of uncertainty. The variables stp, f, dg contain the values of the step, function, and derivative at the current step. */ stx = 0.0; fx = finit; dgx = dginit; sty = 0.0; fy = finit; dgy = dginit; // Iteration while (info == 0) { if (brackt == 1) { stmin = pmin(stx, sty); stmax = pmax(stx, sty); } else { stmin = stx; stmax = *stp + xtrapf*(*stp - stx); } *stp = pmax(*stp, stepmin); *stp = pmin(*stp, maxstep); if ((brackt == 1 && (*stp <= stmin || *stp >= stmax)) || nfev >= siter - 1 || infoc == 0 || (brackt == 1 && (stmax - stmin) <= xtol*stmax)) { *stp = stx; } for (j = 0; j < N; ++j) { x[j] = wa[j] + *stp * s[j]; } *f = FUNCPT_EVAL(funcpt,x, N); if (*f >= DBL_MAX || *f <= -DBL_MAX) { printf("Program Exiting as the function value exceeds the maximum double value"); free(rcheck); free(wa); return 15; } if (*f != *f) { printf("Program Exiting as the function returns NaN"); free(rcheck); free(wa); return 15; } grad_cd(funcpt,funcgrad, x, N, dx, eps2,g); nfev++; dg = 0.0; for (j = 0; j < N; ++j) { dg = dg + g[j]*s[j]; } ftest1 = finit + *stp * dgtest; // Test for convergence. if ((brackt == 1 && (*stp <= stmin || *stp >= stmax)) || infoc == 0) { info = 6; } if (*stp == maxstep && *f <= ftest1 && dg <= dgtest) { info = 5; } if (*stp == stepmin && (*f > ftest1 || dg >= dgtest)) { info = 4; } if (nfev >= siter) { info = 3; } if (brackt == 1 && ((stmax - stmin) <= xtol*stmax)) { info = 2; } if (*f <= ftest1 && fabs(dg) <= gtol*(-dginit)) { info = 1; } if (stage1 == 1 && *f <= ftest1 && dg >= pmin(ftol, gtol)*dginit) { stage1 = 0; } /* A modified function is used to predict the step only if we have not obtained a step for which the modified function has a nonpositive function value and nonnegative derivative, and if a lower function value has been obtained but the decrease is not sufficient. */ if (stage1 == 1 && *f <= fx && *f > ftest1) { fm = *f - *stp*dgtest; fxm = fx - stx*dgtest; fym = fy - sty*dgtest; dgm = dg - dgtest; dgxm = dgx - dgtest; dgym = dgy - dgtest; infoc = cstep(&stx, &fxm, &dgxm, &sty, &fym, &dgym, stp, &fm, &dgm, &brackt, stmin, stmax); fx = fxm + stx*dgtest; fy = fym + sty*dgtest; dgx = dgxm + dgtest; dgy = dgym + dgtest; } else { infoc = cstep(&stx, &fx, &dgx, &sty, &fy, &dgy, stp, f, &dg, &brackt, stmin, stmax); } if (brackt == 1) { if (fabs(sty - stx) >= p66*width1) { *stp = stx + p5*(sty - stx); } width1 = width; width = fabs(sty - stx); } } free(rcheck); free(wa); return info; }
int EmbedVision(TopologicalGraph &G) {int morg = G.ne(); if(!G.CheckConnected())G.MakeConnected(); if(!G.FindPlanarMap()) {Tprintf("Not Planar Graph"); for(tedge e = G.ne(); e > morg; e--) G.DeleteEdge(e); return -1; } if(!G.CheckBiconnected())G.Biconnect(); bool alreadyBipolarOriented = false; bool stConnected = false; tvertex s,t; tbrin bs,bt; bool already2Connected = (morg == G.ne()); if(already2Connected && (alreadyBipolarOriented = CheckBipolarlyOriented(G,s,t,stConnected,bs,true)) == true) {if(stConnected)Tprintf("Using original orientation (s,t are connected)"); else Tprintf("Using original orientation (s,t are not connected)"); bt = -bs; } else {// Find reasonable s t vertices tedge e; tbrin b; int len; G.LongestFace(bs,len); s = G.vin[bs]; bt = bs; for(int i = 1 ;i <= len/2; i++)bt = G.cir[-bt]; t = G.vin[bt]; // Check if s an t are connected b = bs; do {if(G.vin[-b] == t){stConnected = true;break;} }while((b = G.cir[b]) != bs); if(!stConnected) {G.NewEdge(bs,bt); bs = (tbrin)G.ne(); } s = G.vin[bs]; t = G.vin[-bs]; // BipolarOrient the graph G.BipolarPlan(bs); G.FixOrientation(); } int n = G.nv(); int m = G.ne(); // if bs has been reoriented as the packing suppose that vin[bst]= source tbrin bst = (G.vin[bs] != s) ? -bs : bs; // Compute y coords Prop<int> y(G.Set(tvertex()),PROP_DRAW_INT_5); y.clear(); MaxPath *MP=new MaxPath(n,m); for(tedge e = 1; e <= m; e++) MP->insert(G.vin[e.firsttbrin()](),G.vin[e.secondtbrin()](),1); MP->solve(y); delete MP; int maxyval = y[t]; // compute MaxPath for edges svector<int> x(0,m); x.clear(); MP=new MaxPath(m,2*m); svector<tbrin> &Fpbrin = G.ComputeFpbrin(); tbrin b0,b; // out == positif for(int i = 1; i <= Fpbrin.n(); i++) {b0 = Fpbrin[i]; if(b0.out()) while((b=-G.acir[b0]).out()) b0=b; else do {b0=G.cir[-b0];} while(b0.in()); // b0 is the lowest tbrin on the left of the face if(b0 == G.cir[bst])continue; // face exterieure // référence : e tedge e = (G.acir[b0]).GetEdge(); b=b0; while (b.out()) {if(stConnected || b != bst) MP->insert(b.GetEdge()(),e(),1); b=G.cir[-b]; } while (b.GetEdge()!=e) {MP->insert(e(),b.GetEdge()(),0); b=G.cir[-b]; } } MP->solve(x); delete &Fpbrin; delete MP; // computes extremities of vertices Prop<int> x1(G.Set(tvertex()),PROP_DRAW_INT_1); Prop<int> x2(G.Set(tvertex()),PROP_DRAW_INT_2); int maxxval=ComputeExtremities(G,x,x1,x2,morg); Prop1<int> m_org(G.Set(),PROP_TMP); m_org() = morg; for(tedge e = G.ne(); e > morg; e--) G.DeleteEdge(e); Prop1<int> maxx(G.Set(),PROP_DRAW_INT_1); Prop1<int> maxy(G.Set(),PROP_DRAW_INT_2); maxx()=maxxval; maxy()=maxyval; Prop1<Tpoint> pmin(G.Set(),PROP_POINT_MIN); Prop1<Tpoint> pmax(G.Set(),PROP_POINT_MAX); pmin() = Tpoint(-1,-1); pmax() = Tpoint(maxxval+1,maxyval+1); Prop<Tpoint> P1(G.Set(tedge()),PROP_DRAW_POINT_1); Prop<Tpoint> P2(G.Set(tedge()),PROP_DRAW_POINT_2); for (tedge e=1; e<= G.ne(); e++) {P1[e]=Tpoint(x[e],y[G.vin[e.firsttbrin()]]); P2[e]=Tpoint(x[e],y[G.vin[e.secondtbrin()]]); } return 0; }
int EmbedPolyline(TopologicalGraph &G) {if(G.nv() < 3 || G.ne() < 2)return -1; int OldNumEdge = G.ne(); PSet1 propSave(G.Set()); G.MakeConnected(); if(!G.FindPlanarMap() ) {Tprintf("Not Planar Graph"); for(tedge e = G.ne(); e > OldNumEdge; e--) G.DeleteEdge(e); return -1; } tbrin FirstBrin = 1; bool MaxPlanar = (G.ne() != 3 * G.nv() - 6) ? false : true; int len; if(!FirstBrin && !MaxPlanar) G.LongestFace(FirstBrin,len); else if(FirstBrin == 0) {FirstBrin = G.extbrin();FirstBrin = -G.acir[FirstBrin];} if(!MaxPlanar && G.ZigZagTriangulate())return -2; svector<short> ecolor(1, G.ne()); SchnyderDecomp(G,FirstBrin,ecolor); GeometricGraph G0(G); //Compute trees tedge ee; Prop<Tpoint> Ebend(G.Set(tedge()),PROP_DRAW_POINT_3); svector<tbrin> FatherB(1,G.nv(),(tbrin)0); FatherB.SetName("FatherB"); svector<tbrin> FatherG(1,G.nv(),(tbrin)0); FatherG.SetName("FatherG"); svector<tbrin> FatherR(1,G.nv(),(tbrin)0); FatherR.SetName("FatherR"); svector<int> x(1,G.nv(),0), y(1,G.nv(),0); x.clear(); y.clear(); compute_parents(G0, Blue, -FirstBrin, FatherB, ecolor); compute_parents(G0, Red, FirstBrin, FatherR, ecolor); compute_parents(G0, Green, -G0.acir[FirstBrin], FatherG, ecolor); // Compute the number of leaves of each tree int nb_leavesB, nb_leavesR, nb_leavesG; nb_leavesB = nb_leaves(G0, Blue, -FirstBrin, ecolor); nb_leavesR = nb_leaves(G0, Red, FirstBrin, ecolor); nb_leavesG = nb_leaves(G0, Green, -G0.acir[FirstBrin], ecolor); // Compute the coordinates using the tree with the minimum number of leaves ForAllEdges(ee, G) Ebend[ee] = Tpoint(-1,-1); if (nb_leavesB <= nb_leavesR && nb_leavesB <= nb_leavesG) compute_coords(G0,Red,Blue,-FirstBrin,FatherB,FatherR,FatherG,ecolor,x,y,Ebend); else if (nb_leavesR <= nb_leavesG) compute_coords(G0,Green,Red,G0.acir[FirstBrin],FatherR,FatherG,FatherB,ecolor,x,y,Ebend); else compute_coords(G0,Blue,Green,G0.acir[-G0.acir[FirstBrin]],FatherG,FatherB,FatherR,ecolor,x,y,Ebend); // computes extremities of vertices Prop<Tpoint> Epoint1(G.Set(tedge()),PROP_DRAW_POINT_1); Prop<Tpoint> Epoint2(G.Set(tedge()),PROP_DRAW_POINT_2); Prop<Tpoint> Vcoord(G.Set(tvertex()),PROP_DRAW_POINT_1); G.Set() = propSave; Prop1<Tpoint> pmin(G.Set(),PROP_POINT_MIN); Prop1<Tpoint> pmax(G.Set(),PROP_POINT_MAX); tvertex vv; pmin() = Tpoint(0,0); pmax() = Tpoint(0,0); ForAllVertices(vv, G0) {Vcoord[vv] = Tpoint(x[vv], y[vv]); if (Vcoord[vv].x() > pmax().x()) pmax().x() = Vcoord[vv].x(); if (Vcoord[vv].y() > pmax().y()) pmax().y() = Vcoord[vv].y(); }
void DrawBip2Pages(QPainter *p,pigalePaint *paint) {GraphContainer GC = paint->GCP; GeometricGraph G(paint->GCP); Prop<int> h(G.Set(tvertex()),PROP_DRAW_INT_1); Prop<int> h1(G.Set(tvertex()),PROP_DRAW_INT_2); Prop<int> h2(G.Set(tvertex()),PROP_DRAW_INT_3); Prop1<Tpoint> pmax(G.Set(),PROP_POINT_MAX); Prop1<Tpoint> pmin(G.Set(),PROP_POINT_MIN); QPen pn = p->pen();pn.setWidth(1); QPoint ps,pt,ps2,pt2; // horizontale int yh = pmin().y()+ pmax().y()/2; ps = QPoint(paint->to_x(pmin().x()),paint->to_y(yh)); pt = QPoint(paint->to_x(pmax().x()),paint->to_y(yh)); pn.setWidth(1);pn.setColor(color[Grey1]); p->setPen(pn); p->drawLine(ps,pt); pn.setColor(color[Black]); pn.setWidth(1);p->setPen(pn); // draw edges: 2 segments double x1,x2,dh; tvertex vmin,vmax; for(tedge e = 1; e < G.ne();e++) {tvertex v1 = G.vin[e]; tvertex v2 = G.vin[-e]; if(h[v1] <h[v2]) {vmin = v1;vmax = v2;} else {vmin = v2;vmax = v1;} x1 = (double)Min(h[v1],h[v2]); x2 = (double)Max(h[v1],h[v2]); dh = Min((x2-x1)*paint->xscale,(x2-x1)*paint->yscale)/2; QRect r = QRect(paint->to_x(x1),paint->to_y(yh)-dh/2,(int)((x2-x1)*paint->xscale),(int)dh); if(G.vcolor[vmax] == Red) p->drawArc(r,0,180*16); else p->drawArc(r,0,-180*16); } // Draw verticces QBrush pb = p->brush(); pb.setStyle(Qt::SolidPattern); pb.setColor(color[White]); p->setBrush(pb); int dy = Min(10,paint->height()/(pmax().y()+1)-2); QFont font = QFont("sans",dy); p->setFont(font); pn.setWidth(1); for(tvertex v = 1;v <= G.nv();v++) {ps = QPoint(paint->to_x(h[v]),paint->to_y(yh)); QString t = getVertexLabel(GC,v); QSize size = QFontMetrics(font).size(Qt::AlignCenter,t); int dx =size.width() + 2; dy =size.height();// + 2; if(t.length() == 0)dx = dy= 8; QRect rect = QRect(ps.x()-dx/2 ,ps.y()-dy/2,dx,dy); pn.setColor(color[G.vcolor[v]]);p->setPen(pn); p->drawRect(rect); pn.setColor(color[Black]);p->setPen(pn); p->drawText(rect,Qt::AlignCenter,t); } }
inline int FindInnerPoint2 (POINTARRAY & points, FACEARRAY & faces, Point3d & p) { static int timer = NgProfiler::CreateTimer ("FindInnerPoint2"); NgProfiler::RegionTimer reg (timer); ARRAY<Vec3d> a; ARRAY<double> c; Mat<3> m, inv; Vec<3> rs, x, pmin; int nf = faces.Size(); a.SetSize (nf); c.SetSize (nf); for (int i = 0; i < nf; i++) { Point3d p1 = points.Get(faces[i][0]); a[i] = Cross (points.Get(faces[i][1]) - p1, points.Get(faces[i][2]) - p1); a[i] /= a[i].Length(); c[i] = - (a[i].X() * p1.X() + a[i].Y() * p1.Y() + a[i].Z() * p1.Z()); } x = 0; double hmax = 0; for (int i = 0; i < nf; i++) { const Element2d & el = faces[i]; for (int j = 1; j <= 3; j++) { double hi = Dist (points.Get(el.PNumMod(j)), points.Get(el.PNumMod(j+1))); if (hi > hmax) hmax = hi; } } double fmin = 0; for (int i1 = 1; i1 <= nf; i1++) for (int i2 = i1+1; i2 <= nf; i2++) for (int i3 = i2+1; i3 <= nf; i3++) for (int i4 = i3+1; i4 <= nf; i4++) { m(0, 0) = a.Get(i1).X() - a.Get(i2).X(); m(0, 1) = a.Get(i1).Y() - a.Get(i2).Y(); m(0, 2) = a.Get(i1).Z() - a.Get(i2).Z(); rs(0) = c.Get(i2) - c.Get(i1); m(1, 0) = a.Get(i1).X() - a.Get(i3).X(); m(1, 1) = a.Get(i1).Y() - a.Get(i3).Y(); m(1, 2) = a.Get(i1).Z() - a.Get(i3).Z(); rs(1) = c.Get(i3) - c.Get(i1); m(2, 0) = a.Get(i1).X() - a.Get(i4).X(); m(2, 1) = a.Get(i1).Y() - a.Get(i4).Y(); m(2, 2) = a.Get(i1).Z() - a.Get(i4).Z(); rs(2) = c.Get(i4) - c.Get(i1); if (fabs (Det (m)) > 1e-10) { CalcInverse (m, inv); x = inv * rs; double f = -1e10; for (int i = 0; i < nf; i++) { double hd = x(0) * a[i].X() + x(1) * a[i].Y() + x(2) * a[i].Z() + c[i]; if (hd > f) f = hd; if (hd > fmin) break; } if (f < fmin) { fmin = f; pmin = x; } } } p = Point3d (pmin(0), pmin(1), pmin(2)); (*testout) << "fmin = " << fmin << endl; return (fmin < -1e-3 * hmax); }
int cstep(double *stx,double *fx,double *dx,double *sty,double *fy,double *dy,double *stp,double *fp,double *dp,int *brackt, double stpmin,double stpmax) { int info,bound; double gamma, p, p66, q, r, s, sgnd, stpc, stpf, stpq, theta; info = 0; p66 = 0.66; if ((*brackt == 1 && (*stp <= pmin(*stx, *sty) || *stp >= pmax(*stx, *sty))) || *dx*(*stp - *stx) >= 0.0 || stpmax < stpmin) { return info; } sgnd = (*dp) * (*dx / fabs(*dx)); /* First case. A higher function value. (fp > fx) The minimum is bracketed. If the cubic step is closer to stx than the quadratic step, the cubic step is taken, else the average of the cubic and quadratic steps is taken. */ if (*fp > *fx) { info = 1; bound = 1; theta = 3 * (*fx - *fp) / (*stp - *stx) + *dx + *dp; s = pmax(fabs(theta), fabs(*dx)); s = pmax(s, fabs(*dp)); gamma = s*sqrt((theta / s)*(theta/s) - (*dx / s)*(*dp / s)); if (*stp < *stx) { gamma = -gamma; } p = (gamma - *dx) + theta; q = ((gamma - *dx) + gamma) + *dp; r = p / q; stpc = *stx + r*(*stp - *stx); stpq = *stx + ((*dx / ((*fx - *fp) / (*stp - *stx) + *dx)) / 2)*(*stp - *stx); if (fabs(stpc - *stx) < fabs(stpq - *stx)) { stpf = stpc; } else { stpf = stpc + (stpq - stpc) / 2; } *brackt = 1; } else if (sgnd < 0.0) { /* Second case. A lower function value and derivatives of opposite sign. The minimum is bracketed. If the cubic step is closer to stx than the quadratic (secant) step, the cubic step is taken, else the quadratic step is taken. */ info = 2; bound = 0; theta = 3 * (*fx - *fp) / (*stp - *stx) + *dx + *dp; s = pmax(fabs(theta), fabs(*dx)); s = pmax(s, fabs(*dp)); gamma = s*sqrt((theta / s)*(theta / s) - (*dx / s)*(*dp / s)); if (*stp > *stx) { gamma = -gamma; } p = (gamma - *dp) + theta; q = ((gamma - *dp) + gamma) + *dx; r = p / q; stpc = *stp + r*(*stx - *stp); stpq = *stp + (*dp / (*dp - *dx))*(*stx - *stp); if (fabs(stpc - *stp) > fabs(stpq - *stp)) { stpf = stpc; } else { stpf = stpq; } *brackt = 1; } else if (fabs(*dp) < fabs(*dx)) { /* Third case. A lower function value, derivatives of the same sign, and the magnitude of the derivative decreases. The cubic step is only used if the cubic tends to infinity in the direction of the step or if the minimum of the cubic is beyond stp. Otherwise the cubic step is defined to be either stpmin or stpmax. The quadratic (secant) step is also computed and if the minimum is bracketed then the the step closest to stx is taken, else the step farthest away is taken. */ info = 3; bound = 1; theta = 3 * (*fx - *fp) / (*stp - *stx) + *dx + *dp; s = pmax(fabs(theta), fabs(*dx)); s = pmax(s, fabs(*dp)); /* The case gamma = 0 only arises if the cubic does not tend to infinity in the direction of the step. */ gamma = s*sqrt(pmax(0., (theta / s)*(theta / s) - (*dx / s)*(*dp / s))); if (*stp > *stx) { gamma = -gamma; } p = (gamma - *dp) + theta; q = (gamma + (*dx - *dp)) + gamma; r = p / q; if (r < 0.0 && gamma != 0.0) { stpc = *stp + r*(*stx - *stp); } else if (*stp > *stx) { stpc = stpmax; } else { stpc = stpmin; } stpq = *stp + (*dp / (*dp - *dx))*(*stx - *stp); if (*brackt == 1) { if (fabs(*stp - stpc) < fabs(*stp - stpq)) { stpf = stpc; } else { stpf = stpq; } } else { if (fabs(*stp - stpc) > fabs(*stp - stpq)) { stpf = stpc; } else { stpf = stpq; } } } else { /* Fourth case. A lower function value, derivatives of the same sign, and the magnitude of the derivative does not decrease. If the minimum is not bracketed, the step is either stpmin or stpmax, else the cubic step is taken. */ info = 4; bound = 0; if (*brackt == 1) { theta = 3 * (*fp - *fy) / (*sty - *stp) + *dy + *dp; s = pmax(fabs(theta), fabs(*dy)); s = pmax(s,fabs(*dp)); gamma = s*sqrt((theta / s)*(theta / s) - (*dy / s)*(*dp / s)); if (*stp > *sty) { gamma = -gamma; } p = (gamma - *dp) + theta; q = ((gamma - *dp) + gamma) + *dy; r = p / q; stpc = *stp + r*(*sty - *stp); stpf = stpc; } else if (*stp > *stx) { stpf = stpmax; } else { stpf = stpmin; } } /* Update the interval of uncertainty. This update does not depend on the new step or the case analysis above. */ if (*fp > *fx) { *sty = *stp; *fy = *fp; *dy = *dp; } else { if (sgnd < 0.0) { *sty = *stx; *fy = *fx; *dy = *dx; } *stx = *stp; *fx = *fp; *dx = *dp; } /* Compute the new step and safeguard it. */ stpf = pmin(stpmax, stpf); stpf = pmax(stpmin, stpf); *stp = stpf; if (*brackt == 1 && bound == 1) { if (*sty > *stx) { *stp = pmin(*stx + p66*(*sty - *stx), *stp); } else { *stp = pmax(*stx + p66*(*sty - *stx), *stp); } } return info; }
void MeshFromSpline2D (SplineGeometry2d & geometry, Mesh *& mesh, MeshingParameters & mp) { PrintMessage (1, "Generate Mesh from spline geometry"); double h = mp.maxh; Box<2> bbox = geometry.GetBoundingBox (); if (bbox.Diam() < h) { h = bbox.Diam(); mp.maxh = h; } mesh = new Mesh; mesh->SetDimension (2); geometry.PartitionBoundary (h, *mesh); // marks mesh points for hp-refinement for (int i = 0; i < geometry.GetNP(); i++) if (geometry.GetPoint(i).hpref) { double mindist = 1e99; PointIndex mpi(0); Point<2> gp = geometry.GetPoint(i); Point<3> gp3(gp(0), gp(1), 0); for (PointIndex pi = PointIndex::BASE; pi < mesh->GetNP()+PointIndex::BASE; pi++) if (Dist2(gp3, (*mesh)[pi]) < mindist) { mpi = pi; mindist = Dist2(gp3, (*mesh)[pi]); } (*mesh)[mpi].Singularity(1.); } int maxdomnr = 0; for (SegmentIndex si = 0; si < mesh->GetNSeg(); si++) { if ( (*mesh)[si].domin > maxdomnr) maxdomnr = (*mesh)[si].domin; if ( (*mesh)[si].domout > maxdomnr) maxdomnr = (*mesh)[si].domout; } mesh->ClearFaceDescriptors(); for (int i = 1; i <= maxdomnr; i++) mesh->AddFaceDescriptor (FaceDescriptor (i, 0, 0, i)); // set Array<string*> bcnames... // number of bcnames int maxsegmentindex = 0; for (SegmentIndex si = 0; si < mesh->GetNSeg(); si++) { if ( (*mesh)[si].si > maxsegmentindex) maxsegmentindex = (*mesh)[si].si; } mesh->SetNBCNames(maxsegmentindex); for ( int sindex = 0; sindex < maxsegmentindex; sindex++ ) mesh->SetBCName ( sindex, geometry.GetBCName( sindex+1 ) ); for (SegmentIndex si = 0; si < mesh->GetNSeg(); si++) (*mesh)[si].SetBCName ( (*mesh).GetBCNamePtr( (*mesh)[si].si-1 ) ); Point3d pmin(bbox.PMin()(0), bbox.PMin()(1), -bbox.Diam()); Point3d pmax(bbox.PMax()(0), bbox.PMax()(1), bbox.Diam()); mesh->SetLocalH (pmin, pmax, mparam.grading); mesh->SetGlobalH (h); mesh->CalcLocalH(); int bnp = mesh->GetNP(); // boundary points int hquad = mparam.quad; for (int domnr = 1; domnr <= maxdomnr; domnr++) if (geometry.GetDomainTensorMeshing (domnr)) { // tensor product mesh Array<PointIndex, PointIndex::BASE> nextpi(bnp); Array<int, PointIndex::BASE> si1(bnp), si2(bnp); PointIndex firstpi; nextpi = -1; si1 = -1; si2 = -1; for (SegmentIndex si = 0; si < mesh->GetNSeg(); si++) { int p1 = -1, p2 = -2; if ( (*mesh)[si].domin == domnr) { p1 = (*mesh)[si][0]; p2 = (*mesh)[si][1]; } if ( (*mesh)[si].domout == domnr) { p1 = (*mesh)[si][1]; p2 = (*mesh)[si][0]; } if (p1 == -1) continue; nextpi[p1] = p2; // counter-clockwise int index = (*mesh)[si].si; if (si1[p1] != index && si2[p1] != index) { si2[p1] = si1[p1]; si1[p1] = index; } if (si1[p2] != index && si2[p2] != index) { si2[p2] = si1[p2]; si1[p2] = index; } } PointIndex c1(0), c2, c3, c4; // 4 corner points int nex = 1, ney = 1; for (PointIndex pi = 1; pi <= si2.Size(); pi++) if (si2[pi] != -1) { c1 = pi; break; } for (c2 = nextpi[c1]; si2[c2] == -1; c2 = nextpi[c2], nex++); for (c3 = nextpi[c2]; si2[c3] == -1; c3 = nextpi[c3], ney++); for (c4 = nextpi[c3]; si2[c4] == -1; c4 = nextpi[c4]); Array<PointIndex> pts ( (nex+1) * (ney+1) ); // x ... inner loop pts = -1; for (PointIndex pi = c1, i = 0; pi != c2; pi = nextpi[pi], i++) pts[i] = pi; for (PointIndex pi = c2, i = 0; pi != c3; pi = nextpi[pi], i++) pts[(nex+1)*i+nex] = pi; for (PointIndex pi = c3, i = 0; pi != c4; pi = nextpi[pi], i++) pts[(nex+1)*(ney+1)-i-1] = pi; for (PointIndex pi = c4, i = 0; pi != c1; pi = nextpi[pi], i++) pts[(nex+1)*(ney-i)] = pi; for (PointIndex pix = nextpi[c1], ix = 0; pix != c2; pix = nextpi[pix], ix++) for (PointIndex piy = nextpi[c2], iy = 0; piy != c3; piy = nextpi[piy], iy++) { Point<3> p = (*mesh)[pix] + ( (*mesh)[piy] - (*mesh)[c2] ); pts[(nex+1)*(iy+1) + ix+1] = mesh -> AddPoint (p , 1, FIXEDPOINT); } for (int i = 0; i < ney; i++) for (int j = 0; j < nex; j++) { Element2d el(QUAD); el[0] = pts[i*(nex+1)+j]; el[1] = pts[i*(nex+1)+j+1]; el[2] = pts[(i+1)*(nex+1)+j+1]; el[3] = pts[(i+1)*(nex+1)+j]; el.SetIndex (domnr); mesh -> AddSurfaceElement (el); } } for (int domnr = 1; domnr <= maxdomnr; domnr++) { if (geometry.GetDomainTensorMeshing (domnr)) continue; if ( geometry.GetDomainMaxh ( domnr ) > 0 ) h = geometry.GetDomainMaxh(domnr); PrintMessage (3, "Meshing domain ", domnr, " / ", maxdomnr); int oldnf = mesh->GetNSE(); mparam.quad = hquad || geometry.GetDomainQuadMeshing (domnr); Meshing2 meshing (Box<3> (pmin, pmax)); for (PointIndex pi = PointIndex::BASE; pi < bnp+PointIndex::BASE; pi++) meshing.AddPoint ( (*mesh)[pi], pi); PointGeomInfo gi; gi.trignum = 1; for (SegmentIndex si = 0; si < mesh->GetNSeg(); si++) { if ( (*mesh)[si].domin == domnr) meshing.AddBoundaryElement ( (*mesh)[si][0] + 1 - PointIndex::BASE, (*mesh)[si][1] + 1 - PointIndex::BASE, gi, gi); if ( (*mesh)[si].domout == domnr) meshing.AddBoundaryElement ( (*mesh)[si][1] + 1 - PointIndex::BASE, (*mesh)[si][0] + 1 - PointIndex::BASE, gi, gi); } mparam.checkoverlap = 0; meshing.GenerateMesh (*mesh, h, domnr); for (SurfaceElementIndex sei = oldnf; sei < mesh->GetNSE(); sei++) (*mesh)[sei].SetIndex (domnr); // astrid char * material; geometry.GetMaterial( domnr, material ); if ( material ) { (*mesh).SetMaterial ( domnr, material ); } } mparam.quad = hquad; int hsteps = mp.optsteps2d; mp.optimize2d = "smcm"; mp.optsteps2d = hsteps/2; Optimize2d (*mesh, mp); mp.optimize2d = "Smcm"; mp.optsteps2d = (hsteps+1)/2; Optimize2d (*mesh, mp); mp.optsteps2d = hsteps; mesh->Compress(); mesh -> SetNextMajorTimeStamp(); extern void Render(); Render(); }
void DrawBipContact(QPainter *p,pigalePaint *paint) {GraphContainer GC = paint->GCP; GeometricGraph G(paint->GCP); Prop<int> h(G.Set(tvertex()),PROP_DRAW_INT_1); Prop<int> h1(G.Set(tvertex()),PROP_DRAW_INT_2); Prop<int> h2(G.Set(tvertex()),PROP_DRAW_INT_3); Prop1<Tpoint> pmax(G.Set(),PROP_POINT_MAX); Prop1<Tpoint> pmin(G.Set(),PROP_POINT_MIN); QPen pn = p->pen();pn.setWidth(1); QBrush pb = p->brush(); pb.setStyle(Qt::SolidPattern); QPoint ps,pt,ps2,pt2; // Drawing the diagonal ps = QPoint(paint->to_x(pmin().x()),paint->to_y(pmin().y())); pt = QPoint(paint->to_x(pmax().x()),paint->to_y(pmax().y())); pn.setColor(color[Grey1]); p->setPen(pn); p->drawLine(ps,pt); // Drawing the vertices: horizontal and vertical segments for(tvertex v = 1;v <= G.nv();v++) {double delta = (h1[v] < h[v])?.45:-.45; pn.setColor(color[G.vcolor[v]]); pn.setWidth(1);p->setPen(pn); if(G.vcolor[v] == Red)//horizontales {ps = QPoint(paint->to_x(h1[v]),paint->to_y(h[v])); pt = QPoint(paint->to_x(h2[v]),paint->to_y(h[v])); if(h2[v] > h[v] && h1[v] > h[v]) {ps2 = QPoint(paint->to_x(h[v]),paint->to_y(h[v])); p->drawLine(ps2,pt); } else if(h2[v] < h[v] && h1[v] < h[v]) {pt2 = QPoint(paint->to_x(h[v]),paint->to_y(h[v])); p->drawLine(ps,pt2); } if(h1[v] == h2[v])// isthme {ps = QPoint(paint->to_x(h1[v]),paint->to_y(h[v])); pt = QPoint(paint->to_x(h2[v]+delta),paint->to_y(h[v])); } pn.setWidth(2);p->setPen(pn); p->drawLine(ps,pt); } else // verticales {ps = QPoint(paint->to_x(h[v]),paint->to_y(h1[v])); pt = QPoint(paint->to_x(h[v]),paint->to_y(h2[v])); if(h2[v] > h[v] && h1[v] > h[v]) {ps2 = QPoint(paint->to_x(h[v]),paint->to_y(h[v])); p->drawLine(ps2,pt); } else if(h2[v] < h[v] && h1[v] < h[v]) {pt2 = QPoint(paint->to_x(h[v]),paint->to_y(h[v])); p->drawLine(ps,pt2); } if(h1[v] == h2[v])// isthme {ps = QPoint(paint->to_x(h[v]),paint->to_y(h1[v])); pt = QPoint(paint->to_x(h[v]),paint->to_y(h2[v]+delta)); } pn.setWidth(2);p->setPen(pn); p->drawLine(ps,pt); } } //drawing labels int dy = Min(12,paint->height()/(pmax().y()+1)-2); QFont font = QFont("sans",dy); p->setFont(font); pb.setColor(color[White]); p->setBrush(pb); pn.setWidth(1); for(tvertex v = 1;v <= G.nv();v++) //trace des labels {double delta = (h1[v] < h[v])?.9:-.9; if(G.vcolor[v] == Red) {if(h1[v] != h2[v]) {ps = QPoint(paint->to_x(h1[v]),paint->to_y(h[v])); pt = QPoint(paint->to_x(h2[v]),paint->to_y(h[v])); } else {ps = QPoint(paint->to_x(h1[v]),paint->to_y(h[v])); pt = QPoint(paint->to_x(h2[v]+delta),paint->to_y(h[v])); } } else {if(h1[v] != h2[v]) {ps = QPoint(paint->to_x(h[v]),paint->to_y(h1[v])); pt = QPoint(paint->to_x(h[v]),paint->to_y(h2[v])); } else {ps = QPoint(paint->to_x(h[v]),paint->to_y(h1[v])); pt = QPoint(paint->to_x(h[v]),paint->to_y(h2[v]+delta)); } } QString t = getVertexLabel(GC,v); QSize size = QFontMetrics(font).size(Qt::AlignCenter,t); int dx =size.width() + 2; dy =size.height() + 2; if(t.length() == 0)dx = dy= 8; QRect rect = QRect((ps.x() + pt.x() - dx)/2,(ps.y() + pt.y() - dy)/2,dx,dy); pn.setColor(color[G.vcolor[v]]);p->setPen(pn); p->drawRect(rect); pn.setColor(color[Black]);p->setPen(pn); p->drawText(rect,Qt::AlignCenter,t); } }
void Grid::traceCoherent(const vector<Segment> &segments, vector<pair<int, float>> &out, int ignored_id, int flags) const { out.resize(segments.size(), make_pair(-1, constant::inf)); if(segments.empty()) return; int2 start, end; { float3 pmin(constant::inf, constant::inf, constant::inf); float3 pmax(-constant::inf, -constant::inf, -constant::inf); for(int s = 0; s < (int)segments.size(); s++) { const Segment &segment = segments[s]; float tmin = max(0.0f, intersection(segment, m_bounding_box)); float tmax = min(segment.length(), -intersection(-segment, m_bounding_box)); float3 p1 = segment.at(tmin), p2 = segment.at(tmax); pmin = min(pmin, min(p1, p2)); pmax = max(pmax, max(p1, p2)); } start = worldToGrid((int2)pmin.xz()); end = worldToGrid((int2)pmax.xz()); start = max(start, int2(0, 0)); end = min(end, int2(m_size.x - 1, m_size.y - 1)); } float max_dist = -constant::inf; Interval idir[3], origin[3]; { const Segment &first = segments.front(); idir [0] = first.invDir().x; idir [1] = first.invDir().y; idir [2] = first.invDir().z; origin[0] = first.origin().x; origin[1] = first.origin().y; origin[2] = first.origin().z; for(int s = 1; s < (int)segments.size(); s++) { const Segment &segment = segments[s]; float tidir[3] = { segment.invDir().x, segment.invDir().y, segment.invDir().z }; float torigin[3] = { segment.origin().x, segment.origin().y, segment.origin().z }; max_dist = max(max_dist, segment.length()); for(int i = 0; i < 3; i++) { idir [i] = Interval(min(idir [i].min, tidir [i]), max(idir [i].max, tidir [i])); origin[i] = Interval(min(origin[i].min, torigin[i]), max(origin[i].max, torigin[i])); } } } for(int x = start.x; x <= end.x; x++) for(int z = start.y; z <= end.y; z++) { int node_id = nodeAt(int2(x, z)); const Node &node = m_nodes[node_id]; if(flagTest(node.obj_flags, flags) && intersection(idir, origin, node.bbox) < max_dist) { const Object *objects[node.size]; int count = extractObjects(node_id, objects, ignored_id, flags); for(int n = 0; n < count; n++) { if(intersection(idir, origin, objects[n]->bbox) < max_dist) { for(int s = 0; s < (int)segments.size(); s++) { const Segment &segment = segments[s]; float dist = intersection(segment, objects[n]->bbox); if(dist < out[s].second) { out[s].second = dist; out[s].first = objects[n] - &m_objects[0]; } } } } if(node.is_dirty) updateNode(node_id); } } }