|
|
93cbac |
/*
|
|
|
93cbac |
......... 2015 Ivan Mahonin
|
|
|
93cbac |
|
|
|
93cbac |
This program is free software: you can redistribute it and/or modify
|
|
|
93cbac |
it under the terms of the GNU General Public License as published by
|
|
|
93cbac |
the Free Software Foundation, either version 3 of the License, or
|
|
|
93cbac |
(at your option) any later version.
|
|
|
93cbac |
|
|
|
93cbac |
This program is distributed in the hope that it will be useful,
|
|
|
93cbac |
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
93cbac |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
93cbac |
GNU General Public License for more details.
|
|
|
93cbac |
|
|
|
93cbac |
You should have received a copy of the GNU General Public License
|
|
|
93cbac |
along with this program. If not, see <http: licenses="" www.gnu.org="">.</http:>
|
|
|
93cbac |
*/
|
|
|
93cbac |
|
|
|
93cbac |
#ifndef _GEOMETRY_H_
|
|
|
93cbac |
#define _GEOMETRY_H_
|
|
|
93cbac |
|
|
|
93cbac |
#include <cmath></cmath>
|
|
|
93cbac |
|
|
|
93cbac |
#include <algorithm></algorithm>
|
|
|
93cbac |
|
|
|
93cbac |
|
|
|
93cbac |
typedef double Real;
|
|
|
93cbac |
|
|
|
93cbac |
template<typename t=""></typename>
|
|
|
93cbac |
bool intersects(const T &a0, const T &a1, const T &b0, const T &b1) {
|
|
|
93cbac |
return !(std::max(b0, b1) < std::min(a0, a1))
|
|
|
93cbac |
&& !(std::max(a0, a1) < std::min(b0, b1));
|
|
|
93cbac |
}
|
|
|
93cbac |
|
|
|
93cbac |
inline Real wrap_angle(Real a, Real round) {
|
|
|
93cbac |
Real rounds = a/round + 0.5;
|
|
|
93cbac |
return (rounds - floor(rounds) - 0.5)*round;
|
|
|
93cbac |
}
|
|
|
93cbac |
|
|
|
93cbac |
inline bool angle_between(Real a0, Real a1, Real a, Real round) {
|
|
|
93cbac |
if (a1 < a0) std::swap(a0, a1);
|
|
|
93cbac |
a0 = wrap_angle(a0, round);
|
|
|
93cbac |
a1 = wrap_angle(a1, round);
|
|
|
93cbac |
a = wrap_angle(a, round);
|
|
|
93cbac |
if (a < a0) a += round;
|
|
|
93cbac |
if (a1 < a0) a1 += round;
|
|
|
93cbac |
return a0 < a && a < a1;
|
|
|
93cbac |
}
|
|
|
93cbac |
|
|
|
a80036 |
template<typename t=""></typename>
|
|
|
a80036 |
class vec2 {
|
|
|
93cbac |
public:
|
|
|
a80036 |
typedef T type;
|
|
|
a80036 |
|
|
|
93cbac |
union {
|
|
|
a80036 |
struct { type x, y; };
|
|
|
7c6b57 |
struct { type coords[2]; };
|
|
|
93cbac |
};
|
|
|
93cbac |
|
|
|
a80036 |
vec2():
|
|
|
93cbac |
x(), y() { }
|
|
|
f83e6b |
vec2(const type &x, const type &y):
|
|
|
93cbac |
x(x), y(y) { }
|
|
|
93cbac |
|
|
|
a80036 |
template<typename tt=""></typename>
|
|
|
a80036 |
explicit vec2(const vec2<tt> &other):</tt>
|
|
|
a80036 |
x((type)other.x), y((type)other.y) { }
|
|
|
a80036 |
|
|
|
a80036 |
type& operator[] (int index)
|
|
|
93cbac |
{ return coords[index]; }
|
|
|
a80036 |
const type& operator[] (int index) const
|
|
|
93cbac |
{ return coords[index]; }
|
|
|
a80036 |
bool is_equal_to(const vec2 &other) const
|
|
|
93cbac |
{ return fabs(x - other.x) < 1e-6 && fabs(y - other.y) < 1e-6; }
|
|
|
93cbac |
|
|
|
a80036 |
vec2 operator+(const vec2 &a) const
|
|
|
a80036 |
{ return vec2(x + a.x, y + a.y); }
|
|
|
a80036 |
vec2 operator-(const vec2 &a) const
|
|
|
a80036 |
{ return vec2(x - a.x, y - a.y); }
|
|
|
a80036 |
vec2 operator*(const vec2 &a) const
|
|
|
a80036 |
{ return vec2(x*a.x, y*a.y); }
|
|
|
a80036 |
vec2 operator/(const vec2 &a) const
|
|
|
a80036 |
{ return vec2(x/a.x, y/a.y); }
|
|
|
a80036 |
|
|
|
f83e6b |
vec2 operator*(const type &a) const
|
|
|
a80036 |
{ return vec2(x*a, y*a); }
|
|
|
f83e6b |
vec2 operator/(const type &a) const
|
|
|
a80036 |
{ return vec2(x/a, y/a); }
|
|
|
a80036 |
|
|
|
8cd87e |
type dot(const vec2 &a) const
|
|
|
8cd87e |
{ return x*a.x + y*a.y; }
|
|
|
8cd87e |
|
|
|
a80036 |
static vec2 zero() { return vec2(); }
|
|
|
93cbac |
};
|
|
|
93cbac |
|
|
|
f83e6b |
template<typename t=""></typename>
|
|
|
f83e6b |
class line2 {
|
|
|
f83e6b |
public:
|
|
|
f83e6b |
typedef T type;
|
|
|
f83e6b |
vec2<type> p0, p1;</type>
|
|
|
f83e6b |
line2() { }
|
|
|
f83e6b |
line2(const vec2<type> &p0, const vec2<type> &p1): p0(p0), p1(p1) { }</type></type>
|
|
|
f83e6b |
line2(const type &x0, const type &y0, const type &x1, const type &y1): p0(x0, y0), p1(x1, y1) { }
|
|
|
f83e6b |
};
|
|
|
a80036 |
|
|
|
f83e6b |
template<typename t=""></typename>
|
|
|
f83e6b |
class rect {
|
|
|
93cbac |
public:
|
|
|
f83e6b |
typedef T type;
|
|
|
f83e6b |
vec2<type> p0, p1;</type>
|
|
|
93cbac |
|
|
|
f83e6b |
bool intersects(const rect &other) const
|
|
|
93cbac |
{ return ::intersects(p0.x, p1.x, other.p0.x, other.p1.x)
|
|
|
93cbac |
&& ::intersects(p0.y, p1.y, other.p0.y, other.p1.y); }
|
|
|
93cbac |
|
|
|
f83e6b |
rect expand(const vec2<type> &p) const {</type>
|
|
|
f83e6b |
rect r;
|
|
|
93cbac |
r.p0.x = std::min(std::min(p0.x, p1.x), p.x);
|
|
|
93cbac |
r.p0.y = std::min(std::min(p0.y, p1.y), p.y);
|
|
|
93cbac |
r.p1.x = std::max(std::max(p0.x, p1.x), p.x);
|
|
|
93cbac |
r.p1.y = std::max(std::max(p0.y, p1.y), p.y);
|
|
|
93cbac |
return r;
|
|
|
93cbac |
}
|
|
|
f83e6b |
|
|
|
f83e6b |
rect() { }
|
|
|
f83e6b |
rect(const vec2<type> &p0, const vec2<type> &p1): p0(p0), p1(p1) { }</type></type>
|
|
|
f83e6b |
rect(const type &x0, const type &y0, const type &x1, const type &y1): p0(x0, y0), p1(x1, y1) { }
|
|
|
93cbac |
};
|
|
|
93cbac |
|
|
|
f83e6b |
typedef vec2<real> Vector;</real>
|
|
|
f83e6b |
typedef line2<real> Line;</real>
|
|
|
f83e6b |
typedef rect<real> Rect;</real>
|
|
|
f83e6b |
|
|
|
f83e6b |
typedef vec2<float> vec2f;</float>
|
|
|
f83e6b |
typedef line2<float> line2f;</float>
|
|
|
f83e6b |
typedef rect<float> rectf;</float>
|
|
|
f83e6b |
|
|
|
93cbac |
class ContextRect {
|
|
|
93cbac |
public:
|
|
|
93cbac |
int minx, miny, maxx, maxy;
|
|
|
93cbac |
ContextRect(): minx(), miny(), maxx(), maxy() { }
|
|
|
93cbac |
};
|
|
|
93cbac |
|
|
|
93cbac |
#endif
|