求点到线段的距离
由于网页显示吃tab键,缩进无法正常显示
对于空间V-xyz三维几何中点到水平线段的距离,可以投影到xy平面(欧式几何)上。distance = √(∆h ^2 + d ^2);
其中d为投影xy平面上的点到线段的距离。
线段端点a(x1, y1), b(x2, y2),任一点vxt, yt)。
若两端点a,b是否共点
d = 两点间距离
否则
若两端点和任意点v共线(用点积结果判断)
若 v 在线段ab上
d = 0;
否则 d = min(|va|, |vb|);
否则
若三点组成钝角三角形(用余弦定理判断)
d = min(|va|, |vb|);
否则 d = 三角形abv的以ab为底的高(用点乘求得)
今天玲珑杯的A题,题不难,但过的不多,用了一些高中数学知识,大概这就是为啥高中生虐了大学生的部分原因吧。
#include <iostream>
#include <cstdio>
#include <queue>
#include <stack>
#include <string>
#include <cstring>
#include <map>
#include <set>
#include <algorithm>
#include <cstdlib>
#include <cmath>
using namespace std;
const int maxn = 1e4 + 7;
int main()
{
ios::sync_with_stdio(false);
int t;
cin >> t;
while(t--) {
int x1, y1, H, x2, y2;
cin >> H >> x1 >> y1 >> x2 >> y2;
int x0, y0, h0, x, y, h;
cin >> x0 >> y0 >> h0 >> x >> y >> h;
int n;
double line = sqrt(pow(x1 - x2, 2.0) + pow(y1 - y2, 2.0));
cin >> n;
while(n--) {
int t;
cin >> t;
int xt = x0 + t* x;
int yt = y0 + t * y;
int ht = h0 + t * h;
double d;
if (x1 == x2 && y1 == y2) { //重合
d = sqrt(pow(xt - x1, 2.0) + pow(yt - y1, 2.0));
}
else {
if ((x1 - xt) * (y2 - yt) == (x2 - xt) * (y1 - yt)) { //共线
if(xt >= min(x1, x2) && yt <= max(y1, y2)) {
d = 0.0;
}
else {
d = min(sqrt(pow(x1 - xt, 2.0) + pow(y1 - yt, 2.0)),
sqrt(pow(x2 - xt, 2.0) + pow(y2 - yt, 2.0)));
}
}
else {
if (line * line + pow(xt - x1, 2.0) + pow(yt - y1, 2.0) < pow(xt - x2, 2.0) + pow(yt - y2, 2.0) ||
line * line + pow(xt - x2, 2.0) + pow(yt - y2, 2.0) < pow(xt - x1, 2.0) + pow(yt - y1, 2.0))
d = min(sqrt(pow(x1 - xt, 2.0) + pow(y1 - yt, 2.0)),
sqrt(pow(x2 - xt, 2.0) + pow(y2 - yt, 2.0)));
else d = fabs((x1 - xt) * (y2 - yt) - (x2 - xt) * (y1 - yt)) / line;
}
}
double ans = sqrt(pow(ht - H, 2.0) + d * d);
printf("%.2lf\n", ans);
}
}
return 0;
}