Line findBestLine(GraphPoint[] points)
{
Line bestLine =null;
int bestCount=0;
HashMap<Double ,ArrayList<Line>> linesBySlope=
new HashMap<Double,ArrayList<Line>>();
for(int i=0;i<points.length;i++)
{
for(int j=i+1;j<points.length;j++)
{
Line line=new Line(points[i],points[j]);
insertLine(linesBySlope,line);
int count=countEquivalentLines(linesBySlope,line);
if(count>bestCount)
{
bestLine=line;
bestCount=count;
}
}
}
return bestLine;
}
int countEquivalLines(HashMap<Double,ArrayList<line>> linesBySlope,Line line)
{
double key=Line.floorToNearestEpsilon(line.slope);
double eps=Line.epsilon;
int count=countEquivalentLines(linesBySlope.get(key),line)+countEquivalentLines(linesBySlope.get(key-eps),line)+countEquivalentLines(linesBySlope.get(key+eps),line);
return count;
}
void insertLine(HashMap<Double,ArrayList<Line>> liensBySlope,Line line)
{
ArrayList<Line> lines=null;
double key=Line.floorToNearestEpsilon(line.slope);
if(!linesBySlope.containsKey(key))
{
lines=new ArrayList<Line>();
linesBySlope.put(key,lines);
}
else
{
lines=linesBySlope.get(key);
}
lines.add(line);
}
public class Line
{
public static double epsilon=.0001;
public double slope,intercept;
private boolean infinite_slope=false;
public Line(GraphPoint p,GraphPoint q)
{
if(Math.abs(p.x-q.x)>epsilon)
{
slope=(p.y-q.y)/(p.x-q.x);//斜率
intercept=p.y-slope*p.x;//利用y=mx+b计算y轴截距
}
else
{
infinite_slope=true;
intercept=p.x;//x轴截距。因为斜率无穷大
}
}
public static double floorToNearestEpsilon(double d)
{
int r=(int)(d/epsilon);
return ((double)r)*epsilon;
}
public boolean isEquivalent(double a,double b)
{
return (Math.abs(a-b)<epsilon);
}
public boolean isEquivalent(Object o)
{
Line l=(Line)o;
if(isEquivalent(l.slope,slope)&& isEquivalent(l.intercept,intercept)&&(infinitte_slope==l.infinite_slope))
{
return true;
}
return false;
}
}
计算直线的斜率务必小心谨慎,直线有可能完全垂直,也即它没有y轴截距且斜率无穷大。可用单独的标记(infinite_slope)跟踪记录。在equals方法中,必须检查这个条件。
版权声明:本文为博主原创文章,未经博主允许不得转载。