原本我想使用无限叠if-else
的方式估计能解决, 但这样总归是不够优雅。
使用点斜式
在斜率上可能存在问题, 为了少写判断, 使用一般式
描述直线。并且将坐标带入一般式
就能直观判断点与直线的位置关系, 以此判断线段的位置关系
完成关系判断后, 剩下的事就相当于求直线交点, 直接解方程又得判断条件, 不行, 这很麻烦...
搜索? 二分x轴或y轴?同时考虑xy又得加条件, 太累了
既然给定目标与样本...等等, 机器学习? 线性回归?
反向传播...不对, 题目的条件明确(样本完全), 可以直接求最优解(xy)
接下来就是转化成矩阵形式
[egin{cases}
a_1x + b_1y+c_1 = 0 \
a_2x + b_2y+c_2 = 0
end{cases}
]
[egin{cases}
a_1x + b_1y = -c_1 \
a_2x + b_2y = -c_2
end{cases}
]
[egin{pmatrix}
x&y
end{pmatrix}
egin{pmatrix}
a_1&a_2\
b_1&b_2
end{pmatrix}
=
egin{pmatrix}
-c_1&-c_2
end{pmatrix} \
egin{pmatrix}
x&y
end{pmatrix}
egin{pmatrix}
a_1&a_2\
b_1&b_2
end{pmatrix}
egin{pmatrix}
a_1&a_2\
b_1&b_2
end{pmatrix}^{-1}
=
egin{pmatrix}
-c_1&-c_2
end{pmatrix}
egin{pmatrix}
a_1&a_2\
b_1&b_2
end{pmatrix}^{-1} \
egin{pmatrix}
x&y
end{pmatrix}
=
egin{pmatrix}
-c_1&-c_2
end{pmatrix}
egin{pmatrix}
a_1&a_2\
b_1&b_2
end{pmatrix}^{-1}
]
接下来就是二阶矩阵求逆矩阵
[egin{pmatrix}
a&b\
c&d
end{pmatrix}^{-1}
=
frac{1}{det}
egin{pmatrix}
d&-b\
-c&a
end{pmatrix} \
egin{pmatrix}
a&b\
c&d
end{pmatrix}^{-1}
=
frac{1}{ad - bc}
egin{pmatrix}
d&-b\
-c&a
end{pmatrix}
]
由于在一般式
阶段已经可以完成一些判断, 过滤特殊情况, 所以行列式det
已经不为0
, 直接计算逆矩阵带入后就能得到交点(x, y)
_(:з」∠)_
如果从行列式角度直接讨论无解/多解/唯一解, 似乎需要线性变换, 太麻烦...不管了
C艹
class Solution {
public:
struct pit {
int x, y;
bool operator<(const pit &b) const {
if (x != b.x) return x < b.x;
return y < b.y;
}
};
vector<double> intersection(vector<int>& start1, vector<int>& end1, vector<int>& start2, vector<int>& end2) {
if (std::max(start1[0], end1[0]) < std::min(start2[0], end2[0])) return {};
if (std::max(start1[1], end1[1]) < std::min(start2[1], end2[1])) return {};
int a1 = start1[1] - end1[1], b1 = end1[0] - start1[0];
int c1 = -(a1*end1[0] + b1*end1[1]);
int v1 = a1*start2[0] + b1*start2[1] + c1;
int v2 = a1*end2[0] + b1*end2[1] + c1;
if (v1*v2 > 0) return {};
if (v1 == v2) {
pit ary[4] = {
{start1[0], start1[1]}, {end1[0], end1[1]},
{start2[0], start2[1]}, {end2[0], end2[1]},
};
std::sort(ary, ary + 4);
return {double(ary[1].x), double(ary[1].y)};
}
int a2 = start2[1] - end2[1], b2 = end2[0] - start2[0];
int c2 = -(a2*end2[0] + b2*end2[1]);
v1 = a2*start1[0] + b2*start1[1] + c2;
v2 = a2*end1[0] + b2*end1[1] + c2;
if (v1*v2 > 0) return {};
double detL = a1*b2 - a2*b1;
double L[2][2] = {
{b2/detL, -a2/detL},
{-b1/detL, a1/detL},
};
double optX = -c1*L[0][0] + -c2*L[1][0];
double optY = -c1*L[0][1] + -c2*L[1][1];
return {optX, optY};
}
};