public ClosestPointOfApproach closestPointOfApproach() {
        checkState(
            point1.time().equals(point2.time()),
            "This function can only be applied to points at the same Instant"
        );

        Vector initialVectorBetweenPoints = vectorBetweenPointsInNm();
        Vector velocityDifference = velocityInKnots(point2).minus(velocityInKnots(point1));

        //will be negative if aircraft are diverging
        double timeOfMinDistanceInHours = timeToProjectedMinDistanceInHours(
            initialVectorBetweenPoints,
            velocityDifference
        );

        if (!Double.isFinite(timeOfMinDistanceInHours) || timeOfMinDistanceInHours <= 0) {
            return new ClosestPointOfApproach(Duration.ZERO, lateralDistance());
        }

        long timeOfMinDistanceInMillis = (long) (timeOfMinDistanceInHours * 1000 * 60 * 60);

        Vector vectorBetweenPointsAtCpa = initialVectorBetweenPoints.plus(
            velocityDifference.times(timeOfMinDistanceInHours)
        );

        return new ClosestPointOfApproach(
            Duration.ofMillis(timeOfMinDistanceInMillis),
            Distance.ofNauticalMiles(vectorBetweenPointsAtCpa.magnitude())
        );
    }
@Test
    public void closestPointOfApproachRequiresPointsFromTheSameTime() {
        Point p1 = Point.builder().latLong(0.0, 0.0).time(EPOCH).build();
        Point p2 = Point.builder().latLong(0.0, 0.0).time(EPOCH.plusSeconds(1)).build();

        PointPair points = new PointPair(p1, p2);

        assertThrows(
            IllegalStateException.class,
            () -> points.closestPointOfApproach(),
            "The points have to be from the same time."
        );
    }