class LaserMeasurement {

    @NonNull
    public static List<LaserMeasurement> reorder(@NonNull List<LaserMeasurement> points) {
        // Find height and width range
        final Range xRange = new Range();
        final Range yRange = new Range();
        for (LaserMeasurement point : points) {
            xRange.expand(point.x);
            yRange.expand(point.y);
        }
        if (xRange.min < 0 && xRange.max <= 0 && yRange.min >= 0) {
            // Quadrant 4: Assume coordinates are reversed y,x
            final List<LaserMeasurement> swapped = new ArrayList<>();
            for (LaserMeasurement point : points) {
                //noinspection SuspiciousNameCombination
                swapped.add(new LaserMeasurement(point.y, point.x));
            }
            // Sort by horiz
            Collections.sort(swapped, (l1, l2) -> Double.compare(l1.x, l2.x));
            return swapped;
        } else if (yRange.min >= 0 && yRange.max > 0) {
            // Quadrant 1: Assume lasering from bottom
            final List<LaserMeasurement> reversed = new ArrayList<>();
            for (LaserMeasurement point : points) {
                reversed.add(new LaserMeasurement(xRange.max - point.x, point.y - yRange.max));
            }
            // Add reversed 0,0
            reversed.add(new LaserMeasurement(xRange.max, -yRange.max));
            // Sort by horiz
            Collections.sort(reversed, (l1, l2) -> Double.compare(l1.x, l2.x));
            return reversed;
        } else {
            // Quadrant 2: default x,y
            final List<LaserMeasurement> sorted = new ArrayList<>(points);
            // Sort by horiz
            Collections.sort(sorted, (l1, l2) -> Double.compare(l1.x, l2.x));
            return sorted;
        }
    }

    public  LaserMeasurement(double x, double y);

}