double _stdcall LocusCrsAtPoint(const Locus & locus, const LLPoint & testPt, LLPoint & geoPt, double & dPerpCrs, const double dTol)
	{
		if(!PtIsOnLocus(locus, testPt, geoPt, dTol))
			return -1.0;

		double dLocusCrs = 0.0;
		double dPerpDist;

		InverseResult result;
		DistVincenty(testPt, geoPt, result);
		dPerpCrs = result.azimuth;
		dPerpDist = result.distance;

		DistVincenty(locus.geoStart, locus.geoEnd, result);
		double dGeoLen = result.distance;

		double dDistToLocus = DistToLocusP(locus, geoPt, dTol, Eps());
		double dSlope = atan((locus.endDist - locus.startDist) / dGeoLen);

		dPerpCrs = dPerpCrs + dSlope;

		if(dDistToLocus < 0)
			dLocusCrs = dPerpCrs - M_PI_2;
		else
			dLocusCrs = dPerpCrs + M_PI_2;

		if(dLocusCrs > M_2PI)
			dLocusCrs = dLocusCrs - M_2PI;

		return dLocusCrs;
	}
	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;
	}
Example #3
0
void distVincenty(LLPoint pt1, LLPoint pt2, InverseResult * result)
	{
	InverseResult temp;
    //bool test =
    DistVincenty( pt1,  pt2,   &temp);
    *result=temp;
	}
Example #4
0
    bool 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;

        bOnArc = false;

        if (fabs(invResult.distance - dArcRadius) <= 0.5e-3)
        {
            const double dSubtendedAng1 = GetArcExtent(dArcStartAzimuth, dArcEndAzimuth, nArcDirection, kTol);

            if (dSubtendedAng1 == M_2PI)
                bOnArc = true;
            else
            {
                const double dSubtendedAng2 = GetArcExtent(dArcStartAzimuth, invResult.azimuth,
                                                     nArcDirection, kTol);

                if (nArcDirection > 0)
                {
                    if (dSubtendedAng2 <= dSubtendedAng1)
                        bOnArc = true;
                }
                else
                {
                    if (dSubtendedAng2 >= dSubtendedAng1)
                        bOnArc = true;
                }
            }
        }
        return true;
    }
Example #5
0
    bool PtIsOnGeodesic(const LLPoint &pt1, const LLPoint &pt2, const LLPoint &pt3, int lengthCode,
                        PtIsOnGeodesicResult &result)
    {
        InverseResult invResult;
        if (!DistVincenty(pt1, pt3, invResult))
            return false;

        const double dist13 = invResult.distance;

        if (!DistVincenty(pt1, pt2, invResult))
            return false;

        const double dist12 = invResult.distance;
        const double crs12 = invResult.azimuth;

        LLPoint testPt2 = DestVincenty(pt1, crs12, dist13);

        if (!DistVincenty(pt3, testPt2, invResult))
            return false;

        if (invResult.distance <= kTolPtIsOnGeodesic)
        {
            result.result = lengthCode > 0 || dist13 - dist12 <= kTolPtIsOnGeodesic;
        }
        else if (lengthCode == 2)
        {
            testPt2 = DestVincenty(pt1, crs12 + M_PI, dist13);

            if (!DistVincenty(pt3, testPt2, invResult))
                return false;

            result.result = invResult.distance <= kTolPtIsOnGeodesic;
        }
        else
        {
            result.result = false;
        }
        result.geoStart = pt1;
        result.geoEnd = pt2;
        result.geoPt = testPt2;
        result.lengthCode = lengthCode;
        return true;
    }
Example #6
0
    LLPoint PointOnLocusP(const Locus &loc, const LLPoint &geoPt, double tol, double eps)
    {
        const double distp = DistToLocusP(loc, geoPt, tol, eps);

        if (distp == 0)
            return geoPt;

        InverseResult result;
        DistVincenty(geoPt, loc.geoStart, result);

        result.azimuth += distp > 0.0 ? -M_PI / 2.0 : M_PI / 2.0;

        return DestVincenty(geoPt, result.azimuth, fabs(distp));
    }
Example #7
0
    double DistToLocusD(const Locus &loc, double dDistance, double dEps)
    {
        InverseResult result;

        if (!DistVincenty(loc.geoStart, loc.geoEnd, result))
            return numeric_limits<double>::signaling_NaN();

        if (result.distance > 0.0)
        {
            return loc.startDist + (dDistance / result.distance) * (loc.endDist - loc.startDist);
        }

        return 0.0;
    }
Example #8
0
bool DistVincenty(double lat1, double lon1, double lat2, double lon2, double *dist, double *fwdAz, double *revAz){

    InverseResult result;
    LLPoint pt1, pt2;
    pt1.latitude=toRad(lat1);
    pt1.longitude=toRad(lon1);
    pt2.latitude=toRad(lat2);
    pt2.longitude=toRad(lon2);

    bool test=DistVincenty( pt1,  pt2, & result);
    *dist = mtoNM(result.distance);
    *fwdAz = toDeg(result.azimuth);
    *revAz = toDeg(result.azimuth);
    return test;
}
    int TangentFixedRadiusArc(const LLPoint &pt1, double crs12, const LLPoint &pt3,
                              double crs3, double radius, int &dir,
                              LLPoint &centerPt, LLPoint &tanPt1, LLPoint &tanPt2, double dTol)
    {
        LLPoint pt2;
        if (!CrsIntersect(pt1, crs12, pt3, crs3 + M_PI, dTol, pt2))
            return 0;

        InverseResult result;
        DistVincenty(pt1, pt2, result);
        const double dist12 = result.distance;

        DistVincenty(pt2, pt1, result);
        const double crs21 = result.azimuth;

        DistVincenty(pt2, pt3, result);
        const double vertexAngle = SignAzimuthDifference(crs21, result.azimuth);

        if (fabs(sin(vertexAngle)) < dTol)
            return 0;

        dir = vertexAngle > 0.0 ? -1 : 1;

        if (radius > fabs(kSphereRadius * vertexAngle / 2.0))
            return 0;

        double distToStart = dist12 - fabs(kSphereRadius *
                                           asin(tan(radius / kSphereRadius) / tan(vertexAngle / 2.0)));
        LLPoint startPt, endPt;
        int k = 0;
        double dErr = 0.0;
        while (k == 0 || (fabs(dErr) > dTol && k <= 10))
        {
            distToStart = distToStart - dErr / fabs(sin(vertexAngle));
            startPt = DestVincenty(pt1, crs12, distToStart);
            DistVincenty(startPt, pt2, result);
            result.azimuth += dir < 0 ? M_PI_2 : -M_PI_2;
            centerPt = DestVincenty(startPt, result.azimuth, radius);

            double dCrsFromPt, dDistFromPt;
            endPt = PerpIntercept(pt3, crs3 + M_PI, centerPt, dCrsFromPt, dDistFromPt, dTol);
            DistVincenty(centerPt, endPt, result);
            dErr = radius - result.distance;
            k++;
        }
        tanPt1 = startPt;
        tanPt2 = endPt;

        DistVincenty(pt2, tanPt2, result);

        return fabs(SignAzimuthDifference(result.azimuth, crs3)) <= M_PI_2;
    }
Example #10
0
    int GeoLocusIntersect(const LLPoint &gStart, const LLPoint &gEnd, const Locus &loc, LLPoint &intersect,
                          double dTol, double dEps)
    {
        InverseResult result;
        DistVincenty(gStart, gEnd, result);
        const double gAz = result.azimuth;

        DistVincenty(loc.locusStart, loc.locusEnd, result);
        const double locStAz = result.azimuth;
        const double locLength = result.distance;

        double crs31, crs32, dist13, dist23;
        LLPoint pt1;
        if (!CrsIntersect(loc.locusStart, locStAz, crs31, dist13, gStart, gAz, crs32, dist23, dTol, pt1))
            return 0;

        DistVincenty(loc.geoStart, loc.geoEnd, result);

        const double tcrs = result.azimuth;
        double crsFromPt, distFromPt;
        LLPoint ptInt = PerpIntercept(loc.geoStart, tcrs, pt1, crsFromPt, distFromPt, dTol);

        double distLoc = DistToLocusP(loc, ptInt, dTol, dEps);

        double distarray[2];
        double errarray[2];
        errarray[1] = distFromPt - fabs(distLoc);
        distarray[1] = dist23;

        double distBase = dist23 - errarray[1] / cos(fabs(SignAzimuthDifference(crsFromPt, crs32)));

        int k = 0;
        const int maxCount = 10;
        while (!std::isnan(distBase) && fabs(errarray[1]) > dTol && k < maxCount)
        {
            pt1 = DestVincenty(gStart, gAz, distBase);
            errarray[0] = errarray[1];
            distarray[0] = distarray[1];
            distarray[1] = distBase;

            ptInt = PerpIntercept(loc.geoStart, tcrs, pt1, crsFromPt, distFromPt, dTol);
            distLoc = DistToLocusP(loc, ptInt, dTol, dEps);
            errarray[1] = distFromPt - fabs(distLoc);

            FindLinearRoot(distarray, errarray, distBase);
            k++;
        }
        intersect = pt1;

        DistVincenty(intersect, loc.locusStart, result);
        const double distLocStPt1 = result.distance;
        DistVincenty(intersect, loc.locusEnd, result);

        // found intersect point must be on or between locus
        // If 5e-3 is to tight a tolerance then try setting to 5e-2
        // For the 8260.54A Appendix test cases 1e-3 was to tight, 5e-3
        // works just fine.
        if (!IsNearZero(locLength - (distLocStPt1 + result.distance), 5e-3))
            return 0;
        return 1;
    }
    int GeodesicArcIntercept(const LLPoint &pt1, double crs1,
                             const LLPoint &center, double radius,
                             LLPoint &intPtC1, LLPoint &intPtC2, double dTol)
    {
        double dCrsFromPt, dDistFromPt;
        const LLPoint perpPt = PerpIntercept(pt1, crs1, center, dCrsFromPt, dDistFromPt, dTol);

        InverseResult result;
        DistVincenty(perpPt, center, result);

        if (result.distance > radius)
            return 0;

        if (fabs(result.distance - radius) < dTol)
        {
            intPtC1 = perpPt;
            return 1;
        }

        const double perpDist = result.distance;
        DistVincenty(perpPt, pt1, result);

        if (IsApprox(cos(perpDist / kSphereRadius), 0.0, 1e-8))
            return 0;

        double crs = result.azimuth;
        double dist = kSphereRadius * acos(cos(radius / kSphereRadius) / cos(perpDist / kSphereRadius));
        LLPoint pt = DestVincenty(perpPt, crs, dist);

        const int nIntersects = 2;
        for (int i = 0; i < nIntersects; i++)
        {
            DistVincenty(center, pt, result);
            const double rcrs = result.reverseAzimuth;
            const double dErr = radius - result.distance;

            double distarray[2], errarray[2];
            distarray[0] = dist;
            errarray[0] = dErr;

            DistVincenty(pt, perpPt, result);
            const double bcrs = result.azimuth;

            DistVincenty(center, pt, result);
            const double dAngle = fabs(SignAzimuthDifference(result.azimuth, result.reverseAzimuth));
            const double B = fabs(SignAzimuthDifference(bcrs, rcrs) + M_PI - dAngle);
            const double A = acos(sin(B) * cos(fabs(dErr) / kSphereRadius));
            double c;
            if (fabs(sin(A)) < dTol)
                c = dErr;
            else if (fabs(A) < dTol)
                c = dErr / cos(B);
            else
                c = kSphereRadius * asin(sin(dErr / kSphereRadius) / sin(A));

            dist = dErr > 0 ? dist + c : dist - c;
            pt = DestVincenty(perpPt, crs, dist);
            DistVincenty(center, pt, result);
            distarray[1] = dist;
            errarray[1] = radius - result.distance;

            while (fabs(dErr) > dTol)
            {
                FindLinearRoot(distarray, errarray, dist);
                if (std::isnan(dist))
                    break;

                pt = DestVincenty(perpPt, crs, dist);
                DistVincenty(center, pt, result);
                distarray[0] = distarray[1];
                errarray[0] = errarray[1];
                distarray[1] = dist;
                errarray[1] = radius - result.distance;
                break;
            }

            if (i == 0)
                intPtC1 = pt;
            else if (i == 1)
                intPtC2 = pt;
            else
                break;

            crs += M_PI;
            pt = DestVincenty(perpPt, crs, dist);
            DistVincenty(center, pt, result);
            errarray[0] = radius - result.distance;
        }

        return nIntersects;
    }
Example #12
0
    int LocusPerpIntercept(const Locus &loc, const LLPoint &pt2, double &crsFromPt,
                           double &distFromPt, LLPoint &intPt, double dTol)
    {
        InverseResult result;
        DistVincenty(loc.geoStart, loc.geoEnd, result);
        double gcrs = result.azimuth;
        double gdist = result.distance;

        if (fabs(loc.startDist - loc.endDist) < dTol)
        {
            const LLPoint geoPt = PerpIntercept(loc.geoStart, gcrs, pt2, crsFromPt, distFromPt, dTol);
            intPt = PointOnLocusP(loc, geoPt, dTol, kEps);
            DistVincenty(pt2, intPt, result);
            distFromPt = result.distance;
            crsFromPt = result.azimuth;
            return 1;
        }

        DistVincenty(loc.locusStart, loc.locusEnd, result);
        LLPoint locPt = PerpIntercept(loc.locusStart, result.azimuth, pt2, crsFromPt, distFromPt, dTol);
        LLPoint geoPt = PerpIntercept(loc.geoStart, gcrs, locPt, crsFromPt, distFromPt, dTol);
        const double locAngle = atan((loc.startDist - loc.endDist) / gdist);

        double distarray[2], errarray[2];
        distarray[0] = distarray[1] = errarray[0] = errarray[1] = 0.0;

        DistVincenty(loc.geoStart, geoPt, result);
        distarray[1] = result.distance;

        const int maxCount = 15;
        double newDist = 0.0;
        int k = 0;
        while (k == 0 || (!std::isnan(newDist) && fabs(errarray[1]) > dTol && k < maxCount))
        {
            geoPt = DestVincenty(loc.geoStart, gcrs, distarray[1]);
            locPt = PointOnLocusP(loc /*loc.geoStart*/, geoPt, dTol, kEps);

            DistVincenty(locPt, pt2, result);
            errarray[1] = -result.distance * cos(fabs(
                    SignAzimuthDifference(LocusCrsAtPoint(loc, locPt, geoPt, 1e-8), result.azimuth)));

            if (fabs(errarray[1]) < dTol)
            {
                distFromPt = result.distance;
                crsFromPt = result.reverseAzimuth;
                intPt = locPt;
                break;
            }

            if (k == 0)
                newDist = distarray[1] + errarray[1] * cos(locAngle);
            else
                FindLinearRoot(distarray, errarray, newDist);
            distarray[0] = distarray[1];
            distarray[1] = newDist;
            errarray[0] = errarray[1];
            k++;
        }

        intPt = locPt;
        DistVincenty(pt2, intPt, result);
        distFromPt = result.distance;
        crsFromPt = result.azimuth;
        return 1;
    }
Example #13
0
	bool  CrsIntersect1(double lat1, double lon1, double az13,
		double & az31, double & dist13, double lat2, double lon2, double az23,
		double & az32, double & dist23, double dTol, double lati, double loni)
	{
	    LLPoint pt1;
	    LLPoint pt2;
		pt1.latitude = lat1;
		pt1.longitude = lon1;
        pt2.latitude = lat2;
		pt2.longitude = lon2;

		double dAz13 = az13;
		double dAz23 = az23;

		InverseResult result;
		DistVincenty(pt1, pt2, &result);

		double dist12 = result.distance;
		double crs12 = result.azimuth;
		double crs21 = result.reverseAzimuth;

		double angle1 = fabs(SignAzimuthDifference(dAz13, crs12));
		double angle2 = fabs(SignAzimuthDifference(crs21, dAz23));
		if(angle1 < 0.0 && angle2 < 0.0)
		{
			angle1 = -angle1;
			angle2 = -angle2;
		}

		if(sin(angle1) == 0.0 && sin(angle2) == 0.0)
			return false;

		// step 7
		// locate approx intersection of point3 using spherical earth model. Section 3.2

		double cosA = cos(angle1);
		double sinA = sin(angle1);
		double cosB = cos(angle2);
		double sinB = sin(angle2);

		double C = acos( -cosA * cosB + sinA * sinB * cos(dist12 / SphereRadius()));

		double cosC = cos(C);
		double sinC = sin(C);
		double a = SphereRadius() * acos( (cosA + cosB * cosC) / (sinB * sinC) );
		double b = SphereRadius() * acos( (cosB + cosA * cosC) / (sinA * sinC) );

		if(!IsNumber(a) || !IsNumber(b))
			return false;

		LLPoint llIntersect = DestVincenty(pt1, dAz13, b);
		DistVincenty(pt1, llIntersect, &result);
		dist13 = result.distance;

		LLPoint llInv = llIntersect;
		llInv.latitude = -llInv.latitude;
		llInv.longitude = llInv.longitude + M_PI - (2*M_PI);
		DistVincenty(pt1, llInv, &result);

		if(dist13 > result.distance)
		{
			llIntersect = llInv;
			dist13 = result.distance;
			az31 = result.reverseAzimuth;
			dAz13 = dAz13 + M_PI;
			dAz23 = dAz23 + M_PI;
		}

		DistVincenty(pt2, llIntersect, &result);
		dist23 = result.distance;

		if(dist13 < NmToMeters(1))
		{
			pt1 = DestVincenty(pt1, dAz13 + M_PI, NmToMeters(1.0));
			DistVincenty(pt1, llIntersect, &result);
			dAz13 = result.azimuth;
		}
		if(dist23 < NmToMeters(1))
		{
			pt2 = DestVincenty(pt2, dAz23 + M_PI, NmToMeters(1.0));
			DistVincenty(pt2, llIntersect, &result);
			dAz23 = result.azimuth;
		}

		bool bSwapped = false;
		if(dist23 < dist13)
		{
			LLPoint newPt = pt1;
			pt1 = pt2;
			pt2 = newPt;
			double aaz13 = dAz13;
			dAz13 = dAz23;
			dAz23 = aaz13;
			dist13 = dist23;
			bSwapped = true;
		}

		double distarray[2], errarray[2];
		distarray[0] = dist13;
		llIntersect = DestVincenty(pt1, dAz13, dist13);
		DistVincenty(pt2, llIntersect, &result);
		double aacrs23 = result.azimuth;
		errarray[0] = SignAzimuthDifference(aacrs23, dAz23);
		distarray[1] = 1.01 * dist13;
		llIntersect = DestVincenty(pt1, dAz13, distarray[1]);
		DistVincenty(pt2, llIntersect, &result);
		aacrs23 = result.azimuth;
		errarray[1] = SignAzimuthDifference(aacrs23, dAz23);

		int k = 0;
		double dErr = 0;
		int nMaxCount = 15;

		while(k == 0 || ((dErr > dTol) && (k <= nMaxCount)))
		{
			FindLinearRoot(distarray, errarray, dist13);
			LLPoint newPt = DestVincenty(pt1, dAz13, dist13);
			DistVincenty(pt2, newPt, &result);
			aacrs23 = result.azimuth;

			DistVincenty(newPt, llIntersect, &result);
			dErr = result.distance;

			distarray[0] = distarray[1];
			distarray[1] = dist13;
			errarray[0] = errarray[1];
			errarray[1] = SignAzimuthDifference(aacrs23, dAz23);
			k++;
			llIntersect = newPt;
		}
		// display if k == maxinteratorcount (10) and show error message
		// because results might not have converged.
		if(k > nMaxCount && dErr > 1e-8)
			return false;

		if(bSwapped)
		{
			LLPoint newPt = pt1;
			pt1 = pt2;
			pt2 = newPt;
			double aaz13 = dAz13;
			dAz13 = dAz23;
			dAz23 = aaz13;
			dist13 = dist23;
		}
		DistVincenty(llIntersect, pt1, &result);
		az31 = result.azimuth;
		dist13 = result.distance;

		DistVincenty(llIntersect, pt2, &result);
		az32 = result.azimuth;
		dist23 = result.distance;

		return true;
	}