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
|
#include "util.h"
vector<vector<string> > splitString(string s)
{
vector<vector<string> > result;
vector<string> line;
string word;
for(int i = 0; i < (int) s.size(); ++i)
{
if(s[i] == ' ')
{
line.push_back(word);
word = "";
}
else if(s[i] == '\n')
{
line.push_back(word);
word = "";
result.push_back(line);
line = vector<string>();
}
else
word += s[i];
}
line.push_back(word);
result.push_back(line);
return result;
}
void _tospace(string &s)
{
for(int i = 0; i < (int) s.size(); ++i)
if(s[i] == '_')
s[i] = ' ';
}
void spaceto_(string &s)
{
for(int i = 0; i < (int) s.size(); ++i)
if(s[i] == ' ')
s[i] = '_';
}
double round_beautiful(double d)
{
if(d == 0)
return d;
double ten = 1;
while(d >= 10)
{
d/= 10;
ten *= 10;
}
while(d < 1)
{
d*= 10;
ten /= 10;
}
vector<double> candidates;
candidates.push_back((int)d);
candidates.push_back(((int)d) + 0.5);
if(ten > 1)
{
candidates.push_back(((int)d)/9.0*10);
}
int closest = 0;
double mindist = 10;
for(int i = 0; i < (int)candidates.size(); ++i)
{
if(mindist > fabs(candidates[i]-d))
{
mindist = fabs(candidates[i]-d);
closest = i;
}
}
double result = candidates[closest] * ten;
if(closest == 2)
result = (int) result;
return result;
}
SDL_Event relativate(const SDL_Event &e, SDL_Rect p)
{
SDL_Event result = e;
if(e.type == SDL_MOUSEMOTION)
{
result.motion.x -= p.x;
result.motion.y -= p.y;
}
if(e.type == SDL_MOUSEBUTTONDOWN || e.type == SDL_MOUSEBUTTONUP)
{
result.button.x -= p.x;
result.button.y -= p.y;
}
return result;
}
bool inRect(SDL_Rect r, double x, double y)
{
if(x < r.x || x >= r.x + r.w || y < r.y || y >= r.y + r.h)
return false;
return true;
}
SDL_Surface* copyImage(SDL_Surface* s)
{
return SDL_ConvertSurface(s,s->format,SDL_SWSURFACE);
}
//loads a bitmap from file and converts it to screen properties
SDL_Surface* loadBMP(std::string filename)
{
SDL_Surface* loadedImage = NULL;
SDL_Surface* convertedImage = NULL;
loadedImage = IMG_Load(filename.c_str());
if(loadedImage != NULL)
{
convertedImage = SDL_DisplayFormat(loadedImage);
if(convertedImage)
{
Uint32 colorkey = SDL_MapRGB(convertedImage->format, 0, 1, 2);
SDL_SetColorKey(convertedImage, SDL_SRCCOLORKEY, colorkey);
SDL_FreeSurface(loadedImage);
return convertedImage;
}
cout << "Error: Could not convert Image" << filename << '.' << endl;
}
cout << "Error: Could not load bitmap from file " << filename << endl;
return NULL;
}
string lltostr(const long long& l)
{
stringstream str;
str << l;
return str.str();
}
string dbltostr(const double& d, int dec)
{
stringstream str;
long long bla = pow(10,dec);
str << ((long long) (bla*d))/((double) bla);
return str.str();
}
//returns true if the line intersects with the circle (or lies in it)
bool intersects(double radius, double startx, double starty, double endx, double endy)
{
double xdir = endx - startx;
double ydir = endy - starty;
//|dir*lambda+start|<radius
//(xdir^2+ydir^2)*lamda^2 + (xdir*startx + ydir*starty)*lamda + startx^2 + starty^2 - radius^2 = 0;
double a = xdir*xdir + ydir*ydir;
double b = xdir*startx + ydir*starty;
double c = startx*startx + starty*starty - radius*radius;
double dis = b*b - 4 * a * c;
if(dis < 0)
return false;
double sol1 = (-b + sqrt(dis))/(2*a);
if(sol1 < 0)
return false;
double sol2 = (-b - sqrt(dis))/(2*a);
if(sol2 > 1)
return false;
return true;
}
|