Projection
For given three points p1,p2,p, find the projection point x of p onto p1p2.
Input
xp1 yp1 xp2 yp2 q xp0 yp0 xp1 yp1 ... xpq−1 ypq−1
In the first line, integer coordinates of p1 and p2 are given. Then, q queries are given for integer coordinates of p.
Output
For each query, print the coordinate of the projection point x. The output values should be in a decimal fraction with an error less than 0.00000001.
Constraints
- 1≤ q ≤1000
- −10000 ≤ xi, yi ≤10000
- p1 and p2 are not identical.
Sample Input 1
0 0 2 0 3 -1 1 0 1 1 1
Sample Output 1
-1.0000000000 0.0000000000 0.0000000000 0.0000000000 1.0000000000 0.0000000000
Sample Input 2
0 0 3 4 1 2 5
Sample Output 2
3.1200000000 4.1600000000
题目大意:
求出p点在线段p1 p2上的投影(p点的数据有很多组)
题解:
这是一道很基础的计算几何题目,一道标准的模板题:
首先我们得学习过向量有关的知识
设 d = P1 到 X (交点) 的距离;不难得出点X的坐标 就是 P1 + [unit(P2 - P1)] * d。
那主要问题就转化成了 如何求解 d,以及如何单位化(unit)
#include<iostream>
#include<algorithm>
#include<vector>
#include<cmath>
using namespace std;
const double eps = 1e-9;
typedef struct Point
{
double x, y;
Point(double x = 0, double y = 0) : x(x), y(y) { }; // 构造函数
//下面是模板内容 重载四则运算函数 方便直接计算点的坐标
Point operator + (const struct Point& t) const
{
return Point(x + t.x, y + t.y);
}
Point operator - (const struct Point& t) const
{
return Point(x - t.x, y - t.y);
}
Point operator * (const double t) const
{
return Point(x * t, y * t);
}
Point operator / (const double t) const
{
return Point(x / t, y / t);
}
}Point;
Point A, B;
int q;
double distance(Point A, Point B)
{
double a = A.x - B.x, b = A.y - B.y;
return sqrt(a * a + b * b);
}
double dot(Point A, Point B) // 向量点乘
{
return A.x * B.x + A.y * B.y;
}
int main()
{
cin >> A.x >> A.y >> B.x >> B.y;
cin >> q;
while (q--)
{
Point C;
cin >> C.x >> C.y;
// 用两点的差来表示向量
double d = dot(C - A, B - A) / distance(A, B);
// 单位化向量 = 向量 / 模长
Point unit = (B - A) / sqrt(dot(B - A, B - A));
Point o = A + unit * d;
printf("%.10lf %.10lf", o.x, o.y);
cout << endl;
}
return 0;
}