Copyright Tristan Aubrey-Jones December 2005.
package tajy;
public class CycleSpotter
{
private long[] times; //last hit
private int[] hits; //number of hits at this spot
private double[] xCoords; //the x coord of this spot
private double[] yCoords; //the y coord of this spot
private long[] periods; //the the period since the last hit
private int pointer;
private final double threshold = 10;
private boolean arrayFull = false;
public CycleSpotter(int bufferSize)
{
pointer = 0;
times = new long[bufferSize];
hits = new int[bufferSize];
xCoords = new double[bufferSize];
yCoords = new double[bufferSize];
periods = new long[bufferSize];
}
private void incPointer()
{
pointer++;
if (pointer >= times.length)
{
pointer = 0;
arrayFull = true;
}
}
public void add(long time, double x, double y)
{
// search through pervious for matching
boolean added = false;
for (int i = 0; i != pointer; i++)
{
// if is the same coord (minus variance)
if (match(i, x, y))
{
// update that coordinate
periods[i] = time - times[i];
times[i] = time;
hits[i]++;
xCoords[i] = x;
yCoords[i] = y;
added = true;
break;
}
}
// if hasnt found existing
if (!added)
{
// if none write new at current pointer
periods[pointer] = 0;
hits[pointer] = 1;
times[pointer] = time;
xCoords[pointer] = x;
yCoords[pointer] = y;
// increment pointer
incPointer();
}
}
public void add(long time, Vector coord)
{
add(time, coord.getX(), coord.getY());
}
private boolean match(int i, double x, double y)
{
// get other coords
double x1 = xCoords[i];
double y1 = yCoords[i];
// return
return (((x > x1 - threshold) &&
(x < x1 + threshold)) &&
((y > y1 - threshold) &&
(y < y1 + threshold)));
}
public int getBestTarget(Vector pos)
{
int maxHits = 0;
double minDist = 99999;
int best = 0;
for (int i = 0; i != pointer; i++)
{
int hit = hits[i];
if (hit > maxHits)
{
double x = xCoords[i];
double y = yCoords[i];
maxHits = hit;
best = i;
minDist = pos.distanceTo(new Vector(x, y));
}
else if (hit == maxHits)
{
double x = xCoords[i];
double y = yCoords[i];
double dist = pos.distanceTo(new Vector(x, y));
if (dist < minDist)
{
minDist = dist;
best = i;
}
}
}
return best;
}
public long getNextTime(int i, long time)
{
long period = periods[i];
long start = times[i] + period;
while (start < time) start += period;
return start;
}
public int getVisits(int i)
{
return hits[i];
}
public double getX(int i)
{
return xCoords[i];
}
public double getY(int i)
{
return yCoords[i];
}
public Vector getPosition(int i)
{
return new Vector(getX(i), getY(i));
}
}