class FootprintCalculator {

    public GeographicConvexQuadrilateral calculateFootprint2(PlatformMetadata metadata, double fieldOfViewWidth,
            double fieldOfViewHeight)
    {
        double altitude = metadata.getLocation().getAltM();

        double widthAngleDeg = fieldOfViewWidth / 2;
        double heightAngleDeg = fieldOfViewHeight / 2;
        double widthAngle = Math.toRadians(widthAngleDeg);
        double heightAngle = Math.toRadians(heightAngleDeg);

        double yawAngle = metadata.getCameraYawAngle() + metadata.getYawAngle();
        double pitchAngle = metadata.getPitchAngle() + metadata.getCameraPitchAngle();

        double pitchRads = Math.toRadians(90 + pitchAngle);
        double yawRads = Math.toRadians(-yawAngle);

        double groundDistanceTop = altitude * Math.tan(pitchRads + heightAngle);
        double groundDistanceBottom = altitude * Math.tan(pitchRads - heightAngle);

        double aircraftToTopDistance = Math.sqrt(Math.pow(groundDistanceTop, 2) + Math.pow(altitude, 2));
        double aircraftToBottomDistance = Math.sqrt(Math.pow(groundDistanceBottom, 2) + Math.pow(altitude, 2));

        double lonDeltaTopM = aircraftToTopDistance * Math.tan(widthAngle);
        double lonDeltaBottomM = aircraftToBottomDistance * Math.tan(widthAngle);

        LatLonAlt pos = LatLonAlt.createFromDegrees(metadata.getLocation().getLatD(), metadata.getLocation().getLonD());

        LatLonAlt bottomLat = calculateIntersectionPoint(pos, altitude, 0, pitchAngle - heightAngleDeg);
        LatLonAlt topLat = calculateIntersectionPoint(pos, altitude, 0, pitchAngle + heightAngleDeg);

        LatLonAlt topLeft = GeographicBody3D.greatCircleEndPosition(topLat, Math.toRadians(270),
                WGS84EarthConstants.RADIUS_EQUATORIAL_M, lonDeltaTopM);
        LatLonAlt topRight = GeographicBody3D.greatCircleEndPosition(topLat, Math.toRadians(90),
                WGS84EarthConstants.RADIUS_EQUATORIAL_M, lonDeltaTopM);
        LatLonAlt bottomLeft = GeographicBody3D.greatCircleEndPosition(bottomLat, Math.toRadians(270),
                WGS84EarthConstants.RADIUS_EQUATORIAL_M, lonDeltaBottomM);
        LatLonAlt bottomRight = GeographicBody3D.greatCircleEndPosition(bottomLat, Math.toRadians(90),
                WGS84EarthConstants.RADIUS_EQUATORIAL_M, lonDeltaBottomM);

        Vector2d posVector = pos.asVec2d();
        Vector2d topLeftVector = topLeft.asVec2d().subtract(posVector).rotateAroundOrigin(yawRads).add(posVector);
        Vector2d bottomLeftVector = bottomLeft.asVec2d().subtract(posVector).rotateAroundOrigin(yawRads).add(posVector);
        Vector2d bottomRightVector = bottomRight.asVec2d().subtract(posVector).rotateAroundOrigin(yawRads).add(posVector);
        Vector2d topRightVector = topRight.asVec2d().subtract(posVector).rotateAroundOrigin(yawRads).add(posVector);

        topLeft = LatLonAlt.createFromDegrees(topLeftVector.getY(), topLeftVector.getX());
        bottomLeft = LatLonAlt.createFromDegrees(bottomLeftVector.getY(), bottomLeftVector.getX());
        bottomRight = LatLonAlt.createFromDegrees(bottomRightVector.getY(), bottomRightVector.getX());
        topRight = LatLonAlt.createFromDegrees(topRightVector.getY(), topRightVector.getX());

        return new GeographicConvexQuadrilateral(new GeographicPosition(topLeft), new GeographicPosition(topRight),
                new GeographicPosition(bottomRight), new GeographicPosition(bottomLeft));
    }

}