bool _stdcall PtIsOnArc( const LLPoint & llArcCenter, double dArcRadius, double dArcStartAzimuth, double dArcEndAzimuth, int nArcDirection, const LLPoint & llTestPt, int & bOnArc ) { InverseResult invResult; if(!DistVincenty(llArcCenter, llTestPt, invResult)) return false; double dDist = invResult.distance; double dCrs = invResult.azimuth; bOnArc = false; if(fabs(dDist - dArcRadius) > 0.5e-3) //Tol()) bOnArc = false; else { double dArcExtent = GetArcExtent(dArcStartAzimuth, dArcEndAzimuth, nArcDirection, Tol()); if(dArcExtent == M_2PI) bOnArc = true; else { double dSubExtent = GetArcExtent(dArcStartAzimuth, dCrs, nArcDirection, Tol()); if(nArcDirection > 0) { if(dSubExtent <= dArcExtent) bOnArc = true; } else { if(dSubExtent >= dArcExtent) bOnArc = true; } } } return true; }
bool GiGraphics::setClipWorld(const Box2d& rectWorld) { bool ret = false; if (isDrawing() && !rectWorld.isEmpty()) { Box2d box (rectWorld * xf().worldToDisplay()); box.intersectWith(Box2d(m_impl->clipBox0)); if (!box.isEmpty(Tol(1, 0))) { if (box != Box2d(m_impl->clipBox)) { box.get(m_impl->clipBox); m_impl->rectDraw = box; m_impl->rectDraw.inflate(GiGraphicsImpl::CLIP_INFLATE); m_impl->rectDrawM = m_impl->rectDraw * xf().displayToModel(); m_impl->rectDrawW = m_impl->rectDrawM * xf().modelToWorld(); SafeCall(m_impl->canvas, _clipBoxChanged(m_impl->clipBox)); } ret = true; } } return ret; }
float mgnear::linesHit( int n, const Point2d* points, bool closed, const Point2d& pt, float tol, Point2d& nearpt, int& segment, bool* inside, int* hitType) { Point2d ptTemp; float dist, distMin = _FLT_MAX; const Box2d rect (pt, 2 * tol, 2 * tol); int n2 = (closed && n > 1) ? n + 1 : n; int type = mglnrel::ptInArea(pt, n, points, segment, Tol(tol), closed); if (inside) { *inside = (closed && type == mglnrel::kPtInArea); } if (hitType) { *hitType = type; } if (type == mglnrel::kPtAtVertex) { nearpt = points[segment]; distMin = nearpt.distanceTo(pt); return distMin; } if (type == mglnrel::kPtOnEdge) { distMin = mglnrel::ptToLine(points[segment], points[(segment+1)%n], pt, nearpt); return distMin; } if (!closed || type != mglnrel::kPtInArea) { return distMin; } for (int i = 0; i + 1 < n2; i++) { const Point2d& pt2 = points[(i + 1) % n]; if (closed || rect.isIntersect(Box2d(points[i], pt2))) { dist = mglnrel::ptToLine(points[i], pt2, pt, ptTemp); if (distMin > 1e10f || (dist <= tol && dist < distMin)) { distMin = dist; nearpt = ptTemp; if (dist <= tol) segment = i; } } } return distMin; }
bool destRhumb(double lat1, double lon1, double brng, double dist, double* lat2, double* lon2) { lat1=toRad(lat1); lon1=toRad(lon1); double d=NMtorad(dist); double tc=toRad(brng); double lat= lat1+d*cos(tc); if (std::abs(lat) > M_PI/2) return false;//"d too large. You can't go this far along this rhumb line!" double q; if (std::abs(lat-lat1) < sqrt(Tol())){ q=cos(lat1); } else { double dphi=log(tan(lat/2+M_PI/4)/tan(lat1/2+M_PI/4)); q= (lat-lat1)/dphi; } double dlon=-d*sin(tc)/q; *lon2=toDeg(mod(lon1+dlon+M_PI,2*M_PI)-M_PI); *lat2=toDeg(lat); return true; }
/** * Calculates rhumb line distance between two points specified by latitude/longitude * http://williams.best.vwh.net/avform.htm#Rhumb * -> double lat1, lon1: first point in decimal degrees * -> double lat2, lon2: second point in decimal degrees * <- double dist: distance along bearing in nautical miles * <- double bearing in decimal degrees * As stated in the introduction, North latitudes and West longitudes are treated as positive, * and South latitudes and East longitudes negative. It's easier to go with the flow, but if * you prefer another convention you can change the signs in the formulae. */ void distRhumb(double lat1,double lon1, double lat2, double lon2, double *distance, double *brng){ lat1=toRad(lat1); lat2=toRad(lat2); lon1=toRad(lon1); lon2=toRad(lon2); double dlon_W=mod(lon2-lon1,(2*M_PI)); double dlon_E=mod(lon1-lon2,(2*M_PI)); double dphi=log(tan(lat2/2+M_PI/4)/tan(lat1/2+M_PI/4)); double q=0; if (std::abs(lat2-lat1) < sqrt(Tol())){ q=cos(lat1); } else { q= (lat2-lat1)/dphi; } if (dlon_W < dlon_E){// Westerly rhumb line is the shortest *brng=toDeg(mod(atan2(-dlon_W,dphi),(2*M_PI))); *distance= radtoNM(sqrt(sqr(q)*(sqr(dlon_W)) + sqr(lat2-lat1))); } else{ *brng=toDeg(mod(atan2(dlon_E,dphi),(2*M_PI))); *distance= radtoNM(sqrt(sqr(q)*(sqr(dlon_E)) + sqr(lat2-lat1))); } }
Expr *Expr::FoldConstants(void) { Expr *n = AllocExpr(); *n = *this; int c = Children(); if(c >= 1) n->a = a->FoldConstants(); if(c >= 2) n->b = b->FoldConstants(); switch(op) { case PARAM_PTR: case PARAM: case CONSTANT: break; case MINUS: case TIMES: case DIV: case PLUS: // If both ops are known, then we can evaluate immediately if(n->a->op == CONSTANT && n->b->op == CONSTANT) { double nv = n->Eval(); n->op = CONSTANT; n->v = nv; break; } // x + 0 = 0 + x = x if(op == PLUS && n->b->op == CONSTANT && Tol(n->b->v, 0)) { *n = *(n->a); break; } if(op == PLUS && n->a->op == CONSTANT && Tol(n->a->v, 0)) { *n = *(n->b); break; } // 1*x = x*1 = x if(op == TIMES && n->b->op == CONSTANT && Tol(n->b->v, 1)) { *n = *(n->a); break; } if(op == TIMES && n->a->op == CONSTANT && Tol(n->a->v, 1)) { *n = *(n->b); break; } // 0*x = x*0 = 0 if(op == TIMES && n->b->op == CONSTANT && Tol(n->b->v, 0)) { n->op = CONSTANT; n->v = 0; break; } if(op == TIMES && n->a->op == CONSTANT && Tol(n->a->v, 0)) { n->op = CONSTANT; n->v = 0; break; } break; case SQRT: case SQUARE: case NEGATE: case SIN: case COS: case ASIN: case ACOS: if(n->a->op == CONSTANT) { double nv = n->Eval(); n->op = CONSTANT; n->v = nv; } break; default: oops(); } return n; }