-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.cpp
185 lines (154 loc) · 2.88 KB
/
main.cpp
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
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
#include <iostream>
#include <vector>
#include <string>
#include <stdexcept>
#include <cmath>
using namespace std;
struct vec2f
{
float x;
float y;
vec2f(float _x = 0,float _y = 0):
x(_x),
y(_y)
{
}
friend vec2f operator*(vec2f vec,float lambda)
{
return {vec.x*lambda,vec.y*lambda};
}
friend vec2f operator*(float lambda,vec2f vec)
{
return vec*lambda;
}
friend vec2f operator*(vec2f va,vec2f vb)
{
return {va.x*vb.x,va.y*vb.y};
}
friend vec2f operator+(vec2f va,vec2f vb)
{
return {va.x+vb.x,va.y+vb.y};
}
friend vec2f operator-(vec2f va,vec2f vb)
{
return {va.x-vb.x,va.y-vb.y};
}
friend vec2f operator-(vec2f va)
{
return -1.0f*va;
}
friend ostream &operator<<(ostream &str,vec2f const &vec)
{
str<<"( "<<vec.x<<" ; "<<vec.y<<" )";
return str;
}
};
class quad_curve
{
protected:
vector<vec2f> base_points;
vector<vec2f> correction_points;
public:
// look wikipedia's article for description
vec2f getPoint(size_t segment_num,float t)
{
//number of segments is equal to num. of correction points (one point per segment)
if(correction_points.size()>=segment_num && base_points.size()>=2)
{
// pivot points
vec2f P[] = {
base_points[segment_num],
correction_points[segment_num],
base_points[segment_num+1]
};
// Bernstain's polynomials
float b[] = {
std::pow(1-t,2.0f),
2*t*(1-t),
std::pow(t,2.0f)
};
vec2f sum;
size_t cnt = 3;
for(size_t i=0;i<cnt;++i)
sum = sum + b[i]*P[i];
return sum;
}
else
throw out_of_range("not enought point to calculate provided segment_num");
}
void addStartPoint(vec2f pt)
{
if(base_points.empty())
base_points.push_back(pt);
else
throw string("curve already contains start point");
}
void addSegment(vec2f base_pt,vec2f correction_pt)
{
if(!base_points.empty())
{
base_points.push_back(base_pt);
correction_points.push_back(correction_pt);
}
else
throw string("first you need to add start point");
}
};
bool test_struct(void)
{
vec2f vec1(1,2);
cout<<vec1<<endl;
quad_curve tcurve;
try{
// out to fail
tcurve.getPoint(0,0.5f);
cout<<"empty FAIL"<<endl;
return false;
}
catch(...)
{ cout<<"empty OK"<<endl;}
tcurve.addStartPoint(vec2f(0.0f,0.0f));
try{
tcurve.addSegment(vec2f(1.0f,0.0f),vec2f(0.7f,1.0f));
for(float q=0;q<1.0f;q+=0.1f)
{
cout<<tcurve.getPoint(0,q)<<endl;
}
cout<<"access test LOOKS_LIKE_OK :)"<<endl;
}
catch(string const &msg)
{
cout<<msg<<endl;
throw 0;
}
catch(out_of_range const &oor)
{
cout<<oor.what()<<endl;
throw 0;
}
catch(...)
{
cout<<"access test FAIL"<<endl;
return false;
}
return true;
}
int main(int argc,char **argv)
{
try
{
if(test_struct())
cout<<"Tests PASSED"<<endl;
else
cout<<"Tests FAILED"<<endl;
}
catch(string const &msg)
{
cout<<msg<<endl;
}
catch(out_of_range const &oor)
{
cout<<oor.what()<<endl;
}
return 0;
}