一.准备:利用commons-math3 数学包封装的向量进行计算。
二.前提:输入参数为三点,两个向量共起点。
三.操作:
3.1)利用向量的相加构成的平行四边形法则来求角平分线,见图1.1、1.2
图1.1
图1.2
3.2)但是平行四边形的对角线不是角平分线,菱形的对角线才是角平分线,所以我们要对向量进行归一化,各分量除以模长,将其转为单位向量且方向不变,这样就可以构造菱形对角线了;在将归一化的两个向量相加即可得到对角线向量(如图1.3)。
( 图1.3)
public static Point getAngularBisectorPoint(Point left, Point right, Point wareHouse) {
RealVector vector1 = new ArrayRealVector(new double[]{left.x - wareHouse.x, left.y - wareHouse.y}); //RealVector common-math3
RealVector vector2 = new ArrayRealVector(new double[]{right.x - wareHouse.x, right.y - wareHouse.y});
RealVector vector = vector1.mapDivide(vector1.getNorm()).add(vector2.mapDivide(vector2.getNorm()));
double[] vectorArray = vector.toArray();
double x = vectorArray[0] + wareHouse.x;
double y = vectorArray[1] + wareHouse.y;
return new Point(x, y); //注意1这是锐角情况,钝角就反向延长 。2.结果存在细微误差
}
3.3) 将上面代码求得的点与中心仓库点连线即可得到角平分线
3.4) 利用向量的向量积来判断其他点位于角平分线的哪一侧;由公式得
P = ( x1, y1 ),Q = ( x2, y2 )
P×Q = x1y2 - x2y1;
若 P × Q > 0 , 则P在Q的顺时针方向。
若 P × Q < 0 , 则P在Q的逆时针方向。
若 P × Q = 0 , 则P与Q共线,但可能同向也可能反向。
public static void dividePoints(List<Point> points, Point wareHouse, Point angularBisector) {
Point point = new Point(angularBisector.x - wareHouse.x,
angularBisector.y - wareHouse.y);
List<Point> onePartClients = new ArrayList<>();
List<Point> otherPartClients = new ArrayList<>();
for (Point point1 : points) {
Point point2 = new Point(point1.x - wareHouse.x,
point1.y - wareHouse.y);
double data = point.x * point2.y - point2.x * point.y;
if (data < 0) { // point 在 point2 的逆时针
onePartClients.add(point1);
} else {
otherPartClients.add(point1);
}
}
}
三.参考文献
https://blog.youkuaiyun.com/m0_37667021/article/details/76498623
https://blog.youkuaiyun.com/whiteForever/article/details/82762540