internal void FindClusterCandidate_(int xyindex, com.epl.geometry.Clusterer.ClusterCandidate candidate)
        {
            com.epl.geometry.Point2D pointOfInterest = new com.epl.geometry.Point2D();
            m_shape.GetXY(xyindex, pointOfInterest);
            double x_0 = pointOfInterest.x - m_origin.x;
            double x   = x_0 * m_inv_cell_size;
            double y0  = pointOfInterest.y - m_origin.y;
            double y   = y0 * m_inv_cell_size;
            int    xi  = (int)x;
            int    yi  = (int)y;

            // find the nearest neighbour in the 4 neigbouring cells.
            candidate.vertex   = -1;
            candidate.distance = com.epl.geometry.NumberUtils.DoubleMax();
            com.epl.geometry.Clusterer.ClusterCandidate c = new com.epl.geometry.Clusterer.ClusterCandidate();
            for (int dx = 0; dx <= 1; dx += 1)
            {
                for (int dy = 0; dy <= 1; dy += 1)
                {
                    int bucket_ptr = m_hash_table.GetFirstInBucket(HashFunction_(xi + dx, yi + dy));
                    if (bucket_ptr != com.epl.geometry.IndexHashTable.NullNode())
                    {
                        GetNearestNeighbourCandidate_(xyindex, pointOfInterest, bucket_ptr, c);
                        if (c.vertex != com.epl.geometry.IndexHashTable.NullNode() && c.distance < candidate.distance)
                        {
                            candidate = c;
                        }
                    }
                }
            }
        }
 internal void GetNearestNeighbourCandidate_(int xyindex, com.epl.geometry.Point2D pointOfInterest, int bucket_ptr, com.epl.geometry.Clusterer.ClusterCandidate candidate)
 {
     candidate.vertex   = -1;
     candidate.distance = com.epl.geometry.NumberUtils.DoubleMax();
     com.epl.geometry.Point2D pt = new com.epl.geometry.Point2D();
     for (int node = bucket_ptr; node != -1; node = m_hash_table.GetNextInBucket(node))
     {
         int xyind = m_hash_table.GetElement(node);
         if (xyindex == xyind)
         {
             continue;
         }
         m_shape.GetXY(xyind, pt);
         if (IsClusterCandidate_(pointOfInterest.x, pointOfInterest.y, pt.x, pt.y, m_sqr_tolerance))
         {
             pt.Sub(pointOfInterest);
             double l = pt.Length();
             if (l < candidate.distance)
             {
                 candidate.distance = l;
                 candidate.vertex   = xyind;
             }
         }
     }
 }