又是暴力破解的一天
而且还是个数学渣
刚看到这一题的时候真的崩溃,稍微列了一下公式后好一点,但又发现按这种解法情况太多
但是自己分的情况跪着也要分完
下面先列一下思路:我采用的是最普通的点斜式方程
-
计算两根直线斜率,判断两根线段的斜率是否存在
-
都存在
-
判断是否平行
-
平行但不重合
-
此时一定没有交点,返回空数组
-
-
重合
-
判断哪一部分重合并返回题目中所要求的最小点
-
-
不平行
- 计算出两根直线的点斜式方程
- 计算两根直线交点,并判断交点是否在两根线段范围内
-
-
-
有一根不存在(垂直于x轴)
-
直线一定重合,但线段不一定重合
-
计算斜率存在那根直线的点斜式方程
-
计算直线交点,并判断交点是否在两根线段范围内
-
-
两根都不存在(两根都垂直于x轴)
-
只可能平行或者重合
-
判断是否重合
-
重合,则判断哪一部分重合并返回题目中所要求的最小点
-
平行,返回空数组
-
-
-
下面是在提交过程中修改了很多次的代码...
代码能力是挺差劲的,就看看思路吧(也没啥好看的)
提交时修改的几个点:
1. 计算k(斜率)时,要先强转成double,否则int类型会出错
2. double类型是存在infinity类型的,所以要判断,直接是抛不出异常的
3. 判断交点是否在线段内时不要忘记等号
最后结果是(我尽力了):
执行用时 :8 ms, 在所有 Java 提交中击败了18.52%的用户
内存消耗 :39 MB, 在所有 Java 提交中击败了100.00%的用户
public static double[] intersection(int[] start1, int[] end1, int[] start2, int[] end2) {
//计算k1 k2
double x_res = 0;
double y_res = 0;
try {
//k1 k2均存在
double k1 = (double)(end1[1] - start1[1])/(double)(end1[0] - start1[0]);
if(k1 == Double.POSITIVE_INFINITY || k1 == Double.NEGATIVE_INFINITY) {
throw new Exception();
}
double b1 = start1[1] - k1*start1[0];
double k2 = (double)(end2[1] - start2[1])/(double)(end2[0] - start2[0]);
double b2 = start2[1] - k2*start2[0];
if(k1 == k2 && b1==b2) { //重合但不一定相交
if(Math.min(start2[0],end2[0]) >= Math.min(start1[0], end1[0]) && Math.min(start2[0],end2[0]) <= Math.max(start1[0], end1[0])) {
return new double[] {Math.min(start2[0],end2[0]), Math.min(start2[0],end2[0])*k1+b1};
} else if(Math.max(start2[0],end2[0]) >= Math.min(start1[0], end1[0]) && Math.max(start2[0],end2[0]) <= Math.max(start1[0], end1[0])) {
return new double[] {Math.min(start1[0],end1[0]), Math.min(start1[0],end1[0])*k1+b1};
} else {
return new double[] {};
}
}
else if (k1 == k2 && b1 != b2) //平行
{
return new double[] {};
} else { //既不平行也不重合
x_res = (b1-b2)/(k2-k1);
y_res = k1*x_res + b1;
System.out.println(x_res + " " + y_res);
if(x_res >= Math.min(start1[0], end1[0]) && x_res <= Math.max(start1[0], end1[0]) && y_res <= Math.max(start2[1], end2[1]) && y_res >= Math.min(start2[1], end2[1])) { //有交点
return new double[] {x_res, y_res};
} else {
return new double[] {};
}
}
} catch (Exception e) { //k1为无穷大 第一条线段为x=start1[0]
// System.out.println("k1true");
x_res = start1[0];
try { //可能有交点
double k2 = (double)(end2[1] - start2[1])/(double)(end2[0] - start2[0]);
if(k2 == Double.POSITIVE_INFINITY || k2 == Double.NEGATIVE_INFINITY) {
throw new Exception();
}
double b2 = start2[1] - k2*start2[0];
if(x_res >= Math.min(start1[0], end1[0]) && x_res <= Math.max(start1[0], end1[0])) { //有交点
y_res = k2*x_res + b2;
return new double[] {x_res, y_res};
} else { //无交点
return new double[] {};
}
} catch (Exception e2) { //两条线段都垂直于x轴
if(x_res == start2[0]) { //重合
// System.out.println(true);
// System.out.println(Math.min(start2[1],end2[1]));
if(Math.min(start2[1],end2[1]) >= Math.min(start1[1], end1[1]) && Math.min(start2[1],end2[1]) <= Math.max(start1[1], end1[1])) {
return new double[] {x_res, Math.min(start2[1],end2[1])};
} else if(Math.max(start2[1],end2[1]) >= Math.min(start1[1], end1[1]) && Math.max(start2[1],end2[1]) <= Math.max(start1[1], end1[1])) {
return new double[] {x_res, Math.min(start1[1],end1[1])};
} else {
return new double[] {};
}
} else { //没有交点
return new double[] {};
}
}
}
}