Ejemplo n.º 1
0
	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;
	}
Ejemplo n.º 2
0
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;
}
Ejemplo n.º 3
0
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;
}
Ejemplo n.º 4
0
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;
}
Ejemplo n.º 5
0
/**
 * 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)));
      }
}
Ejemplo n.º 6
0
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;
}