Passed
Branch develop (12c5b1)
by Benjamin
05:18
created

index.php (11 issues)

1
<?php
2
3
require 'org/Michotte/Paths/Dijkstra.php';
4
require 'org/Michotte/Paths/Point.php';
5
6
use \org\Michotte\Paths\Dijkstra;
7
use \org\Michotte\Paths\Point;
8
9
// number of nodes
10
$nodes = 90;
11
12
// maximum size of the map
13
$max = 800;
14
15
// distance between two nodes
16
$minDistance = 150;
17
18
// we add $nodes dynamic nodes
19
$positions = array();
20
for ($i = 0; $i < $nodes; $i++)
21
{
22
	$p = new Point();
23
	$p->setX(rand(0, $max));
24
	$p->setY(rand(0, $max));
25
	$positions[] = $p;
26
}
27
28
// add links
29
findLink($minDistance, $positions);
0 ignored issues
show
$minDistance of type integer is incompatible with the type type expected by parameter $minDistance of findLink(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

29
findLink(/** @scrutinizer ignore-type */ $minDistance, $positions);
Loading history...
30
31
list ($from, $to) = findFromTo($positions);
32
33
$dijkstra = new Dijkstra($positions, $from, $to);
34
$shortestPath = $dijkstra->findShortestPath();
35
36
drawPaths($max, $positions, $from, $to, $shortestPath);
37
38
/**
39
 * Add links between the points
40
 * WARNING, this method doesn't work all the time
41
 * 
42
 * @param type $minDistance
43
 * @param array $positions 
44
 */
45
function findLink($minDistance, array &$positions)
46
{
47
	for ($i = 0; $i < count($positions); $i++)
0 ignored issues
show
Performance Best Practice introduced by
It seems like you are calling the size function count() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.

If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration:

for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}

// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
Loading history...
48
	{
49
		$p1 = $positions[$i];
50
		findLinkBetween($minDistance, $p1, $positions);
0 ignored issues
show
$minDistance of type type is incompatible with the type integer expected by parameter $minDistance of findLinkBetween(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

50
		findLinkBetween(/** @scrutinizer ignore-type */ $minDistance, $p1, $positions);
Loading history...
51
	}
52
}
53
54
/**
55
 * Add a link between two points if they are at a distance less than $distance.
56
 * This function is recursive with $minDistance *= 2 if no link are found
57
 * 
58
 * @param int $minDistance
59
 * @param Point $p1
60
 * @param array $positions 
61
 */
62
function findLinkBetween($minDistance, Point &$p1, array &$positions)
63
{
64
	for ($o = 0; $o < count($positions); $o++)
0 ignored issues
show
Performance Best Practice introduced by
It seems like you are calling the size function count() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.

If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration:

for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}

// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
Loading history...
65
	{
66
		$p2 = $positions[$o];
67
		if ($p1->equal($p2))
68
		{
69
			continue;
70
		}
71
72
		$distance = distance($p1, $p2);
73
		if ($distance < $minDistance)
74
		{
75
			$p1->addPoint($p2);
76
		}
77
	}
78
79
	if (0 == count($p1->getPoints()))
80
	{
81
		findLinkBetween($minDistance * 2, $p1, $positions);
82
	}
83
}
84
85
/**
86
 * Find the distance between two points
87
 * @param Point $p1
88
 * @param Point $p2
89
 * @return float
90
 */
91
function distance(Point $p1, Point $p2)
92
{
93
	// distance = square root of ((x2 - x1)^2 + (y2 - y1)^2)
94
	$distance = sqrt(bcpow($p2->getX() - $p1->getX(), 2) + bcpow($p2->getY() - $p1->getY(), 2));
95
	return $distance;
96
}
97
98
/**
99
 * Find the "from" and "to" points
100
 * from = most left-upper point
101
 * to = most rigth-lower point
102
 * 
103
 * @param array $positions
104
 * @return array
105
 */
106
function findFromTo(array $positions)
107
{
108
	$from = null;
109
	$to = null;
110
	foreach ($positions as $p)
111
	{
112
		if (is_null($from))
113
		{
114
			$from = $p;
115
		}
116
		if (is_null($to))
117
		{
118
			$to = $p;
119
		}
120
121
		if ($p->getX() < $from->getX() && $p->getY() < $from->getY())
122
		{
123
			$from = $p;
124
		}
125
126
		if ($p->getX() > $to->getX() && $p->getY() > $to->getY())
127
		{
128
			$to = $p;
129
		}
130
	}
131
	
132
	return array($from, $to);
133
}
134
135
/**
136
 * Draw the result
137
 * @param int $max
138
 * @param array $positions
139
 * @param Point $from
140
 * @param Point $to
141
 * @param array $shortestPath 
142
 */
143
function drawPaths($max, array $positions, Point $from, Point $to, array $shortestPath)
144
{
145
	// open background
146
	$image = imagecreatetruecolor($max, $max);
147
	$color = imagecolorallocate($image, 255, 255, 255);
148
	imagefill($image, 0, 0, $color);
149
150
	// first run, draw lines
151
	$color = imagecolorallocate($image, 32, 230, 200);
152
	foreach ($positions as $point)
153
	{
154
		foreach ($point->getPoints() as $link)
155
		{
156
			drawLine($image, $point, $link, $color);
157
		}
158
	}
159
		
160
	// then, draw the points
161
	$color = imagecolorallocate($image, 32, 230, 36);
162
	foreach ($positions as $point)
163
	{
164
		imagefilledellipse($image, $point->getX(), $point->getY(), 10, 10, $color);
165
	}
166
	
167
	// draw the shortest path
168
	$color = imagecolorallocate($image, 255, 0, 255);
169
	for ($i = 0; $i < count($shortestPath); $i++)
170
	{
171
		$p = $shortestPath[$i];
172
		if (isset($shortestPath[$i + 1]))
173
		{
174
			$d = $shortestPath[$i + 1];
175
			drawLine($image, $p, $d, $color, 3);
176
		}
177
	}
178
	
179
	// and finally, draw the from and to points
180
	$color = imagecolorallocate($image, 255, 0, 255);
181
	imagefilledellipse($image, $from->getX(), $from->getY(), 10, 10, $color);
0 ignored issues
show
$from->getY() of type double is incompatible with the type integer expected by parameter $cy of imagefilledellipse(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

181
	imagefilledellipse($image, $from->getX(), /** @scrutinizer ignore-type */ $from->getY(), 10, 10, $color);
Loading history...
$from->getX() of type double is incompatible with the type integer expected by parameter $cx of imagefilledellipse(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

181
	imagefilledellipse($image, /** @scrutinizer ignore-type */ $from->getX(), $from->getY(), 10, 10, $color);
Loading history...
182
	imagefilledellipse($image, $to->getX(), $to->getY(), 10, 10, $color);
183
184
	header("Content-type: image/png");
185
	imagepng($image);
186
	die();
0 ignored issues
show
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
187
}
188
189
/**
190
 * Draw a line
191
 * @param resource $image
192
 * @param Point $p Point 1
193
 * @param Point $d Point 2
194
 * @param int $color
195
 * @param int $thick
196
 * @return void
197
 */
198
function drawLine($image, Point $p, Point $d, $color, $thick = 1)
199
{
200
	if (is_null($p) || is_null($d) || is_null($p->getX()) || is_null($p->getY()) || is_null($d->getX()) || is_null($d->getY()))
201
	{
202
		return;
203
	}
204
205
	if ($p->getX() == $d->getX())
206
	{
207
		$from = $p->getY() < $d->getY() ? $p : $d;
208
		$to = $p->getY() > $d->getY() ? $p : $d;
209
	}
210
	else
211
	{
212
		$from = $p->getX() < $d->getX() ? $p : $d;
213
		$to = $p->getX() > $d->getX() ? $p : $d;
214
	}
215
216
	imagesetthickness($image, $thick);
217
218
	imageline($image, $from->getX(), $from->getY(), $to->getX(), $to->getY(), $color);
0 ignored issues
show
$to->getY() of type double is incompatible with the type integer expected by parameter $y2 of imageline(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

218
	imageline($image, $from->getX(), $from->getY(), $to->getX(), /** @scrutinizer ignore-type */ $to->getY(), $color);
Loading history...
$from->getY() of type double is incompatible with the type integer expected by parameter $y1 of imageline(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

218
	imageline($image, $from->getX(), /** @scrutinizer ignore-type */ $from->getY(), $to->getX(), $to->getY(), $color);
Loading history...
$from->getX() of type double is incompatible with the type integer expected by parameter $x1 of imageline(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

218
	imageline($image, /** @scrutinizer ignore-type */ $from->getX(), $from->getY(), $to->getX(), $to->getY(), $color);
Loading history...
$to->getX() of type double is incompatible with the type integer expected by parameter $x2 of imageline(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

218
	imageline($image, $from->getX(), $from->getY(), /** @scrutinizer ignore-type */ $to->getX(), $to->getY(), $color);
Loading history...
219
}