-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathDistance.cpp
More file actions
139 lines (120 loc) · 3.25 KB
/
Distance.cpp
File metadata and controls
139 lines (120 loc) · 3.25 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
#include <bits/stdc++.h>
using namespace std;
typedef long long llong;
// 二次元座標を表す構造体
// ベクトル演算も扱う
struct Point
{
double x;
double y;
Point () {
x = 0;
y = 0;
}
Point(double px, double py) {
x = px;
y = py;
}
Point operator+(Point p2)
{
Point P_Add = Point(0, 0);
P_Add.x = x + p2.x;
P_Add.y = y + p2.y;
return P_Add;
}
Point operator-(Point p2)
{
Point P_Min = Point(0, 0);
P_Min.x = x - p2.x;
P_Min.y = y - p2.y;
return P_Min;
}
// 自身をスカラー倍する
Point operator*(double scal)
{
x *= scal;
y *= scal;
return Point(x,y);
}
// 自身との内積を計算する
double InnerProduct(Point p2)
{
return (x*p2.x + y*p2.y);
}
// 2点のベクトルの外積を計算する
double OuterProduct(Point p2)
{
return (x*p2.y - y*p2.x);
}
// 自身のノルム(大きさの2乗)を返す
double Norm()
{
return x*x + y*y;
}
// 自身のベクトルの大きさを返す
double Magnitude()
{
return sqrt(Norm());
}
// 自身を始点として点p2となす線分に、
// 点p3を射影した時の座標を求める
Point Projection(Point p2, Point p3)
{
// 始点p1→p3へのベクトル
Vector vec1(p3.x - x, p3.y - y);
// 始点p1→p2へのベクトル
Vector vec2(p2.x - x, p2.y - y);
double tmp = vec2.InnerProduct(vec1) / vec2.Norm();
return Point(x, y) + vec2 * tmp;
}
// 自身を始点として点p2となす線分に対して
// 点p3と線対称になる点の座標を求める
Point Reflection(Point p2, Point p3)
{
// 点p3から線分上に射影した点までのベクトル
Vector vec1 = Projection(p2, p3) - p3;
return p3 + vec1 * 2;
}
// 自身ともう一点の距離を求める
double CalcDistancePtoP(Point p)
{
Point tmp = p - Point(x, y);
return tmp.Magnitude();
}
// 自身と2点を通る直線間の距離を求める
double CalcDistanceLineToP(Point p2, Point p3)
{
Point tmp = Point(x, y);
Vector vec1 = p3-p2;
Vector vec2 = tmp - p2;
return vec1.OuterProduct(vec2) / vec1.Magnitude();
}
// 自身と2点を通る線分間の距離を求める
double CalcDistanceSegmentToP(Point p2, Point p3)
{
Point p = Point(x, y);
if((p3-p2).InnerProduct(p-p2) < 0.0) return (p-p2).Magnitude();
if((p2-p3).InnerProduct(p-p3) < 0.0) return (p-p3).Magnitude();
return p.CalcDistanceLineToP(p2, p3);
}
using Vector = Point;
using Line = Point;
};
int main() {
int x1(0), y1(0), x2(0), y2(0);
cin >> x1 >> y1 >> x2 >> y2;
Point p1(x1, y1);
Point p2(x2, y2);
int q(0);
cin >> q;
for (int i = 0; i < q; i++)
{
int x(0),y(0);
cin >> x >> y;
Point p3(x,y);
Point res = p1.Reflection(p2, p3);
// 小数点以下の桁数を指定する
cout << std::fixed << std::setprecision(8) << res.x << " " << res.y << "\n";
}
return 0;
}