判断两条线段的相对位置,用int[] s1表示第一条线段,int[] s2表示第二条线段,即两线段两端点的坐标为:
(s1[0],s1[1]),(s1[2],s1[3])和(s2[0],s2[1]),(s2[2],s2[3])。如果两线段没有交点则返回"NO",只有一个交点则返回"POINT",多个交点则返回"SEGMENT"。
public class TestLine {
/**
* @return 上1下-1左-1右1中0
*/
public static int relative(int x1, int y1, int x2, int y2, int px, int py) {
x2 -= x1; //把x1,y1看成原点,转换成相对原点的坐标
y2 -= y1;
px -= x1;
py -= y1;
int flag = px * y2 - py * x2; //判断P点在线段所在直线的上方还是下方还是线段上
if (flag == 0) {
flag = px * x2 + py * y2; //向量相乘,x1*x2+y1*y2=|a|*|b|*cosα,正负可推出相对原点(x1,y1)的位置
if (flag > 0) {
px -= x2;
py -= y2; //转换px,py相对x2,y2的坐标,即把x2,y2看成原点
flag = px * x2 + py * y2; //向量相乘
if (flag < 0) { //点位于线段上
flag = 0;
}
}
}
return (flag < 0) ? -1 : ((flag > 0) ? 1 : 0);
}
public static String testState(int[] s1, int[] s2) {
int[] state = new int[4];
state[0] = relative(s2[0], s2[1], s2[2], s2[3], s1[0], s1[1]);
state[1] = relative(s2[0], s2[1], s2[2], s2[3], s1[2], s1[3]);
state[2] = relative(s1[0], s1[1], s1[2], s1[3], s2[0], s2[1]);
state[3] = relative(s1[0], s1[1], s1[2], s1[3], s2[2], s2[3]);
int zeroCount = 0;
for (int i = 0; i < state.length; i++) {
if (state[i] == 0)
zeroCount++;
}
if ((state[0] * state[1] > 0) || (state[2] * state[3] > 0)) {
return "NO";
} else if (zeroCount > 1) {
if (zeroCount > 2)
return "SEGMENT";
int index1 = 0;
int index2 = 0;
if (state[0] != 0)
index1 = 2;
if (state[2] != 0)
index2 = 2;
if (s1[index1] == s2[index2] && s1[++index1] == s2[++index2]) {
return "POINT";
}
return "SEGMENT";
} else
return "POINT";
}
public static void main(String[] args) {
int[] s1 = new int[] { 0, 0, 0, 1 };
int[] s2 = new int[] { 0, 1, 0, 2 };
System.out.println(testState(s1, s2));
}
}
输出结果:POINT