public static double[] getLastVisiblePointData( List<ProfilePoint> profile ) {
        if (profile.size() < 2) {
            throw new IllegalArgumentException("A profile needs to have at least 2 points.");
        }
        ProfilePoint first = profile.get(0);
        double baseElev = first.getElevation();
        Coordinate baseCoord = new Coordinate(0, 0);

        double minAzimuthAngle = Double.POSITIVE_INFINITY;
        double maxAzimuthAngle = Double.NEGATIVE_INFINITY;
        ProfilePoint minAzimuthPoint = null;
        ProfilePoint maxAzimuthPoint = null;
        for( int i = 1; i < profile.size(); i++ ) {
            ProfilePoint currentPoint = profile.get(i);
            double currentElev = currentPoint.getElevation();
            if (HMConstants.isNovalue(currentElev)) {
                continue;
            }
            currentElev = currentElev - baseElev;
            double currentProg = currentPoint.getProgressive();
            Coordinate currentCoord = new Coordinate(currentProg, currentElev);

            double azimuth = GeometryUtilities.azimuth(baseCoord, currentCoord);
            if (azimuth <= minAzimuthAngle) {
                minAzimuthAngle = azimuth;
                minAzimuthPoint = currentPoint;
            }
            if (azimuth >= maxAzimuthAngle) {
                maxAzimuthAngle = azimuth;
                maxAzimuthPoint = currentPoint;
            }
        }

        if (minAzimuthPoint == null || maxAzimuthPoint == null) {
            return null;
        }

        return new double[]{//
        /*    */minAzimuthPoint.elevation, //
                minAzimuthPoint.position.x, //
                minAzimuthPoint.position.y, //
                minAzimuthPoint.progressive, //
                minAzimuthAngle, //
                maxAzimuthPoint.elevation, //
                maxAzimuthPoint.position.x, //
                maxAzimuthPoint.position.y, //
                maxAzimuthPoint.progressive, //
                maxAzimuthAngle, //
        };

    }
public static double [ ] getLastVisiblePointData ( List < ProfilePoint > profile ) { if ( profile . size ( ) < 2 ) { throw new IllegalArgumentException ( "A profile needs to have at least 2 points." ) ; } ProfilePoint first = profile . get ( 0 ) ; double baseElev = first . getElevation ( ) ; Coordinate baseCoord = new Coordinate ( 0 , 0 ) ; double minAzimuthAngle = Double . POSITIVE_INFINITY ; double maxAzimuthAngle = Double . NEGATIVE_INFINITY ; ProfilePoint minAzimuthPoint = null ; ProfilePoint maxAzimuthPoint = null ; for ( int i = 1 ; i < profile . size ( ) ; i ++ ) { ProfilePoint currentPoint = profile . get ( i ) ; double currentElev = currentPoint . getElevation ( ) ; if ( HMConstants . isNovalue ( currentElev ) ) { continue ; } currentElev = currentElev - baseElev ; double currentProg = currentPoint . getProgressive ( ) ; Coordinate currentCoord = new Coordinate ( currentProg , currentElev ) ; double azimuth = GeometryUtilities . azimuth ( baseCoord , currentCoord ) ; if ( azimuth <= minAzimuthAngle ) { minAzimuthAngle = azimuth ; minAzimuthPoint = currentPoint ; } if ( azimuth >= maxAzimuthAngle ) { maxAzimuthAngle = azimuth ; maxAzimuthPoint = currentPoint ; } } if ( minAzimuthPoint == null || maxAzimuthPoint == null ) { return null ; } return new double [ ] { minAzimuthPoint . elevation , minAzimuthPoint . position . x , minAzimuthPoint . position . y , minAzimuthPoint . progressive , minAzimuthAngle , maxAzimuthPoint . elevation , maxAzimuthPoint . position . x , maxAzimuthPoint . position . y , maxAzimuthPoint . progressive , maxAzimuthAngle , } ; }
Return last visible point data for a profile points list.

<p>For the profile the min and max angles of "sight" are
calculated. The min azimuth angle represents the "upper"
line of sight, as thoght from the zenith.
<p>The max azimuth angle represents the "below the earth" line
of sight (think of a viewer looking in direction nadir).
<p>The return values are in an array of doubles containing:
<ul>
<li>[0] min point elev, </li>
<li>[1] min point x, </li>
<li>[2] min point y, </li>
<li>[3] min point progressive, </li>
<li>[4] min point azimuth, </li>
<li>[5] max point elev, </li>
<li>[6] max point x, </li>
<li>[7] max point y, </li>
<li>[8] max point progressive, </li>
<li>[9] max point azimuth </li>
</ul>

@param profile the profile to analize.
@return the last visible point parameters.