static Line[] mergeSegments(Line[] segsOrig) {
        int n = segsOrig.length;
        Line[] segs = new Line[n];
        for (int i = 0; i < n; i++) {
            segs[i] = segsOrig[i].a.compareTo(segsOrig[i].b) < 0
                    ? segsOrig[i]
                    : new Line(segsOrig[i].b, segsOrig[i].a);
        }
        for (int i = 0; i < n; i++) {
            for (int j = i + 1; j < n; j++) {
                Line l1 = segs[i];
                Line l2 = segs[j];
                boolean mergable = approxEquals(l1.b.subtract(l1.a).cross(
                        l2.b.subtract(l2.a)), 0)
                        && intersectsLP(l1.a, l1.b, l2.a)
                        && ccw(l1.a, l1.b, l2.b) != 2
                        && ccw(l2.a, l2.b, l1.b) != 2;
                if (mergable) {
                    segs[i--] = new Line(Collections.min(Arrays.asList(l1.a, l2.a)),
                            Collections.max(Arrays.asList(l1.b, l2.b)));
                    segs[j] = segs[--n];
                    break;
                }
            }
        }
        Line[] ret = new Line[n];
        System.arraycopy(segs, 0, ret, 0, n);
        return ret;
        // return Arrays.copyOf(segs, n);  // for Java6
    }