-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy path2.cpp
More file actions
81 lines (67 loc) · 2.24 KB
/
2.cpp
File metadata and controls
81 lines (67 loc) · 2.24 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
#include <cassert>
#include <iostream>
#include <optional>
const double eps = 1e-5;
struct Point {
double x, y;
Point(double x, double y): x(x), y(y) {}
public:
friend bool operator==(const Point& p1, const Point& p2) {
return std::abs(p1.x - p2.x) < eps && std::abs(p1.y - p2.y) < eps;
}
};
class Line {
double a, b, c;
Line(const Point& p1, const Point& p2) :
a(p1.y - p2.y),
b(p2.x - p1.x),
c(p1.x * p2.y - p1.y * p2.x)
{}
public:
Line(double a, double b, double c) : a(a), b(b), c(c) {}
static std::optional<Line> fabric(const Point& p1, const Point& p2) {
if (p1 == p2) return {};
return Line{p1, p2};
}
std::optional<Point> intersection(const Line& other) const {
double det = a * other.b - b * other.a;
if (std::abs(det) < eps) return std::nullopt;
double x = (b * other.c - other.b * c) / det;
double y = (c * other.a - other.c * a) / det;
return Point{x, y};
}
Line perpendicular(const Point& point) const {
double a = -this->b;
double b = this->a;
double c = -(b * point.x + a * point.y);
return {a, b, c};
}
friend std::ostream& operator<<(std::ostream& os, const Line& line) {
if (std::abs(line.b) < eps) {
os << "x = " << -line.c / line.a << "\n";
return os;
}
double k = -line.a / line.b + 0.0f;
double b = -line.c / line.b;
os << "y = " << k << "x " << (std::abs(b) < eps ? "- " : "+ ") << std::abs(b) << "\n";
return os;
}
};
int main() {
Point p1{42, 17}; Point p2{42, 17};
auto invalid_line = Line::fabric(p1, p2);
assert(!invalid_line.has_value());
auto opt_vertical = Line::fabric({2, 0}, {2, 10});
assert(opt_vertical.has_value());
Line vertical = opt_vertical.value();
Line horizontal(0, 1, -5);
auto inter = vertical.intersection(horizontal);
assert(inter.has_value());
assert(inter.value() == Point(2, 5));
auto opt_line = Line::fabric({5, 0}, {3.34, -2.34});
assert(opt_line.has_value());
Line line = opt_line.value();
Line perp = line.perpendicular({1, 1});
auto inter_perp = line.intersection(perp);
assert(inter_perp.has_value());
}