@Test
  public void considerConnect() {
    SquareNode node0 = new SquareNode();
    SquareNode node1 = new SquareNode();

    // first do it with no connections
    SquaresIntoCrossClusters alg = new SquaresIntoCrossClusters(5, -1);

    alg.considerConnect(node0, 0, node1, 0, 4);

    assertTrue(node0.edges[0] == node1.edges[0]);
    assertTrue(node0.edges[0].a == node0);
    assertTrue(node0.edges[0].b == node1);

    // try to connect when its worse
    alg.considerConnect(node0, 0, node1, 1, 4.5);
    assertTrue(node0.edges[0].a == node0);
    assertTrue(node1.edges[1] == null);
    alg.considerConnect(node1, 1, node0, 0, 4.5);
    assertTrue(node0.edges[0].a == node0);
    assertTrue(node1.edges[1] == null);

    // have one be better
    alg.considerConnect(node0, 0, node1, 1, 3.5);
    assertTrue(node0.edges[0] == node1.edges[1]);
    assertTrue(node0.edges[0].a == node0);
    assertTrue(node0.edges[0].b == node1);
    assertTrue(node1.edges[0] == null);
  }
  /** Create a simple perfect cluster. Do a crude test based on number of edge histogram */
  @Test
  public void process_simple() {
    SquaresIntoCrossClusters alg = new SquaresIntoCrossClusters(0.05, -1);

    List<Polygon2D_F64> squares = new ArrayList<Polygon2D_F64>();
    squares.add(createSquare(7, 8));
    squares.add(createSquare(9, 8));
    squares.add(createSquare(8, 9));
    squares.add(createSquare(7, 10));
    squares.add(createSquare(9, 10));

    List<List<SquareNode>> clusters = alg.process(squares);

    assertEquals(1, clusters.size());

    List<SquareNode> cluster = clusters.get(0);

    int connections[] = new int[5];
    for (SquareNode n : cluster) {
      connections[n.getNumberOfConnections()]++;
    }

    assertEquals(0, connections[0]);
    assertEquals(4, connections[1]);
    assertEquals(0, connections[2]);
    assertEquals(0, connections[3]);
    assertEquals(1, connections[4]);
  }
  /**
   * Tests the corner distance threshold. two nodes should be barely within tolerance of each other
   * with the 3rd barely not in tolerance
   */
  @Test
  public void process_connect_threshold() {
    SquaresIntoCrossClusters alg = new SquaresIntoCrossClusters(0.2, -1);

    List<Polygon2D_F64> squares = new ArrayList<Polygon2D_F64>();
    squares.add(createSquare(5, 6));
    squares.add(createSquare(6.20001, 7));
    squares.add(createSquare(6.1999999, 5));

    List<List<SquareNode>> clusters = alg.process(squares);

    assertEquals(2, clusters.size());
  }
  @Test
  public void getCornerIndex() {
    SquareNode node = new SquareNode();
    node.corners = new Polygon2D_F64(4);
    node.corners.get(0).set(5, 6);
    node.corners.get(1).set(6, 7);
    node.corners.get(2).set(7, 8);
    node.corners.get(3).set(8, 9);

    SquaresIntoCrossClusters alg = new SquaresIntoCrossClusters(5, -1);

    assertEquals(0, alg.getCornerIndex(node, 5, 6));
    assertEquals(1, alg.getCornerIndex(node, 6, 7));
    assertEquals(2, alg.getCornerIndex(node, 7, 8));
    assertEquals(3, alg.getCornerIndex(node, 8, 9));
  }
  @Test
  public void candidateIsMuchCloser() {
    SquareNode node0 = new SquareNode();
    SquareNode node1 = new SquareNode();

    node0.largestSide = 2;
    node1.largestSide = 1;

    SquaresIntoCrossClusters alg = new SquaresIntoCrossClusters(5, -1);

    // test obvious cases
    assertTrue(alg.candidateIsMuchCloser(node0, node1, 0));
    assertFalse(alg.candidateIsMuchCloser(node0, node1, 20));

    double frac = alg.tooFarFraction;
    node1.corners = createSquare(12, 10);
    // the closest neighboring node should be 1 away
    assertTrue(alg.candidateIsMuchCloser(node0, node1, Math.pow(2 * frac - 1e-6, 2)));
    assertFalse(alg.candidateIsMuchCloser(node0, node1, Math.pow(2 * frac + 1e-6, 2)));
  }