/**
* <pre>
* author : jason
* e-mail : 1170321738@qq.com
* time : 2019/03/19
* desc : 主要进行几何计算。其中Point是业务中需要的一个类,在这个判断中只需要有x,y坐标就可以了,等同于PointF
* version: 1.0
* </pre>
*/
public class MathUtil {
/**
* 判断某点是否在给定区域内
*
* @param pointList
* @param x
* @param y
* @return true在区域内, false不在
*/
public static boolean pointInArea(List<Point> pointList, float x, float y) {
int i, j;
boolean in = false;
int nPol = pointList.size();
for (i = 0, j = nPol - 1; i < nPol; j = i++) {
if ((((pointList.get(i).getY() <= y) && (y < pointList.get(j).getY())) ||
((pointList.get(j).getY() <= y) && (y < pointList.get(i).getY()))) &&
(x < (pointList.get(j).getX() - pointList.get(i).getX()) * (y - pointList.get(i).getY()) / (pointList.get(j).getY() - pointList.get(i).getY()) + pointList.get(i).getX()))
in = !in;
}
return in;
}
/**
* 判断某点是否在给定路径上,主要有两种实现方式,我选择了第二种。
* [1]顺序取出两点,判断当前点是否在这两个点的矩形内。这种方式适合点比较密集的路径。
* [2]根据两点得到每一段线段的方程,然后将点的坐标带入看是否符合。这种方式判断过于严格,很难点到,需要优化。
*
* @param pointList
* @param x
* @param y
* @return
*/
public static boolean pointInPath(List<Point> pointList, float x, float y) {
boolean in = false;
//为了提高选中率,需要做一个近似处理,可以自己调整大小
float fx = 1;
float fy = 1;
for (int i = 0; i < pointList.size() - 1; i++) {
Point point1 = pointList.get(i);
Point point2 = pointList.get(i + 1);
if (point1.getX() == point2.getX()) {//斜率不存在
if (x >= point1.getX() - fx && x <= point1.getX() + fx && y >= Math.min(point1.getY(), point2.getY()) - fy && y <= Math.max(point1.getY(), point2.getY()) + fy) {
in = true;
break;
}
} else {
//算出两点之间的斜率
float k = (point2.getY() - point1.getY()) / (point2.getX() - point1.getX());
float b = point1.getY() - k * point1.getX();
float realY = x * k + b;
if (y > realY - fy && y < realY + fy) {
in = true;
break;
}
}
}
return in;
}
}