def calculate_3D_intersection_distances(alt_p, volume_id, airspace_volume,
                                        entry_distance, exit_distance,
                                        entry_altitude, exit_altitude,
                                        include_horizontal_exit):
    """
    Calculate path distances where an AltitudeProfile intersects an AirspaceVolume.

    Note: this function calculates vertical intersections and determines
    whether horizontal intersections are valid considering the vertical range
    of the airspace_volume.

    Parameters
    ----------
    alt_p: AltitudeProfile
        The altitude profile of the flight.

    volume_id: string
        The id of the airspace volume.

    airspace_volume: AirspaceVolume
        The airspace volume.

    entry_distance, exit_distance: floats
        The horizontal entry and exit distances [Nautical Miles].

    entry_altitude, exit_altitude: floats
        The altitudes at the horizontal entry and exit distances [feet].

    include_horizontal_exit: bool
        A flag to indicate if horizontal exit distances are required.

    Returns
    -------
    distances: an array of floats
        The unordered intersection distances [Nautical Miles].
        Empty if no intersections found.

    """
    distances = []

    min_alt, max_alt = alt_p.altitude_range(entry_distance, exit_distance)
    if airspace_volume.vertical_intersection(min_alt, max_alt):
        # is the horizontal entry intersection valid?
        if airspace_volume.is_inside(entry_altitude):
            distances.append(entry_distance)

        # if there are vertical intersections with the bottom of the airspace volume
        if airspace_volume.bottom_intersection(min_alt, max_alt):
            distances.extend(alt_p.intersection_distances(airspace_volume.bottom_altitude,
                                                          entry_distance, exit_distance))

        # if there are vertical intersections with the top of the airspace volume
        if airspace_volume.top_intersection(min_alt, max_alt):
            distances.extend(alt_p.intersection_distances(airspace_volume.top_altitude,
                                                          entry_distance, exit_distance))

        # is the horizontal exit intersection valid?
        if include_horizontal_exit and airspace_volume.is_inside(exit_altitude):
            distances.append(exit_distance)

    return distances