public double calculateElevationBasedOnThreePoints(double lat, double lon, double lat0,
                                                       double lon0, double ele0, double lat1, double lon1, double ele1, double lat2,
                                                       double lon2, double ele2) {

        double dlat10 = lat1 - lat0;
        double dlon10 = lon1 - lon0;
        double dele10 = ele1 - ele0;
        double dlat20 = lat2 - lat0;
        double dlon20 = lon2 - lon0;
        double dele20 = ele2 - ele0;

        double a = dlon10 * dele20 - dele10 * dlon20;
        double b = dele10 * dlat20 - dlat10 * dele20;
        double c = dlat10 * dlon20 - dlon10 * dlat20;

        if (Math.abs(c) < EPSILON) {
            double dlat21 = lat2 - lat1;
            double dlon21 = lon2 - lon1;
            double dele21 = ele2 - ele1;

            double l10 = dlat10 * dlat10 + dlon10 * dlon10 + dele10 * dele10;
            double l20 = dlat20 * dlat20 + dlon20 * dlon20 + dele20 * dele20;
            double l21 = dlat21 * dlat21 + dlon21 * dlon21 + dele21 * dele21;

            if (l21 > l10 && l21 > l20) {
                return calculateElevationBasedOnTwoPoints(lat, lon, lat1, lon1, ele1, lat2, lon2,
                        ele2);
            } else if (l20 > l10 && l20 > l21) {
                return calculateElevationBasedOnTwoPoints(lat, lon, lat0, lon0, ele0, lat2, lon2,
                        ele2);
            } else {
                return calculateElevationBasedOnTwoPoints(lat, lon, lat0, lon0, ele0, lat1, lon1,
                        ele1);
            }

        } else {
            double d = a * lat0 + b * lon0 + c * ele0;
            double ele = (d - a * lat - b * lon) / c;
            return round2(ele);
        }
    }
@Test
    public void calculatesElevationOnThreePoints() {
        assertEquals(-0.88, elevationInterpolator.calculateElevationBasedOnThreePoints(0, 0, 1,
                2, 3, 4, 6, 9, 12, 11, 9), PRECISION);
        assertEquals(15, elevationInterpolator.calculateElevationBasedOnThreePoints(10, 0, 0, 0, 0,
                10, 10, 10, 10, -10, 20), PRECISION);
        assertEquals(5, elevationInterpolator.calculateElevationBasedOnThreePoints(5, 5, 0, 0, 0,
                10, 10, 10, 20, 20, 20), PRECISION);
    }