Xinqi Bao's Git

README.md: updated paper url
[XbSlicer.git] / src / Loop.cc
1 #include "Loop.hh"
2
3 #include <cmath>
4 #include <iostream>
5
6 #include "Configurations.hh"
7 using namespace std;
8
9 Loop::Loop(Vec2d& p, uint32_t size = 10) : completed(false)
10 {
11 head.reserve(size);
12 head.push_back(p);
13 minX = p.x, maxX = p.x;
14 minY = p.y, maxY = p.y;
15 }
16
17 bool Loop::isCompleted() const { return completed; }
18 void Loop::add(double x, double y) { add(new Vec2d(x, y)); }
19 void Loop::add(Vec2d* p) { add(*p); }
20 void Loop::add(Vec2d& p)
21 {
22 if (head.front().equal(p))
23 { // Loop complete
24 completed = true;
25 midX = (minX + maxX) / 2;
26 midY = (minY + maxY) / 2;
27 return;
28 }
29 if (minX > p.x) minX = p.x;
30 if (maxX < p.x) maxX = p.x;
31 if (minY > p.y) minY = p.y;
32 if (maxY < p.y) maxY = p.y;
33 head.push_back(p);
34 }
35 int Loop::size() const { return head.size(); }
36 const Vec2d& Loop::at(int i) const { return head.at(i % head.size()); }
37 const Vec2d& Loop::front() const { return head.front(); }
38 const Vec2d& Loop::back() const { return head.back(); }
39 Vec2d& Loop::at(int i) { return head.at(i % head.size()); }
40 Vec2d& Loop::front() { return head.front(); }
41 Vec2d& Loop::back() { return head.back(); }
42 double Loop::getminX() const { return minX; }
43 double Loop::getmaxX() const { return maxX; }
44 double Loop::getminY() const { return minY; }
45 double Loop::getmaxY() const { return maxY; }
46 double Loop::getXsum() const { return xsum; }
47 double Loop::getYsum() const { return ysum; }
48 void Loop::loopSum()
49 {
50 for (const auto& v : head)
51 {
52 xsum += v.x;
53 ysum += v.y;
54 }
55 }
56 void Loop::optimize()
57 {
58 if (head.size() < 4) return;
59 Vec2d p1(head.back()); // position at -1, 0, 1
60 Vec2d p2(head.front());
61 Vec2d p3(head.at(1));
62 if (fabs((p2.x - p1.x) * (p3.y - p1.y) - (p3.x - p1.x) * (p2.y - p1.y)) <
63 thr)
64 head.erase(head.begin());
65
66 for (int i = 0; i < head.size() - 2; i++)
67 { // position form 0, 1, 2 to end-2, end-1, end
68 p1 = head.at(i);
69 p2 = head.at(i + 1);
70 p3 = head.at(i + 2);
71 if (fabs((p2.x - p1.x) * (p3.y - p1.y) -
72 (p3.x - p1.x) * (p2.y - p1.y)) < thr)
73 { // in same line
74 head.erase(head.begin() + (i + 1));
75 i--;
76 }
77 }
78
79 p1 = head.at(head.size() - 2); // position at -2, -1, 0
80 p2 = head.back();
81 p3 = head.front();
82 if (fabs((p2.x - p1.x) * (p3.y - p1.y) - (p3.x - p1.x) * (p2.y - p1.y)) <
83 thr)
84 head.pop_back();
85
86 for (auto& lp : subLoops) lp.optimize();
87 }
88 bool Loop::checkSubLoop(Loop& lp)
89 {
90 if (lp.getminX() > minX && lp.getmaxX() < maxX && lp.getminY() > minY &&
91 lp.getmaxY() < maxY)
92 {
93 subLoops.push_back(lp);
94 for (auto& l : lp.subLoops)
95 {
96 subLoops.push_back(l);
97 }
98 lp.subLoops.clear();
99 return true;
100 }
101 return false;
102 }
103 void Loop::print() const
104 {
105 if (head.size() == 0)
106 {
107 cout << "null\n";
108 return;
109 }
110 cout << head.at(0);
111 for (int i = 1; i < head.size(); i++)
112 {
113 cout << " --> " << head.at(i);
114 }
115 }