This repository has been archived by the owner on Nov 7, 2018. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathdiagram2d.cc
105 lines (90 loc) · 2.61 KB
/
diagram2d.cc
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
// Copyright (c) 2016 Kai Luo. All rights reserved.
#include "diagram2d.h"
#include <algorithm>
namespace zLi {
Diagram2D::Diagram2D(const Float *xs, const Float *ys, size_t l) {
for (size_t i = 0; i < l; ++i) {
diagram_.push_back(std::make_tuple(xs[i], ys[i]));
}
std::sort(diagram_.begin(), diagram_.end());
}
Diagram2D::Diagram2D(const Float *xs, Float y, size_t l) {
for (size_t i = 0; i < l; ++i) {
diagram_.push_back(std::make_tuple(xs[i], y));
}
std::sort(diagram_.begin(), diagram_.end());
}
void Diagram2D::Display(std::ostream &out) {
for (const auto &p : diagram_) {
out << "(" << std::get<0>(p) << ", " << std::get<1>(p) << ")\n";
}
}
Float Diagram2D::Query(Float x) const {
auto iter = std::lower_bound(
diagram_.begin(), diagram_.end(), std::make_tuple(x, 0),
[](const std::tuple<Float, Float> &a, const std::tuple<Float, Float> &b) {
return std::get<0>(a) < std::get<0>(b);
});
if (iter == diagram_.begin() || iter == diagram_.end()) {
return 0;
}
int j = std::distance(diagram_.begin(), iter);
int i = j - 1;
return Lerp(std::get<0>(diagram_[i]), std::get<1>(diagram_[i]),
std::get<0>(diagram_[j]), std::get<1>(diagram_[j]), x);
}
Diagram2D &Diagram2D::operator+=(const Diagram2D &rhs) {
for (auto &p : diagram_) {
std::get<1>(p) += rhs.Query(std::get<0>(p));
}
return *this;
}
Diagram2D &Diagram2D::operator+=(Float d) {
for (auto &p : diagram_) {
std::get<1>(p) += d;
}
return *this;
}
Diagram2D &Diagram2D::operator*=(const Diagram2D &rhs) {
for (auto &p : diagram_) {
std::get<1>(p) *= rhs.Query(std::get<0>(p));
}
return *this;
}
Diagram2D &Diagram2D::operator*=(Float f) {
for (auto &p : diagram_) {
std::get<1>(p) *= f;
}
return *this;
}
Diagram2D operator*(Float f, const Diagram2D &rhs) {
Diagram2D res(rhs);
for (auto &p : res.diagram_) {
std::get<1>(p) *= f;
}
return res;
}
Diagram2D operator*(const Diagram2D &lhs, Float f) { return operator*(f, lhs); }
Diagram2D operator*(const Diagram2D &lhs, const Diagram2D &rhs) {
Diagram2D res(lhs);
for (auto &p : res.diagram_) {
std::get<1>(p) *= rhs.Query(std::get<0>(p));
}
return res;
}
Diagram2D operator+(Float f, const Diagram2D &rhs) {
Diagram2D res(rhs);
for (auto &p : res.diagram_) {
std::get<1>(p) += f;
}
return res;
}
Diagram2D operator+(const Diagram2D &lhs, Float f) { return operator*(f, lhs); }
Diagram2D operator+(const Diagram2D &lhs, const Diagram2D &rhs) {
Diagram2D res(lhs);
for (auto &p : res.diagram_) {
std::get<1>(p) += rhs.Query(std::get<0>(p));
}
return res;
}
} // namespace zLi