package com.bioxx.jmapgen.com.nodename.delaunay;
import com.bioxx.jmapgen.Point;
public final class EdgeList
{
private double _deltax;
private double _xmin;
private int _hashsize;
private Halfedge[] _hash;
private Halfedge _leftEnd;
public Halfedge getLeftEnd()
{
return _leftEnd;
}
private Halfedge _rightEnd;
public Halfedge getRightEnd()
{
return _rightEnd;
}
public EdgeList(double xmin, double deltax, int sqrt_nsites)
{
_xmin = xmin;
_deltax = deltax;
_hashsize = 2 * sqrt_nsites;
_hash = new Halfedge[_hashsize];
// two dummy Halfedges:
_leftEnd = Halfedge.createDummy();
_rightEnd = Halfedge.createDummy();
_leftEnd.edgeListLeftNeighbor = null;
_leftEnd.edgeListRightNeighbor = _rightEnd;
_rightEnd.edgeListLeftNeighbor = _leftEnd;
_rightEnd.edgeListRightNeighbor = null;
_hash[0] = _leftEnd;
_hash[_hashsize - 1] = _rightEnd;
}
/**
* Insert newHalfedge to the right of lb
* @param lb
* @param newHalfedge
*
*/
public void insert(Halfedge lb, Halfedge newHalfedge)
{
newHalfedge.edgeListLeftNeighbor = lb;
//if(lb.edgeListRightNeighbor != null)
newHalfedge.edgeListRightNeighbor = lb.edgeListRightNeighbor;
//if(lb.edgeListRightNeighbor != null)
lb.edgeListRightNeighbor.edgeListLeftNeighbor = newHalfedge;
lb.edgeListRightNeighbor = newHalfedge;
}
/**
* This function only removes the Halfedge from the left-right list.
* We cannot dispose it yet because we are still using it.
* @param halfEdge
*
*/
public void remove(Halfedge halfEdge)
{
halfEdge.edgeListLeftNeighbor.edgeListRightNeighbor = halfEdge.edgeListRightNeighbor;
halfEdge.edgeListRightNeighbor.edgeListLeftNeighbor = halfEdge.edgeListLeftNeighbor;
halfEdge.edge = Edge.DELETED;
halfEdge.edgeListLeftNeighbor = halfEdge.edgeListRightNeighbor = null;
}
/**
* Find the rightmost Halfedge that is still left of p
* @param p
* @return
*
*/
public Halfedge edgeListLeftNeighbor(Point p)
{
int i, bucket;
Halfedge halfEdge;
/* Use hash table to get close to desired halfedge */
bucket = (int) ((p.x - _xmin)/_deltax * _hashsize);
if (bucket < 0)
{
bucket = 0;
}
if (bucket >= _hashsize)
{
bucket = _hashsize - 1;
}
halfEdge = getHash(bucket);
if (halfEdge == null)
{
for (i = 1; true; ++i)
{
if ((halfEdge = getHash(bucket - i)) != null) break;
if ((halfEdge = getHash(bucket + i)) != null) break;
}
}
/* Now search linear list of halfedges for the correct one */
if (halfEdge != null && (halfEdge == _leftEnd || (halfEdge != getRightEnd() && halfEdge.isLeftOf(p))))
{
do
{
halfEdge = halfEdge.edgeListRightNeighbor;
}
while (halfEdge != getRightEnd() && halfEdge.isLeftOf(p));
halfEdge = halfEdge.edgeListLeftNeighbor;
}
else
{
if(halfEdge != null)
{
do
{
halfEdge = halfEdge.edgeListLeftNeighbor;
}
while(halfEdge != _leftEnd && halfEdge.edge != null && !halfEdge.isLeftOf(p));
}
}
/* Update hash table and reference counts */
if (bucket > 0 && bucket <_hashsize - 1)
{
_hash[bucket] = halfEdge;
}
return halfEdge;
}
/* Get entry from hash table, pruning any deleted nodes */
private Halfedge getHash(int b)
{
Halfedge halfEdge = null;
if (b < 0 || b >= _hashsize)
{
return null;
}
try
{
halfEdge = _hash[b];
}
catch(Exception e){}
if (halfEdge != null && halfEdge.edge == Edge.DELETED)
{
/* Hash table points to deleted halfedge. Patch as necessary. */
_hash[b] = null;
// still can't dispose halfEdge yet!
return null;
}
else
{
return halfEdge;
}
}
}