@Test
    public void testVisibilityGraph() {
        Point[] ps = Arrays.copyOf(aConvex, aConvex.length + 3);
        ps[ps.length - 3] = p(-4, -2);
        ps[ps.length - 2] = p(5, 7);
        ps[ps.length - 1] = p(11, 6);
//        System.out.println(Arrays.toString(ps));
        AdjGraph g = visibilityGraph(ps, new Point[][] { aConvex });
        //        for (ArrayList<Edge> edges : g.edges) {
        //            System.out.println(edges);
        //        }
        Edge[] existingEdges = {
                new Edge(2, 1, sqrt(34)), new Edge(5, 6, sqrt(41)), new Edge(6, 0, 2),
                new Edge(5, 6, sqrt(41)), new Edge(6, 7, sqrt(18)),
                new Edge(7, 1, sqrt(125)), new Edge(8, 3, 6), new Edge(8, 9, sqrt(37)), };
        int[][] noEdgeTable = {
                { 0, 2 }, { 1, 4 }, { 7, 5 }, { 7, 2 }, { 7, 8 }, { 8, 2 }, };
        for (Edge edge : existingEdges) {
            assertHasEdge(g, edge);
        }
        for (int[] is : noEdgeTable) {
            assertHasNoEdge(g, is[0], is[1]);
        }

        ps = new Point[18 + 5];
        int i = 0;
        ps[i++] = p(-9, -9);
        ps[i++] = p(4, -3);
        ps[i++] = p(9, 9);
        ps[i++] = p(-4, 3);
        Point[][] objs = { { p(-10, -10), p(10, -10), p(10, 10), p(-10, 10) },  // 4..7, 外殻
                { p(-5, -5), p(0, -5), p(0, 0), p(-5, 0) },  // 8..11, objs[2]と一点で接する
                { p(0, 0), p(5, 0), p(5, 5), p(0, 5) },  // 12..15, objs[3]と辺の一部が接する
                { p(1, 0), p(2, -1), p(3, 0) },  // 16..18
                { p(-3, -1), p(-1, -1), p(-2, 1) },  // 19..21, objs[1]と交差する
        };
        for (Point[] obj : objs) {
            for (Point p : obj) {
                ps[i++] = p;
            }
        }
        ps[i++] = p(0, -12);  // 22, objs[0]の外側
        g = visibilityGraph(ps, objs);
        int degs[] = {
                0x4, 7, 4, 6, 0x3, 3, 2, 2, 0x3, 9, 8, 5, 0x8, 6, 3, 7, 0x5, 7, 5, 0x1,
                1, 5, 0x2 };
        for (int j = 0; j < i; j++) {
            assertEquals(degs[j], g.edges[j].size());
            // degs[16] と degs[18] は共に4とすべきかもしれないが、POJ2678的には5でよい
        }
        existingEdges = new Edge[] {
                new Edge(10, 12, 0), new Edge(16, 18, 2), new Edge(1, 13, sqrt(10)),
                new Edge(1, 2, 13) };
        noEdgeTable = new int[][] { { 1, 16 }, { 0, 1 }, { 0, 4 } };
        for (Edge edge : existingEdges) {
            assertHasEdge(g, edge);
        }
        for (int[] is : noEdgeTable) {
            assertHasNoEdge(g, is[0], is[1]);
        }
    }