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
Bug
introduced
by
![]() |
|||||||||||
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
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
}
![]() |
|||||||||||
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
![]() |
|||||||||||
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
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
}
![]() |
|||||||||||
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
![]() $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
![]() |
|||||||||||
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
|
|||||||||||
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
![]() $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
![]() $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
![]() $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
![]() |
|||||||||||
219 | } |