aboutsummaryrefslogtreecommitdiff
path: root/geometry.c
blob: 802ca076b3e9f42357bd58b9d51b34146b38e143 (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
/*
 *
 * Copyright (C) 2022 Jeremias Stotter <jeremias@stotter.eu>
 *
 * This file is part of network-simulator.
 *
 * network-simulator 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.
 *
 * network-simulator 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 network-simulator. If not, see <https://www.gnu.org/licenses/>. 
*/

#include <stdbool.h>
#include <stdio.h>
#include <math.h>

#include "geometry.h"

/* This calculates if a path from a to b to c is going clockwise, counterclockwise or striaght
   Return 1 for clockwise, -1 for anticlockwise and 0 if all points are on the same line
 */
int point_orientation(double a_x, double a_y,
					  double b_x, double b_y,
					  double c_x, double c_y) {
	double difference = (b_y - a_y) * (c_x - b_x) - (b_x - a_x) * (c_y - b_y);
	if(difference > 0)
		return 1;
	else if(difference < 0)
		return -1;
	else
		return 0;
}

/*
  We are going to check if the lines intersect like this:
  1. Check if we go clockwise or counterclockwise from points l1_a, l1_b, l2_a; and l1_a, l1_b, l2_b
  2. Do the go in different directions? If no lines don't intersect
  3. Check l2_a, l2_b, l1_a; and l2_a, l2_b, l1_b
  4. Different directions? If no line's don't intersect
  5. LINES INTERSECT!
 */
bool line_line_intersect(double l1_a_x, double l1_a_y, double l1_b_x, double l1_b_y,
						 double l2_a_x, double l2_a_y, double l2_b_x, double l2_b_y) {
	if(point_orientation(l1_a_x, l1_a_y, l1_b_x, l1_b_y, l2_a_x, l2_a_y) ==
	   point_orientation(l1_a_x, l1_a_y, l1_b_x, l1_b_y, l2_b_x, l2_b_y))
		return false;
	if(point_orientation(l2_a_x, l2_a_y, l2_b_x, l2_b_y, l1_a_x, l1_a_y) ==
	   point_orientation(l2_a_x, l2_a_y, l2_b_x, l2_b_y, l1_b_x, l1_b_y))
		return false;
	return true;
}

bool rect_rect_intersect(double a_x1, double a_x2, double a_y1, double a_y2,
						 double b_x1, double b_x2, double b_y1, double b_y2) {
	return !((b_x1 < b_x2 ? b_x1 : b_x2) > (a_x2 > a_x1 ? a_x2 : a_x1) ||
			 (b_x2 > b_x1 ? b_x2 : b_x1) < (a_x1 < a_x2 ? a_x1 : a_x2) ||
			 (b_y1 < b_y2 ? b_y1 : b_y2) > (a_y2 > a_y1 ? a_y2 : a_y1) ||
			 (b_y2 > b_y1 ? b_y2 : b_y1) < (a_y1 < a_y2 ? a_y1 : a_y2));
}

struct coordinate offset_along_line(double x1, double y1, double x2, double y2, double offset) {
	double distance_ratio = offset / sqrt(pow(x2 - x1, 2) + pow(y2 - y1, 2));

	struct coordinate ret_coord;

	ret_coord.x = ((1-distance_ratio) * x1 + distance_ratio * x2);
	ret_coord.y = ((1-distance_ratio) * y1 + distance_ratio * y2);
	
	return ret_coord;
}
Jeremias Stotters git repositories generated by CGIT