summaryrefslogtreecommitdiff
path: root/src/utils/geometry.cpp
blob: 733190f891f641ef1fe9fd7b4f8b58132c74e996 (plain)
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
////////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2018 Leo Tenenbaum
// This file is part of GraphColoring.
//
// GraphColoring is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// GraphColoring is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with GraphColoring.  If not, see <https://www.gnu.org/licenses/>.
////////////////////////////////////////////////////////////////////////////////

#include "geometry.hpp"

#define _USE_MATH_DEFINES
#include <cmath>
#include <iostream>

#include "errors.hpp"

namespace utils {
namespace geometry {

bool InRectangle(int x, int y, int rx, int ry, int rw, int rh)
{
	return x >= rx && x <= rx+rw && y >= ry && y <= ry+rh;
}

bool InCircle(int x, int y, int cx, int cy, int r)
{
	return (x-cx)*(x-cx) + (y-cy)*(y-cy) <= r*r;
}

double LineAngle(int x1, int y1, int x2, int y2)
{
	if (x1 == x2)
	{
		if (y1 == y2)
			return 0; // Give up
		if (y1 < y2)
			return M_PI / 2; // Slope = Positive infinity
		if (y1 > y2)
			return 3 * M_PI / 2; // Negative infinity
	}
	double slope = (double)(y2-y1)/(x2-x1);
	return x2 > x1 ? atan(slope) : M_PI + atan(slope);

}

int PointToLineSegmentDistance(int x, int y, int x1, int y1, int x2, int y2,
		int tolerance)
{
	// See https://en.wikipedia.org/wiki/Distance_from_a_point_to_a_line#Line_defined_by_two_points
	// Check if point is inside rectangle bounded by endpoints.
	int min_x = std::min(x1, x2);
	int min_y = std::min(y1, y2);
	int max_x = std::max(x1, x2);
	int max_y = std::max(y1, y2);
	if (x < min_x-tolerance || x > max_x+tolerance || y < min_y-tolerance
	 || y > max_y+tolerance)
		return -1;
	// Check if the two points are the same.
	if (x1 == x2 && y1 == y2)
		return sqrt((x1-x)*(x1-x)+(y1-y)*(y1-y));
	// Find distance to line.
	int dx = x2-x1, dy = y2-y1;
	double length = sqrt(dx*dx+dy*dy);
	return abs(dy*x - dx*y + x2*y1 - y2*x1)/length;
}

} // namespace geometry
} // namespace utils