1 package cz.cuni.amis.pogamut.base.utils.math;
2
3 import java.util.ArrayList;
4 import java.util.Collection;
5 import java.util.Collections;
6 import java.util.Comparator;
7 import java.util.LinkedList;
8 import java.util.List;
9
10 import cz.cuni.amis.pogamut.base3d.worldview.object.ILocated;
11 import cz.cuni.amis.pogamut.base3d.worldview.object.IViewable;
12 import cz.cuni.amis.pogamut.base3d.worldview.object.Location;
13 import cz.cuni.amis.utils.IFilter;
14 import cz.cuni.amis.utils.Tuple2;
15
16 /**
17 * DistanceUtils consists of usual routines for selecting "X" from some "collections of Xes" that are in some "distance" relation to the "target",
18 * e.g., "get nearest weapon from collection of available weapons to my position".
19 * <p><p>
20 * Note that you may always use custom metric via {@link IGetDistance} interface.
21 * <p><p>
22 * Note that you may always use some custom filters via {@link IDistanceFilter} interface.
23 *
24 * @author Jimmy
25 * @author ik
26 */
27 public class DistanceUtils {
28
29 // --------------
30 // =====================
31 // RELATIONs
32 // =====================
33 // --------------
34
35 /**
36 * Relation-ship estimator between two {@link ILocated} objects and their distance (or whatever required).
37 * @author Jimmy
38 *
39 * @param <T>
40 */
41 public static interface IBetterRelation<T> {
42
43 public boolean isBetterRelation(ILocated target, T examinedObject, double examinedObjectToTargetDistance, T currentBestCandidate, double currentBestObjectToTargetDistance);
44
45 }
46
47 /**
48 * Prefer "closer" objects to "target"
49 * @author Jimmy
50 *
51 * @param <T>
52 */
53 public static class RelationCloser<T> implements IBetterRelation<T> {
54
55 @Override
56 public boolean isBetterRelation(ILocated target, T examinedObject, double examinedObjetToTargetDistance, T currentBestCandidate, double currentBestObjectToTargetDistance) {
57 return examinedObjetToTargetDistance < currentBestObjectToTargetDistance;
58 }
59
60 }
61
62 @SuppressWarnings("rawtypes")
63 public static final RelationCloser relationCloser = new RelationCloser();
64
65 /**
66 * Prefer "further" objects to "target"
67 * @author Jimmy
68 *
69 * @param <T>
70 */
71 public static class RelationFurther<T> implements IBetterRelation<T> {
72
73 @Override
74 public boolean isBetterRelation(ILocated target, T examinedObject, double examinedObjetToTargetDistance, T currentBestCandidate, double currentBestObjectToTargetDistance) {
75 return examinedObjetToTargetDistance > currentBestObjectToTargetDistance;
76 }
77
78 }
79
80 @SuppressWarnings("rawtypes")
81 public static final RelationFurther relationFurther = new RelationFurther();
82
83 // --------------
84 // =====================
85 // METRICS
86 // =====================
87 // --------------
88
89 /**
90 * Distance estimator between object of types T and some {@link Location} target.
91 * @author Jimmy
92 *
93 * @param <T>
94 */
95 public static interface IGetDistance<T> {
96
97 public double getDistance(T object, ILocated target);
98
99 }
100
101 /**
102 * Simple implementation of {@link IGetDistance} that uses {@link Location#getDistance(Location)} method.
103 * @author Jimmy
104 *
105 * @param <T>
106 */
107 public static class GetLocatedDistance3D<T extends ILocated> implements IGetDistance<T> {
108
109 /**
110 * Uses {@link Location#getDistance(Location)} method.
111 */
112 @Override
113 public double getDistance(T object, ILocated target) {
114 if (object.getLocation() == null) return Double.MAX_VALUE;
115 return object.getLocation().getDistance(target.getLocation());
116 }
117
118 }
119
120 /**
121 * See {@link GetLocatedDistance3D}.
122 */
123 public static final GetLocatedDistance3D<ILocated> getLocatedDistance3D = new GetLocatedDistance3D<ILocated>();
124
125 /**
126 * Simple implementation of {@link IGetDistance} that uses {@link Location#getDistance2D(Location)} method.
127 * @author Jimmy
128 *
129 * @param <T>
130 */
131 public static class GetLocatedDistance2D<T extends ILocated> implements IGetDistance<T> {
132
133 /**
134 * Uses {@link Location#getDistance(Location)} method.
135 */
136 @Override
137 public double getDistance(T object, ILocated target) {
138 if (object.getLocation() == null) return Double.MAX_VALUE;
139 return object.getLocation().getDistance2D(target.getLocation());
140 }
141
142 }
143
144 /**
145 * See {@link GetLocatedDistance2D}.
146 */
147 public static final GetLocatedDistance2D<ILocated> getLocatedDistance2D = new GetLocatedDistance2D<ILocated>();
148
149 // --------------
150 // =====================
151 // FILTERS
152 // =====================
153 // --------------
154
155 /**
156 * Filter that allows to check whether "object" is accepted with respect to "distanceToTarget" for given "target".
157 * @author Jimmy
158 *
159 * @param <T>
160 */
161 public static interface IDistanceFilter<T> {
162
163 /**
164 * @param object
165 * @param target
166 * @param distanceToTarget
167 * @return TRUE == can be result, FALSE == filter out
168 */
169 public boolean isAccepted(T object, ILocated target, double distanceToTarget);
170
171 }
172
173
174 /**
175 * Filter that accepts all "objects" (does not filter anything out).
176 * @author Jimmy
177 *
178 * @param <T>
179 */
180 public static final class AcceptAllDistanceFilter<T> implements IDistanceFilter<T> {
181
182 @Override
183 public boolean isAccepted(T object, ILocated target, double distanceToTarget) {
184 return true;
185 }
186
187 }
188
189 /**
190 * See {@link AcceptAllDistanceFilter}.
191 */
192 @SuppressWarnings("unchecked")
193 public static final AcceptAllDistanceFilter acceptAllDistanceFilter = new AcceptAllDistanceFilter();
194
195 /**
196 * Contains single filter, {@link #acceptAllDistanceFilter}, i.e., this will ACCEPTS-ALL-ITEMS.
197 */
198 public static final IDistanceFilter[] NO_FILTER = new IDistanceFilter[]{ acceptAllDistanceFilter };
199
200 /**
201 * Filter that accepts all "objects" that are within range of min/max distance (inclusive).
202 * @author Jimmy
203 *
204 * @param <T>
205 */
206 public static class RangeDistanceFilter<T> implements IDistanceFilter<T> {
207
208 private double minDistance;
209 private double maxDistance;
210
211 public RangeDistanceFilter(double minDistance, double maxDistance) {
212 this.minDistance = minDistance;
213 this.maxDistance = maxDistance;
214 }
215
216 @Override
217 public boolean isAccepted(T object, ILocated target, double distanceToTarget) {
218 return minDistance <= distanceToTarget && distanceToTarget <= maxDistance;
219 }
220
221 }
222
223 /**
224 * Accepts only VISIBLE ({@link IViewable#isVisible()} == TRUE) objects.
225 * @author Jimmy
226 *
227 * @param <T>
228 */
229 public static class VisibleFilter<T extends IViewable> implements IDistanceFilter<T> {
230
231 @Override
232 public boolean isAccepted(T object, ILocated target, double distanceToTarget) {
233 return object.isVisible();
234 }
235
236 }
237
238 /**
239 * See {@link VisibleFilter}.
240 */
241 public static final VisibleFilter<IViewable> visibleFilter = new VisibleFilter<IViewable>();
242
243 /**
244 * Adapter that wraps {@link IFilter} making it into {@link IDistanceFilter}.
245 *
246 * @author Jimmy
247 *
248 * @param <T>
249 */
250 public static class FilterAdapter<T> implements IDistanceFilter<T> {
251
252 private IFilter<T> filter;
253
254 public FilterAdapter(IFilter<T> filter) {
255 this.filter = filter;
256 }
257
258 @Override
259 public boolean isAccepted(T object, ILocated target, double distanceToTarget) {
260 return filter.isAccepted(object);
261 }
262
263 }
264
265 // --------------
266 // =====================
267 // getNearest()
268 // =====================
269 // --------------
270
271 /**
272 * Returns "in-best-distance-relation-to-'target'" object.
273 * <p><p>
274 * Distance is obtained via provided {@link IGetDistance#getDistance(Object, Location)}.
275 * <p><p>
276 * Relation checking is provided via {@link IBetterRelation#isBetterRelation(Object, ILocated, double, double)}.
277 * <p><p>
278 * Only 'locations' that passes ALL 'filters' may get into the result.
279 *
280 * WARNING: O(n) complexity!
281 *
282 * @param <T>
283 * @param locations
284 * @param target
285 * @param getDistance distance-computer between 'locations' and 'target'.
286 * @param betterRelation assessing
287 * @param filters if null or empty, is ignored
288 * @return nearest object from collection of objects
289 */
290 public static <T> T getInBestRelation(Collection<T> locations, ILocated target, IGetDistance getDistance, IBetterRelation betterRelation, IDistanceFilter... filters) {
291 if (filters == null || (filters.length == 1 && filters[0] == acceptAllDistanceFilter)) {
292 return getInBestRelation(locations, target, getDistance, betterRelation);
293 }
294 if (filters == null) return null;
295 if (locations == null) return null;
296 if (target == null) return null;
297 if (target.getLocation() == null) return null;
298 if (getDistance == null) return null;
299 if (betterRelation == null) return null;
300
301 T nearest = null;
302 double minDistance = Double.MAX_VALUE;
303 double distance;
304
305 for(T location : locations) {
306 distance = getDistance.getDistance(location, target);
307
308 boolean accepted = true;
309 for (IDistanceFilter filter : filters) {
310 if (filter == null) continue;
311 if (filter.isAccepted(location, target, distance)) continue;
312 accepted = false;
313 break;
314 }
315
316 if (accepted) {
317 if (betterRelation.isBetterRelation(target, location, distance, nearest, minDistance)) {
318 minDistance = distance;
319 nearest = location;
320 }
321 }
322 }
323
324 return nearest;
325 }
326
327 /**
328 * Returns "in-best-distance-relation-to-'target'" object.
329 * <p><p>
330 * Distance is obtained via provided {@link IGetDistance#getDistance(Object, Location)}.
331 * <p><p>
332 * Relation checking is provided via {@link IBetterRelation#isBetterRelation(Object, ILocated, double, double)}.
333 *
334 * WARNING: O(n) complexity!
335 *
336 * @param <T>
337 * @param locations
338 * @param target
339 * @param getDistance distance computer between 'locations' and 'target'.
340 * @param betterRelation
341 * @return nearest object from collection of objects
342 */
343 public static <T> T getInBestRelation(Collection<T> locations, ILocated target, IGetDistance getDistance, IBetterRelation betterRelation) {
344 if (locations == null) return null;
345 if (target == null) return null;
346 if (target.getLocation() == null) return null;
347 if (getDistance == null) return null;
348 if (betterRelation == null) return null;
349
350 T best = null;
351 double bestDistance = Double.MAX_VALUE;
352 double distance;
353
354 for(T location : locations) {
355 distance = getDistance.getDistance(location, target);
356
357 if (betterRelation.isBetterRelation(target, location, distance, best, bestDistance)) {
358 bestDistance = distance;
359 best = location;
360 }
361 }
362
363 return best;
364 }
365
366 /**
367 * Returns "in-nth-best-distance-relation-to-'target'" object from 'location'. This means is will not get the 1st best, 2nd best but n-th best, i.e.,
368 * if we would sort all 'locations' according to 'betterRelation', this returns n-th element.
369 * <p><p>
370 * Distance is obtained via provided {@link IGetDistance#getDistance(Object, Location)}.
371 * <p><p>
372 * Relation checking is provided via {@link IBetterRelation#isBetterRelation(Object, ILocated, double, double)}.
373 * <p><p>
374 * Only 'locations' that passes ALL 'filters' may get into the result.
375 *
376 * WARNING: O(locations.size * N) ~ O(n^2) complexity!
377 *
378 * @param <T>
379 * @param nthBest if <= 0, returns the 1-BEST
380 * @param locations if locations.size() < 'nthBest', returns the "worst" from 'locations'
381 * @param target
382 * @param getDistance distance computer between 'locations' and 'target'.
383 * @param filters if insufficient (< nthBest) locations gets to the result, the "worst" is returned, or null in case of all locations are filtered out
384 * @return "in-nth-best-distance-relation-to-'target'" object from 'location'
385 */
386 public static <T> T getInNthBestRelation(int nthBest, Collection<T> locations, ILocated target, IGetDistance getDistance, IBetterRelation betterRelation, IDistanceFilter... filters) {
387 if (nthBest < 1) return getInBestRelation(locations, target, getDistance, betterRelation, filters);
388 if (filters == null) return null;
389 if (locations == null) return null;
390 if (target == null) return null;
391 if (target.getLocation() == null) return null;
392 if (getDistance == null) return null;
393 if (betterRelation == null) return null;
394
395 List<Tuple2<T, Double>> best = new ArrayList<Tuple2<T, Double>>();
396
397 double distance;
398
399 for(T location : locations) {
400 distance = getDistance.getDistance(location, target);
401
402 boolean accepted = true;
403 for (IDistanceFilter filter : filters) {
404 if (filter == null) continue;
405 if (filter.isAccepted(location, target, distance)) continue;
406 accepted = false;
407 break;
408 }
409
410 if (accepted) {
411 int i = 0;
412 for (; i < best.size(); ++i) {
413 Tuple2<T, Double> candidate = best.get(i);
414 if (betterRelation.isBetterRelation(target, location, distance, candidate.getFirst(), candidate.getSecond())) {
415 break;
416 }
417 }
418 if (i < nthBest) {
419 if (i < best.size()) {
420 best.add(i, new Tuple2<T, Double>(location, distance));
421 } else {
422 best.add(new Tuple2<T, Double>(location, distance));
423 }
424 }
425 }
426 }
427
428 return best.size() == 0 ? null : best.get(best.size()-1).getFirst();
429 }
430
431 /**
432 * Returns "in-nth-best-distance-relation-to-'target'" object from 'locations'. This means is will not get the 1st best, 2nd best but n-th best, i.e.,
433 * if we would sort all 'locations' according to 'betterRelation', this returns n-th element.
434 * <p><p>
435 * Distance is obtained via provided {@link IGetDistance#getDistance(Object, Location)}.
436 * <p><p>
437 * Relation checking is provided via {@link IBetterRelation#isBetterRelation(Object, ILocated, double, double)}.
438 *
439 * WARNING: O(locations.size * N) ~ O(n^2) complexity!
440 *
441 * @param <T>
442 * @param nthBest if <= 0, returns the 1-BEST
443 * @param locations if locations.size() < 'nthBest', returns the "worst" from 'locations'
444 * @param target
445 * @param getDistance distance computer between 'locations' and 'target'.
446 * @return nth-nearest object from 'locations'
447 */
448 public static <T> T getInNthBestRelation(int nthBest, Collection<T> locations, ILocated target, IGetDistance getDistance, IBetterRelation betterRelation) {
449 if (nthBest < 1) return getInBestRelation(locations, target, getDistance, betterRelation);
450 if (locations == null) return null;
451 if (target == null) return null;
452 if (target.getLocation() == null) return null;
453 if (getDistance == null) return null;
454 if (betterRelation == null) return null;
455
456 List<Tuple2<T, Double>> best = new ArrayList<Tuple2<T, Double>>();
457
458 double distance;
459
460 for(T location : locations) {
461 distance = getDistance.getDistance(location, target);
462
463 int i = 0;
464 for (; i < best.size(); ++i) {
465 Tuple2<T, Double> candidate = best.get(i);
466 if (betterRelation.isBetterRelation(target, location, distance, candidate.getFirst(), candidate.getSecond())) {
467 break;
468 }
469 }
470 if (i < nthBest) {
471 if (i < best.size()) {
472 best.add(i, new Tuple2<T, Double>(location, distance));
473 } else {
474 best.add(new Tuple2<T, Double>(location, distance));
475 }
476 }
477 }
478
479 return best.size() == 0 ? null : best.get(best.size()-1).getFirst();
480 }
481
482 /**
483 * Returns the nearest object from 'location' to 'target' that is accepted by all 'filters'.
484 * <p><p>
485 * Distance is obtained via provided {@link IGetDistance#getDistance(Object, Location)}.
486 * <p><p>
487 * WARNING: O(n) complexity!
488 *
489 * @param <T>
490 * @param locations
491 * @param target
492 * @param getDistance distance computer between 'locations' and 'target'.
493 * @param filters filters to be used (that can filter out unsuitable results)
494 * @return nearest object from 'locations'
495 */
496 public static <T> T getNearest(Collection<T> locations, ILocated target, IGetDistance getDistance, IDistanceFilter... filters) {
497 return
498 getInBestRelation(
499 locations,
500 target,
501 getDistance,
502 relationCloser,
503 filters
504 );
505 }
506
507 /**
508 * Returns the n-th nearest object from 'locations' to 'target' that is accepted by all 'filters'.
509 * <p><p>
510 * Distance is obtained via provided {@link IGetDistance#getDistance(Object, Location)}.
511 * <p><p>
512 * WARNING: O(n) complexity!
513 *
514 * @param <T>
515 * @param nthNearest if <= 0, returns the nearest
516 * @param locations
517 * @param target
518 * @param getDistance distance computer between 'locations' and 'target'.
519 * @param filters filters to be used (that can filter out unsuitable results)
520 * @return nth-nearest object from 'locations'
521 */
522 public static <T> T getNthNearest(int nthNearest, Collection<T> locations, ILocated target, IGetDistance getDistance, IDistanceFilter... filters) {
523 return
524 getInNthBestRelation(
525 nthNearest,
526 locations,
527 target,
528 getDistance,
529 relationCloser,
530 filters
531 );
532 }
533
534 /**
535 * Returns the farthest object from 'locations' to 'target' that is accepted by all 'filters'.
536 * <p><p>
537 * Distance is obtained via provided {@link IGetDistance#getDistance(Object, Location)}.
538 * <p><p>
539 * WARNING: O(n) complexity!
540 *
541 * @param <T>
542 * @param locations
543 * @param target
544 * @param getDistance distance computer between 'locations' and 'target'.
545 * @param filters filters to be used (that can filter out unsuitable results)
546 * @return nearest object from 'location'
547 */
548 public static <T> T getFarthest(Collection<T> locations, ILocated target, IGetDistance getDistance, IDistanceFilter... filters) {
549 return
550 getInBestRelation(
551 locations,
552 target,
553 getDistance,
554 relationFurther,
555 filters
556 );
557 }
558
559 /**
560 * Returns the n-th farthest object from 'locations' to 'target' that is accepted by all 'filters'.
561 * <p><p>
562 * Distance is obtained via provided {@link IGetDistance#getDistance(Object, Location)}.
563 * <p><p>
564 * WARNING: O(n) complexity!
565 *
566 * @param <T>
567 * @param nthFarthest if <= 0, returns the farthest
568 * @param locations
569 * @param target
570 * @param getDistance distance computer between 'locations' and 'target'.
571 * @param filters filters to be used (that can filter out unsuitable results)
572 * @return nearest object from 'locations'
573 */
574 public static <T> T getNthFarthest(int nthFarthest, Collection<T> locations, ILocated target, IGetDistance getDistance, IDistanceFilter... filters) {
575 return
576 getInNthBestRelation(
577 nthFarthest,
578 locations,
579 target,
580 getDistance,
581 relationFurther,
582 filters
583 );
584 }
585
586 /**
587 * Returns the nearest object from 'locations' to 'target'.
588 * <p><p>
589 * Distance is obtained via provided {@link IGetDistance#getDistance(Object, Location)}.
590 * <p><p>
591 * WARNING: O(n) complexity!
592 *
593 * @param <T>
594 * @param locations
595 * @param target
596 * @param getDistance distance computer between 'locations' and 'target'.
597 * @return nearest object from 'locations'
598 */
599 public static <T> T getNearest(Collection<T> locations, ILocated target, IGetDistance getDistance) {
600 return
601 getInBestRelation(
602 locations,
603 target,
604 getDistance,
605 relationCloser
606 );
607 }
608
609 /**
610 * Returns the n-th nearest object from 'locations' to 'target'.
611 * <p><p>
612 * Distance is obtained via provided {@link IGetDistance#getDistance(Object, Location)}.
613 * <p><p>
614 * WARNING: O(n) complexity!
615 *
616 * @param <T>
617 * @param nthNearest if <= 0, returns the nearest
618 * @param locations
619 * @param target
620 * @param getDistance distance computer between 'locations' and 'target'.
621 * @return nth-nearest object from 'locations'
622 */
623 public static <T> T getNthNearest(int nthNearest, Collection<T> locations, ILocated target, IGetDistance getDistance) {
624 return
625 getInNthBestRelation(
626 nthNearest,
627 locations,
628 target,
629 getDistance,
630 relationCloser
631 );
632 }
633
634 /**
635 * Returns the farthest object to 'target'.
636 * <p><p>
637 * Distance is obtained via provided {@link IGetDistance#getDistance(Object, Location)}.
638 * <p><p>
639 * WARNING: O(n) complexity!
640 *
641 * @param <T>
642 * @param locations
643 * @param target
644 * @param getDistance distance computer between 'locations' and 'target'.
645 * @return farthest object from 'locations'
646 */
647 public static <T> T getFarthest(Collection<T> locations, ILocated target, IGetDistance getDistance) {
648 return
649 getInBestRelation(
650 locations,
651 target,
652 getDistance,
653 relationFurther
654 );
655 }
656
657 /**
658 * Returns the n-th farthest object from 'locations' to 'target'.
659 * <p><p>
660 * Distance is obtained via provided {@link IGetDistance#getDistance(Object, Location)}.
661 * <p><p>
662 * WARNING: O(n) complexity!
663 *
664 * @param <T>
665 * @param nthFarthest if <= 0, returns the farthest
666 * @param locations
667 * @param target
668 * @param getDistance distance computer between 'locations' and 'target'.
669 * @return nth-farthest object from 'locations'
670 */
671 public static <T> T getNthFarthest(int nthFarthest, Collection<T> locations, ILocated target, IGetDistance getDistance) {
672 return
673 getInNthBestRelation(
674 nthFarthest,
675 locations,
676 target,
677 getDistance,
678 relationFurther
679 );
680 }
681
682 /**
683 * Returns the nearest object from 'locations' to 'target' that is accepted by all 'filters'.
684 * <p><p>
685 * WARNING: O(n) complexity!
686 *
687 * @param <T>
688 * @param locations
689 * @param target
690 * @param filters
691 * @return nearest object from 'locations'
692 */
693 public static <T extends ILocated> T getNearest(Collection<T> locations, ILocated target, IDistanceFilter... filters) {
694 return getNearest(locations, target, getLocatedDistance3D, filters);
695 }
696
697 /**
698 * Returns the nearest object from 'locations' to 'target' that is accepted by all 'filters'.
699 * <p><p>
700 * WARNING: O(n) complexity!
701 *
702 * @param <T>
703 * @param nthNearest if <= 0, returns the nearest
704 * @param locations
705 * @param target
706 * @param filters
707 * @return nearest object from 'locations'
708 */
709 public static <T extends ILocated> T getNthNearest(int nthNearest, Collection<T> locations, ILocated target, IDistanceFilter... filters) {
710 return getNthNearest(nthNearest, locations, target, getLocatedDistance3D, filters);
711 }
712
713 /**
714 * Returns the farthest object from 'locations' to 'target' that is accepted by all 'filters'.
715 * <p><p>
716 * WARNING: O(n) complexity!
717 *
718 * @param <T>
719 * @param locations
720 * @param target
721 * @param filters
722 * @return farthest object from 'locations'
723 */
724 public static <T extends ILocated> T getFarthest(Collection<T> locations, ILocated target, IDistanceFilter... filters) {
725 return getFarthest(locations, target, getLocatedDistance3D, filters);
726 }
727
728 /**
729 * Returns the nth-farthest object from 'locations' to 'target' that is accepted by all 'filters'.
730 * <p><p>
731 * WARNING: O(n) complexity!
732 *
733 * @param <T>
734 * @param nthFarthest if <= 0, returns the farthest
735 * @param locations
736 * @param target
737 * @param filters
738 * @return nth-farthest object from 'locations'
739 */
740 public static <T extends ILocated> T getNthFarthest(int nthFarthest, Collection<T> locations, ILocated target, IDistanceFilter... filters) {
741 return getNthFarthest(nthFarthest, locations, target, getLocatedDistance3D, filters);
742 }
743
744 /**
745 * Returns the nearest object from 'locations' to 'target'.
746 * <p><p>
747 * WARNING: O(n) complexity!
748 *
749 * @param <T>
750 * @param locations
751 * @param target
752 * @return nearest object from 'locations'
753 */
754 public static <T extends ILocated> T getNearest(Collection<T> locations, ILocated target) {
755 return getNearest(locations, target, getLocatedDistance3D);
756 }
757
758 /**
759 * Returns the nth-nearest object from 'locations' to 'target'.
760 * <p><p>
761 * WARNING: O(n) complexity!
762 *
763 * @param <T>
764 * @param nthNearest if <= 0, returns the nearest
765 * @param locations
766 * @param target
767 * @return nth-nearest object from 'locations'
768 */
769 public static <T extends ILocated> T getNthNearest(int nthNearest, Collection<T> locations, ILocated target) {
770 return getNthNearest(nthNearest, locations, target, getLocatedDistance3D);
771 }
772
773 /**
774 * Returns the farthest object from 'locations' to 'target'.
775 * <p><p>
776 * WARNING: O(n) complexity!
777 *
778 * @param <T>
779 * @param locations
780 * @param target
781 * @return farthest object from 'locations'
782 */
783 public static <T extends ILocated> T getFarthest(Collection<T> locations, ILocated target) {
784 return getFarthest(locations, target, getLocatedDistance3D);
785 }
786
787 /**
788 * Returns the nth-farthest object from 'locations' to 'target'.
789 * <p><p>
790 * WARNING: O(n) complexity!
791 *
792 * @param <T>
793 * @param nthFarthest if <= 0, returns the farthest
794 * @param locations
795 * @param target
796 * @return nth-farthest object from 'locations'
797 */
798 public static <T extends ILocated> T getNthFarthest(int nthFarthest, Collection<T> locations, ILocated target) {
799 return getNthFarthest(nthFarthest, locations, target, getLocatedDistance3D);
800 }
801
802 /**
803 * Returns the nearest object from 'locations' to 'target' that is not further than 'maxDistance'.
804 * <p><p>
805 * Using {@link RangeDistanceFilter} (minDistance = 0, maxDistance is provided).
806 * <p><p>
807 * WARNING: O(n) complexity!
808 *
809 * @param <T>
810 * @param locations
811 * @param target
812 * @param maxDistance
813 * @return nearest object from 'locations' that is not further than 'maxDistance'
814 */
815 public static <T extends ILocated> T getNearest(Collection<T> locations, ILocated target, double maxDistance) {
816 return getNearest(locations, target, new RangeDistanceFilter<T>(0, maxDistance));
817 }
818
819 /**
820 * Returns the nth-nearest object from 'locations' to 'target' that is not further than 'maxDistance'.
821 * <p><p>
822 * Using {@link RangeDistanceFilter} (minDistance = 0, maxDistance is provided).
823 * <p><p>
824 * WARNING: O(n) complexity!
825 *
826 * @param <T>
827 * @param nthNearest if <= 0, returns the nearest
828 * @param locations
829 * @param target
830 * @param maxDistance
831 * @return nth-nearest object from 'locations' that is not further than 'maxDistance'
832 */
833 public static <T extends ILocated> T getNthNearest(int nthNearest, Collection<T> locations, ILocated target, double maxDistance) {
834 return getNthNearest(nthNearest, locations, target, new RangeDistanceFilter<T>(0, maxDistance));
835 }
836
837 /**
838 * Returns the farthest object from 'locations' to 'target' that is not further than 'maxDistance'.
839 * <p><p>
840 * Using {@link RangeDistanceFilter} (minDistance = 0, maxDistance is provided).
841 * <p><p>
842 * WARNING: O(n) complexity!
843 *
844 * @param <T>
845 * @param locations
846 * @param target
847 * @param maxDistance
848 * @return farthest object from 'locations' that is not further than 'maxDistance'
849 */
850 public static <T extends ILocated> T getFarthest(Collection<T> locations, ILocated target, double maxDistance) {
851 return getFarthest(locations, target, new RangeDistanceFilter<T>(0, maxDistance));
852 }
853
854 /**
855 * Returns the nth-farthest object from 'locations' to 'target' that is not further than 'maxDistance'.
856 * <p><p>
857 * Using {@link RangeDistanceFilter} (minDistance = 0, maxDistance is provided).
858 * <p><p>
859 * WARNING: O(n) complexity!
860 *
861 * @param <T>
862 * @param nthFarthest if <= 0, returns the farthest
863 * @param locations
864 * @param target
865 * @param maxDistance
866 * @return nth-farthest object from 'locations' that is not further than 'maxDistance'
867 */
868 public static <T extends ILocated> T getNthFarthest(int nthFarthest, Collection<T> locations, ILocated target, double maxDistance) {
869 return getNthFarthest(nthFarthest, locations, target, new RangeDistanceFilter<T>(0, maxDistance));
870 }
871
872 /**
873 * Returns the nearest object from 'location' to 'target' that is accepted by 'filter'.
874 * <p><p>
875 * WARNING: O(n) complexity!
876 *
877 * @param <T>
878 * @param locations
879 * @param target
880 * @param filter if null behave as if ALL locations are accepted
881 * @return nearest object from 'locations' accepted by 'filter'
882 */
883 public static <T extends ILocated> T getNearestFiltered(Collection<T> locations, ILocated target, IFilter filter) {
884 if (filter == null) {
885 return getNearest(locations, target);
886 }
887 return getNearest(locations, target, new FilterAdapter<T>(filter));
888 }
889
890 /**
891 * Returns the nth-nearest object from 'locations' to 'target' that is accepted by 'filter'.
892 * <p><p>
893 * WARNING: O(n) complexity!
894 *
895 * @param <T>
896 * @param nthNearest if <= 0, returns the nearest
897 * @param locations
898 * @param target
899 * @param filter if null behave as if ALL locations are accepted
900 * @return nth-nearest object from 'locations' accepted by 'filter'
901 */
902 public static <T extends ILocated> T getNthNearestFiltered(int nthNearest, Collection<T> locations, ILocated target, IFilter filter) {
903 if (filter == null) {
904 return getNthNearest(nthNearest, locations, target);
905 }
906 return getNthNearest(nthNearest, locations, target, new FilterAdapter<T>(filter));
907 }
908
909 /**
910 * Returns the farthest object from 'locations' to 'target' that is accepted by 'filter'.
911 * <p><p>
912 * WARNING: O(n) complexity!
913 *
914 * @param <T>
915 * @param locations
916 * @param target
917 * @param filter if null behave as if ALL locations are accepted
918 * @return farthest object from 'locations' accepted by 'filter'
919 */
920 public static <T extends ILocated> T getFarthestFiltered(Collection<T> locations, ILocated target, IFilter filter) {
921 if (filter == null) {
922 return getFarthest(locations, target);
923 }
924 return getFarthest(locations, target, new FilterAdapter<T>(filter));
925 }
926
927 /**
928 * Returns the nth-farthest object from 'locations' to 'target' that is accepted by 'filter'.
929 * <p><p>
930 * WARNING: O(n) complexity!
931 *
932 * @param <T>
933 * @param nthFarthest if <= 0, returns the farthest
934 * @param locations
935 * @param target
936 * @param filter if null behave as if ALL locations are accepted
937 * @return nth-farthest object from 'locations' accepted by 'filter'
938 */
939 public static <T extends ILocated> T getNthFarthestFiltered(int nthFarthest, Collection<T> locations, ILocated target, IFilter filter) {
940 if (filter == null) {
941 return getNthFarthest(nthFarthest, locations, target);
942 }
943 return getNthFarthest(nthFarthest, locations, target, new FilterAdapter<T>(filter));
944 }
945
946 /**
947 * Returns the nearest object from 'locations' to 'target' that is visible (using {@link VisibleFilter}).
948 * <p><p>
949 * WARNING: O(n) complexity!
950 *
951 * @param <T>
952 * @param locations must be objects implementing {@link IViewable} as well as {@link ILocated} (so {@link Item} or {@link Player} is usable)
953 * @param target
954 * @return nearest visible object from 'locations'
955 */
956 public static <T extends IViewable> T getNearestVisible(Collection<T> locations, ILocated target) {
957 return getNearest(locations, target, getLocatedDistance3D, visibleFilter);
958 }
959
960 /**
961 * Returns the nth-nearest object from 'locations' to 'target' that is visible (using {@link VisibleFilter}).
962 * <p><p>
963 * WARNING: O(n) complexity!
964 *
965 * @param <T>
966 * @param ntNearest if <= 0, returns the nearest
967 * @param locations must be objects implementing {@link IViewable} as well as {@link ILocated} (so {@link Item} or {@link Player} is usable)
968 * @param target
969 * @return nth-nearest visible object from 'locations'
970 */
971 public static <T extends IViewable> T getNthNearestVisible(int nthNearest, Collection<T> locations, ILocated target) {
972 return getNthNearest(nthNearest, locations, target, getLocatedDistance3D, visibleFilter);
973 }
974
975 /**
976 * Returns the farthest object from 'locations' to 'target' that is visible (using {@link VisibleFilter}).
977 * <p><p>
978 * WARNING: O(n) complexity!
979 *
980 * @param <T>
981 * @param locations must be objects implementing {@link IViewable} as well as {@link ILocated} (so {@link Item} or {@link Player} is usable)
982 * @param target
983 * @return farthest visible object from 'locations'
984 */
985 public static <T extends IViewable> T getFarthestVisible(Collection<T> locations, ILocated target) {
986 return getFarthest(locations, target, getLocatedDistance3D, visibleFilter);
987 }
988
989 /**
990 * Returns the nth-farthest object from 'locations' to 'target' that is visible (using {@link VisibleFilter}).
991 * <p><p>
992 * WARNING: O(n) complexity!
993 *
994 * @param <T>
995 * @param ntFarthest if <= 0, returns the farthest
996 * @param locations must be objects implementing {@link IViewable} as well as {@link ILocated} (so {@link Item} or {@link Player} is usable)
997 * @param target
998 * @return nth-farthest visible object from 'locations'
999 */
1000 public static <T extends IViewable> T getNthFarthestVisible(int nthFarthest, Collection<T> locations, ILocated target) {
1001 return getNthFarthest(nthFarthest, locations, target, getLocatedDistance3D, visibleFilter);
1002 }
1003
1004 // --------------
1005 // =====================
1006 // getDistanceSorted()
1007 // =====================
1008 // --------------
1009
1010 private static class DistancesComparator implements Comparator<Tuple2<Object, Double>> {
1011
1012 @Override
1013 public int compare(Tuple2<Object, Double> o1, Tuple2<Object, Double> o2) {
1014 double result = o1.getSecond() - o2.getSecond();
1015 if (result < 0) return -1;
1016 if (result > 0) return 1;
1017 return 0;
1018 }
1019
1020 }
1021
1022 private static final DistancesComparator distancesComparator = new DistancesComparator();
1023
1024 /**
1025 * Returns "locations" sorted according to the distance to "target". Sorted from the nearest to the farthest.
1026 * <p><p>
1027 * Distance is provided by {@link IGetDistance#getDistance(Object, Location)}.
1028 * <p><p>
1029 * WARNING: 2*O(n) + O(n*log n) complexity!
1030 *
1031 * @param <T>
1032 * @param locations
1033 * @param target
1034 * @param getDistance
1035 * @return
1036 */
1037 public static <T> List<T> getDistanceSorted(Collection<T> locations, ILocated target, IGetDistance getDistance) {
1038 if (locations == null) return null;
1039 if (target == null) return null;
1040 if (target.getLocation() == null) return null;
1041 if (getDistance == null) return null;
1042
1043 List<Tuple2<T, Double>> distances = new ArrayList<Tuple2<T, Double>>(locations.size());
1044
1045 for (T location : locations) {
1046 double distance = getDistance.getDistance(location, target);
1047 distances.add(new Tuple2<T, Double>(location, distance));
1048 }
1049
1050 Collections.sort((List)distances, (Comparator)distancesComparator);
1051
1052 List<T> result = new ArrayList<T>(distances.size());
1053
1054 for (Tuple2<T, Double> location : distances) {
1055 result.add(location.getFirst());
1056 }
1057
1058 return result;
1059 }
1060
1061 /**
1062 * Returns "locations" accepted by all "filters" sorted according to the distance to "target". Sorted from the nearest to the farthest.
1063 * <p><p>
1064 * Distance is provided by {@link IGetDistance#getDistance(Object, Location)}.
1065 * <p><p>
1066 * WARNING: 2*O(n) + O(n*log n) complexity!
1067 *
1068 * @param <T>
1069 * @param locations
1070 * @param target
1071 * @param getDistance
1072 * @return
1073 */
1074 public static <T> List<T> getDistanceSorted(Collection<T> locations, ILocated target, IGetDistance getDistance, IDistanceFilter... filters) {
1075 if (filters == null || filters.length == 0 || (filters.length == 1 && filters[0] instanceof AcceptAllDistanceFilter)) {
1076 return getDistanceSorted(locations, target, getDistance);
1077 }
1078 if (locations == null) return null;
1079 if (target == null) return null;
1080 if (getDistance == null) return null;
1081 Location targetLoc = target.getLocation();
1082 if (targetLoc == null) return null;
1083
1084 List<Tuple2<T, Double>> distances = new ArrayList<Tuple2<T, Double>>(locations.size());
1085
1086 for (T location : locations) {
1087 boolean accepted = true;
1088 double distance = getDistance.getDistance(location, targetLoc);
1089 for (IDistanceFilter filter : filters) {
1090 if (!filter.isAccepted(location, targetLoc, distance)) {
1091 accepted = false;
1092 break;
1093 }
1094 }
1095 if (!accepted) continue;
1096
1097 distances.add(new Tuple2<T, Double>(location, distance));
1098 }
1099
1100 Collections.sort((List)distances, (Comparator)distancesComparator);
1101
1102 List<T> result = new ArrayList<T>(distances.size());
1103
1104 for (Tuple2<T, Double> location : distances) {
1105 result.add(location.getFirst());
1106 }
1107
1108 return result;
1109 }
1110
1111 /**
1112 * Returns "locations" accepted by all "filters" sorted according to the distance to "target". Sorted from the nearest to the farthest.
1113 * <p><p>
1114 * WARNING: 2*O(n) + O(n*log n) complexity!
1115 *
1116 * @param <T>
1117 * @param locations
1118 * @param target
1119 * @param filters
1120 * @return nearest object from collection of objects
1121 */
1122 public static <T extends ILocated> List<T> getDistanceSorted(Collection<T> locations, ILocated target, IDistanceFilter... filters) {
1123 return getDistanceSorted(locations, target, getLocatedDistance3D, filters);
1124 }
1125
1126 /**
1127 * Returns "locations" sorted according to the distance to "target". Sorted from the nearest to the farthest.
1128 * <p><p>
1129 * WARNING: 2*O(n) + O(n*log n) complexity!
1130 *
1131 * @param <T>
1132 * @param locations
1133 * @param target
1134 * @return nearest object from collection of objects
1135 */
1136 public static <T extends ILocated> List<T> getDistanceSorted(Collection<T> locations, ILocated target) {
1137 return getDistanceSorted(locations, target, getLocatedDistance3D);
1138 }
1139
1140 /**
1141 * Returns "locations" sorted according to the distance to "target". Sorted from the nearest to the farthest.
1142 * <p><p>
1143 * Using {@link RangeDistanceFilter} (minDistance = 0, maxDistance is provided).
1144 * <p><p>
1145 * WARNING: 2*O(n) + O(n*log n) complexity!
1146 *
1147 *
1148 * @param <T>
1149 * @param locations
1150 * @param target
1151 * @param maxDistance
1152 * @return nearest object from collection of objects that is not further than 'maxDistance'.
1153 */
1154 public static <T extends ILocated> List<T> getDistanceSorted(Collection<T> locations, ILocated target, double maxDistance) {
1155 return getDistanceSorted(locations, target, new RangeDistanceFilter<T>(0, maxDistance));
1156 }
1157
1158 /**
1159 * Returns "locations" sorted according to the distance to "target". Sorted from the nearest to the farthest.
1160 * <p><p>
1161 * WARNING: 2*O(n) + O(n*log n) complexity!
1162 *
1163 * @param <T>
1164 * @param locations
1165 * @param target
1166 * @param filter if null behave as if ALL locations are accepted
1167 * @return nearest object from collection of objects
1168 */
1169 public static <T extends ILocated> List<T> getDistanceSortedFiltered(Collection<T> locations, ILocated target, IFilter filter) {
1170 if (filter == null) {
1171 return getDistanceSorted(locations, target);
1172 }
1173 return getDistanceSorted(locations, target, new FilterAdapter<T>(filter));
1174 }
1175
1176 /**
1177 * Returns visible "locations" sorted according to the distance to "target". Sorted from the nearest to the farthest.
1178 * <p><p>
1179 * WARNING: 2*O(n) + O(n*log n) complexity!
1180 *
1181 * @param <T>
1182 * @param locations must be objects implementing {@link IViewable} as well as {@link ILocated} (so {@link Item} or {@link Player} is usable)
1183 * @param target
1184 * @return nearest visible object from collection of objects
1185 */
1186 public static <T extends IViewable> List<T> getDistanceSortedVisible(Collection<T> locations, ILocated target) {
1187 return (List<T>) getDistanceSorted(locations, target, (IGetDistance)getLocatedDistance3D, (IDistanceFilter)visibleFilter);
1188 }
1189
1190 // --------------
1191 // =====================
1192 // getSecondNearest()
1193 // =====================
1194 // --------------
1195
1196 /**
1197 * Returns the second nearest object to 'target'.
1198 * <p><p>
1199 * Distance is provided by {@link IGetDistance#getDistance(Object, ILocated)}.
1200 * <p><p>
1201 * WARNING: O(n) complexity!
1202 * <p><p>
1203 * DEPRECATED: use {@link #getNthNearest(int, Collection, ILocated, IGetDistance)} instead!
1204 *
1205 * @param <T>
1206 * @param locations
1207 * @param target
1208 * @return nearest object from collection of objects
1209 */
1210 @Deprecated
1211 public static <T> T getSecondNearest(Collection<T> locations, ILocated target, IGetDistance getDistance) {
1212 return getNthNearest(2, locations, target, getDistance);
1213 }
1214
1215 /**
1216 * Returns the second nearest object to 'target'.
1217 * <p><p>
1218 * WARNING: O(n) complexity!
1219 * <p><p>
1220 * DEPRECATED: use {@link #getNthNearest(int, Collection, ILocated, IGetDistance, IDistanceFilter...)} instead
1221 *
1222 * @param <T>
1223 * @param locations
1224 * @param target
1225 * @return nearest object from collection of objects
1226 */
1227 @Deprecated
1228 public static <T> T getSecondNearest(Collection<T> locations, ILocated target, IGetDistance getDistance, IDistanceFilter... filters) {
1229 return getNthNearest(2, locations, target, getDistance, filters);
1230 }
1231
1232 /**
1233 * Returns the second nearest object to 'target' that is accepted by all 'filters'.
1234 * <p><p>
1235 * WARNING: O(n) complexity!
1236 * <p><p>
1237 * DEPRECATED: use {@link #getNthNearest(int, Collection, ILocated, IDistanceFilter...))} instead
1238 *
1239 * @param <T>
1240 * @param locations
1241 * @param target
1242 * @param filters
1243 * @return nearest object from collection of objects
1244 */
1245 @Deprecated
1246 public static <T extends ILocated> T getSecondNearest(Collection<T> locations, ILocated target, IDistanceFilter... filters) {
1247 return getNthNearest(2, locations, target, filters);
1248 }
1249
1250 /**
1251 * Returns the second nearest object to 'target'.
1252 * <p><p>
1253 * WARNING: O(n) complexity!
1254 * <p><p>
1255 * DEPRECATED: use {@link #getNthNearest(int, Collection, ILocated)} instead
1256 *
1257 * @param <T>
1258 * @param locations
1259 * @param target
1260 * @return second nearest object from collection of objects
1261 */
1262 @Deprecated
1263 public static <T extends ILocated> T getSecondNearest(Collection<T> locations, ILocated target) {
1264 return getNthNearest(2, locations, target);
1265 }
1266
1267 /**
1268 * Returns the second nearest object to 'target' that is not further than 'maxDistance'.
1269 * <p><p>
1270 * Using {@link RangeDistanceFilter} (minDistance = 0, maxDistance is provided).
1271 * <p><p>
1272 * WARNING: O(n) complexity!
1273 * <p><p>
1274 * DEPRECATED: use {@link #getNthNearest(int, Collection, ILocated, double)} instead
1275 *
1276 * @param <T>
1277 * @param locations
1278 * @param target
1279 * @param maxDistance
1280 * @return second nearest object from collection of objects that is not further than 'maxDistance'.
1281 */
1282 @Deprecated
1283 public static <T extends ILocated> T getSecondNearest(Collection<T> locations, ILocated target, double maxDistance) {
1284 return getNthNearest(2, locations, target, new RangeDistanceFilter<T>(0, maxDistance));
1285 }
1286
1287 /**
1288 * Returns the second nearest object to 'target' that is accepted by filter.
1289 * <p><p>
1290 * WARNING: O(n) complexity!
1291 * <p><p>
1292 * DEPRECATED: use {@link #getNthNearestFiltered(int, Collection, ILocated, IFilter)} instead
1293 *
1294 * @param <T>
1295 * @param locations
1296 * @param target
1297 * @param filter if null behave as if ALL locations are accepted
1298 * @return second nearest object from collection of objects
1299 */
1300 @Deprecated
1301 public static <T extends ILocated> T getSecondNearestFiltered(Collection<T> locations, ILocated target, IFilter filter) {
1302 return getNthNearestFiltered(2, locations, target, filter);
1303 }
1304
1305 /**
1306 * Returns the second nearest object to 'target' that is visible (using {@link VisibleFilter}).
1307 * <p><p>
1308 * WARNING: O(n) complexity!
1309 * <p><p>
1310 * DEPRECATED: use {@link #getNthNearestVisible(int, Collection, ILocated)
1311 *
1312 * @param <T>
1313 * @param locations must be objects implementing {@link IViewable} as well as {@link ILocated} (so {@link Item} or {@link Player} is usable)
1314 * @param target
1315 * @return second nearest visible object from collection of objects
1316 */
1317 @Deprecated
1318 public static <T extends IViewable> T getSecondNearestVisible(Collection<T> locations, ILocated target) {
1319 return getNthNearestVisible(2, locations, target);
1320 }
1321
1322 // --------------
1323 // =====================
1324 // getNearest2D()
1325 // =====================
1326 // --------------
1327
1328 /**
1329 * Returns the nearest (in 2D ~ [x,y]) object from 'locations' to 'target' that is accepted by all 'filters'.
1330 * <p><p>
1331 * WARNING: O(n) complexity!
1332 *
1333 * @param <T>
1334 * @param locations
1335 * @param target
1336 * @param filters
1337 * @return nearest (in 2D ~ [x,y]) object from 'locations'
1338 */
1339 public static <T extends ILocated> T getNearest2D(Collection<T> locations, ILocated target, IDistanceFilter... filters) {
1340 return getNearest(locations, target, getLocatedDistance2D, filters);
1341 }
1342
1343 /**
1344 * Returns the nearest (in 2D ~ [x,y]) object from 'locations' to 'target' that is accepted by all 'filters'.
1345 * <p><p>
1346 * WARNING: O(n) complexity!
1347 *
1348 * @param <T>
1349 * @param nthNearest if <= 0, returns the nearest
1350 * @param locations
1351 * @param target
1352 * @param filters
1353 * @return nearest (in 2D ~ [x,y]) object from 'locations'
1354 */
1355 public static <T extends ILocated> T getNthNearest2D(int nthNearest, Collection<T> locations, ILocated target, IDistanceFilter... filters) {
1356 return getNthNearest(nthNearest, locations, target, getLocatedDistance2D, filters);
1357 }
1358
1359 /**
1360 * Returns the farthest (in 2D ~ [x,y]) object from 'locations' to 'target' that is accepted by all 'filters'.
1361 * <p><p>
1362 * WARNING: O(n) complexity!
1363 *
1364 * @param <T>
1365 * @param locations
1366 * @param target
1367 * @param filters
1368 * @return farthest (in 2D ~ [x,y]) object from 'locations'
1369 */
1370 public static <T extends ILocated> T getFarthest2D(Collection<T> locations, ILocated target, IDistanceFilter... filters) {
1371 return getFarthest(locations, target, getLocatedDistance2D, filters);
1372 }
1373
1374 /**
1375 * Returns the nth-farthest (in 2D ~ [x,y]) object from 'locations' to 'target' that is accepted by all 'filters'.
1376 * <p><p>
1377 * WARNING: O(n) complexity!
1378 *
1379 * @param <T>
1380 * @param nthFarthest if <= 0, returns the farthest
1381 * @param locations
1382 * @param target
1383 * @param filters
1384 * @return nth-farthest (in 2D ~ [x,y]) object from 'locations'
1385 */
1386 public static <T extends ILocated> T getNthFarthest2D(int nthFarthest, Collection<T> locations, ILocated target, IDistanceFilter... filters) {
1387 return getNthFarthest(nthFarthest, locations, target, getLocatedDistance2D, filters);
1388 }
1389
1390 /**
1391 * Returns the nearest (in 2D ~ [x,y]) object from 'locations' to 'target'.
1392 * <p><p>
1393 * WARNING: O(n) complexity!
1394 *
1395 * @param <T>
1396 * @param locations
1397 * @param target
1398 * @return nearest (in 2D ~ [x,y]) object from 'locations'
1399 */
1400 public static <T extends ILocated> T getNearest2D(Collection<T> locations, ILocated target) {
1401 return getNearest(locations, target, getLocatedDistance2D);
1402 }
1403
1404 /**
1405 * Returns the nth-nearest (in 2D ~ [x,y]) object from 'locations' to 'target'.
1406 * <p><p>
1407 * WARNING: O(n) complexity!
1408 *
1409 * @param <T>
1410 * @param nthNearest if <= 0, returns the nearest
1411 * @param locations
1412 * @param target
1413 * @return nth-nearest (in 2D ~ [x,y]) object from 'locations'
1414 */
1415 public static <T extends ILocated> T getNthNearest2D(int nthNearest, Collection<T> locations, ILocated target) {
1416 return getNthNearest(nthNearest, locations, target, getLocatedDistance2D);
1417 }
1418
1419 /**
1420 * Returns the farthest (in 2D ~ [x,y]) object from 'locations' to 'target'.
1421 * <p><p>
1422 * WARNING: O(n) complexity!
1423 *
1424 * @param <T>
1425 * @param locations
1426 * @param target
1427 * @return farthest (in 2D ~ [x,y]) object from 'locations'
1428 */
1429 public static <T extends ILocated> T getFarthest2D(Collection<T> locations, ILocated target) {
1430 return getFarthest(locations, target, getLocatedDistance2D);
1431 }
1432
1433 /**
1434 * Returns the nth-farthest object from 'locations' to 'target'.
1435 * <p><p>
1436 * WARNING: O(n) complexity!
1437 *
1438 * @param <T>
1439 * @param nthFarthest if <= 0, returns the farthest
1440 * @param locations
1441 * @param target
1442 * @return nth-farthest (in 2D ~ [x,y]) object from 'locations'
1443 */
1444 public static <T extends ILocated> T getNthFarthest2D(int nthFarthest, Collection<T> locations, ILocated target) {
1445 return getNthFarthest(nthFarthest, locations, target, getLocatedDistance2D);
1446 }
1447
1448 /**
1449 * Returns the nearest (in 2D ~ [x,y]) object from 'locations' to 'target' that is not further than 'maxDistance'.
1450 * <p><p>
1451 * Using {@link RangeDistanceFilter} (minDistance = 0, maxDistance is provided).
1452 * <p><p>
1453 * WARNING: O(n) complexity!
1454 *
1455 * @param <T>
1456 * @param locations
1457 * @param target
1458 * @param maxDistance
1459 * @return nearest (in 2D ~ [x,y]) object from 'locations' that is not further than 'maxDistance'
1460 */
1461 public static <T extends ILocated> T getNearest2D(Collection<T> locations, ILocated target, double maxDistance) {
1462 return getNearest2D(locations, target, new RangeDistanceFilter<T>(0, maxDistance));
1463 }
1464
1465 /**
1466 * Returns the nth-nearest (in 2D ~ [x,y]) object from 'locations' to 'target' that is not further than 'maxDistance'.
1467 * <p><p>
1468 * Using {@link RangeDistanceFilter} (minDistance = 0, maxDistance is provided).
1469 * <p><p>
1470 * WARNING: O(n) complexity!
1471 *
1472 * @param <T>
1473 * @param nthNearest if <= 0, returns the nearest
1474 * @param locations
1475 * @param target
1476 * @param maxDistance
1477 * @return nth-nearest (in 2D ~ [x,y]) object from 'locations' that is not further than 'maxDistance'
1478 */
1479 public static <T extends ILocated> T getNthNearest2D(int nthNearest, Collection<T> locations, ILocated target, double maxDistance) {
1480 return getNthNearest2D(nthNearest, locations, target, new RangeDistanceFilter<T>(0, maxDistance));
1481 }
1482
1483 /**
1484 * Returns the farthest (in 2D ~ [x,y]) object from 'locations' to 'target' that is not further than 'maxDistance'.
1485 * <p><p>
1486 * Using {@link RangeDistanceFilter} (minDistance = 0, maxDistance is provided).
1487 * <p><p>
1488 * WARNING: O(n) complexity!
1489 *
1490 * @param <T>
1491 * @param locations
1492 * @param target
1493 * @param maxDistance
1494 * @return farthest (in 2D ~ [x,y]) object from 'locations' that is not further than 'maxDistance'
1495 */
1496 public static <T extends ILocated> T getFarthest2D(Collection<T> locations, ILocated target, double maxDistance) {
1497 return getFarthest2D(locations, target, new RangeDistanceFilter<T>(0, maxDistance));
1498 }
1499
1500 /**
1501 * Returns the nth-farthest (in 2D ~ [x,y]) object from 'locations' to 'target' that is not further than 'maxDistance'.
1502 * <p><p>
1503 * Using {@link RangeDistanceFilter} (minDistance = 0, maxDistance is provided).
1504 * <p><p>
1505 * WARNING: O(n) complexity!
1506 *
1507 * @param <T>
1508 * @param nthFarthest if <= 0, returns the farthest
1509 * @param locations
1510 * @param target
1511 * @param maxDistance
1512 * @return nth-farthest (in 2D ~ [x,y]) object from 'locations' that is not further than 'maxDistance'
1513 */
1514 public static <T extends ILocated> T getNthFarthest2D(int nthFarthest, Collection<T> locations, ILocated target, double maxDistance) {
1515 return getNthFarthest2D(nthFarthest, locations, target, new RangeDistanceFilter<T>(0, maxDistance));
1516 }
1517
1518 /**
1519 * Returns the nearest (in 2D ~ [x,y]) object from 'location' to 'target' that is accepted by 'filter'.
1520 * <p><p>
1521 * WARNING: O(n) complexity!
1522 *
1523 * @param <T>
1524 * @param locations
1525 * @param target
1526 * @param filter if null behave as if ALL locations are accepted
1527 * @return nearest (in 2D ~ [x,y]) object from 'locations' accepted by 'filter'
1528 */
1529 public static <T extends ILocated> T getNearestFiltered2D(Collection<T> locations, ILocated target, IFilter filter) {
1530 if (filter == null) {
1531 return getNearest2D(locations, target);
1532 }
1533 return getNearest2D(locations, target, new FilterAdapter<T>(filter));
1534 }
1535
1536 /**
1537 * Returns the nth-nearest (in 2D ~ [x,y]) object from 'locations' to 'target' that is accepted by 'filter'.
1538 * <p><p>
1539 * WARNING: O(n) complexity!
1540 *
1541 * @param <T>
1542 * @param nthNearest if <= 0, returns the nearest
1543 * @param locations
1544 * @param target
1545 * @param filter if null behave as if ALL locations are accepted
1546 * @return nth-nearest (in 2D ~ [x,y]) object from 'locations' accepted by 'filter'
1547 */
1548 public static <T extends ILocated> T getNthNearestFiltered2D(int nthNearest, Collection<T> locations, ILocated target, IFilter filter) {
1549 if (filter == null) {
1550 return getNthNearest2D(nthNearest, locations, target);
1551 }
1552 return getNthNearest2D(nthNearest, locations, target, new FilterAdapter<T>(filter));
1553 }
1554
1555 /**
1556 * Returns the farthest (in 2D ~ [x,y]) object from 'locations' to 'target' that is accepted by 'filter'.
1557 * <p><p>
1558 * WARNING: O(n) complexity!
1559 *
1560 * @param <T>
1561 * @param locations
1562 * @param target
1563 * @param filter if null behave as if ALL locations are accepted
1564 * @return farthest (in 2D ~ [x,y]) object from 'locations' accepted by 'filter'
1565 */
1566 public static <T extends ILocated> T getFarthestFiltered2D(Collection<T> locations, ILocated target, IFilter filter) {
1567 if (filter == null) {
1568 return getFarthest2D(locations, target);
1569 }
1570 return getFarthest2D(locations, target, new FilterAdapter<T>(filter));
1571 }
1572
1573 /**
1574 * Returns the nth-farthest (in 2D ~ [x,y]) object from 'locations' to 'target' that is accepted by 'filter'.
1575 * <p><p>
1576 * WARNING: O(n) complexity!
1577 *
1578 * @param <T>
1579 * @param nthFarthest if <= 0, returns the farthest
1580 * @param locations
1581 * @param target
1582 * @param filter if null behave as if ALL locations are accepted
1583 * @return nth-farthest (in 2D ~ [x,y]) object from 'locations' accepted by 'filter'
1584 */
1585 public static <T extends ILocated> T getNthFarthestFiltered2D(int nthFarthest, Collection<T> locations, ILocated target, IFilter filter) {
1586 if (filter == null) {
1587 return getNthFarthest2D(nthFarthest, locations, target);
1588 }
1589 return getNthFarthest2D(nthFarthest, locations, target, new FilterAdapter<T>(filter));
1590 }
1591
1592 /**
1593 * Returns the nearest (in 2D ~ [x,y]) object from 'locations' to 'target' that is visible (using {@link VisibleFilter}).
1594 * <p><p>
1595 * WARNING: O(n) complexity!
1596 *
1597 * @param <T>
1598 * @param locations must be objects implementing {@link IViewable} as well as {@link ILocated} (so {@link Item} or {@link Player} is usable)
1599 * @param target
1600 * @return nearest (in 2D ~ [x,y]) visible object from 'locations'
1601 */
1602 public static <T extends IViewable> T getNearestVisible2D(Collection<T> locations, ILocated target) {
1603 return getNearest(locations, target, getLocatedDistance2D, visibleFilter);
1604 }
1605
1606 /**
1607 * Returns the nth-nearest (in 2D ~ [x,y]) object from 'locations' to 'target' that is visible (using {@link VisibleFilter}).
1608 * <p><p>
1609 * WARNING: O(n) complexity!
1610 *
1611 * @param <T>
1612 * @param ntNearest if <= 0, returns the nearest
1613 * @param locations must be objects implementing {@link IViewable} as well as {@link ILocated} (so {@link Item} or {@link Player} is usable)
1614 * @param target
1615 * @return nth-nearest (in 2D ~ [x,y]) visible object from 'locations'
1616 */
1617 public static <T extends IViewable> T getNthNearestVisible2D(int nthNearest, Collection<T> locations, ILocated target) {
1618 return getNthNearest(nthNearest, locations, target, getLocatedDistance2D, visibleFilter);
1619 }
1620
1621 /**
1622 * Returns the farthest (in 2D ~ [x,y]) object from 'locations' to 'target' that is visible (using {@link VisibleFilter}).
1623 * <p><p>
1624 * WARNING: O(n) complexity!
1625 *
1626 * @param <T>
1627 * @param locations must be objects implementing {@link IViewable} as well as {@link ILocated} (so {@link Item} or {@link Player} is usable)
1628 * @param target
1629 * @return farthest (in 2D ~ [x,y]) visible object from 'locations'
1630 */
1631 public static <T extends IViewable> T getFarthestVisible2D(Collection<T> locations, ILocated target) {
1632 return getFarthest(locations, target, getLocatedDistance2D, visibleFilter);
1633 }
1634
1635 /**
1636 * Returns the nth-farthest (in 2D ~ [x,y]) object from 'locations' to 'target' that is visible (using {@link VisibleFilter}).
1637 * <p><p>
1638 * WARNING: O(n) complexity!
1639 *
1640 * @param <T>
1641 * @param ntFarthest if <= 0, returns the farthest
1642 * @param locations must be objects implementing {@link IViewable} as well as {@link ILocated} (so {@link Item} or {@link Player} is usable)
1643 * @param target
1644 * @return nth-farthest (in 2D ~ [x,y]) visible object from 'locations'
1645 */
1646 public static <T extends IViewable> T getNthFarthestVisible2D(int nthFarthest, Collection<T> locations, ILocated target) {
1647 return getNthFarthest(nthFarthest, locations, target, getLocatedDistance2D, visibleFilter);
1648 }
1649
1650 // --------------
1651 // =====================
1652 // getSecondNearest2D()
1653 // =====================
1654 // --------------
1655
1656 /**
1657 * Returns the second nearest (in 2D ~ [x,y]) object to 'target' that is accepted by all 'filters'.
1658 * <p><p>
1659 * WARNING: O(n) complexity!
1660 * <p><p>
1661 * DEPRECATED: use {@link #getNthNearest2D(int, Collection, ILocated, filters)} instead
1662 *
1663 * @param <T>
1664 * @param locations
1665 * @param target
1666 * @param filters
1667 * @return second nearest (in 2D ~ [x,y]) object from collection of objects
1668 */
1669 @Deprecated
1670 public static <T extends ILocated> T getSecondNearest2D(Collection<T> locations, ILocated target, IDistanceFilter... filters) {
1671 return getNthNearest2D(2, locations, target, filters);
1672 }
1673
1674 /**
1675 * Returns the second nearest (in 2D ~ [x,y]) object to 'target'.
1676 * <p><p>
1677 * WARNING: O(n) complexity!
1678 * <p><p>
1679 * DEPRECATAED: use {@link #getNthNearest2D(int, Collection, ILocated)} instead
1680 *
1681 * @param <T>
1682 * @param locations
1683 * @param target
1684 * @return second nearest (in 2D ~ [x,y]) object from collection of objects
1685 */
1686 @Deprecated
1687 public static <T extends ILocated> T getSecondNearest2D(Collection<T> locations, ILocated target) {
1688 return getNthNearest2D(2, locations, target);
1689 }
1690
1691 /**
1692 * Returns the second nearest (in 2D ~ [x,y]) object to 'target' that is not further than 'maxDistance'.
1693 * <p><p>
1694 * Using {@link RangeDistanceFilter} (minDistance = 0, maxDistance is provided).
1695 * <p><p>
1696 * WARNING: O(n) complexity!
1697 * <p><p>
1698 * DEPRECATED: use {@link #getNthNearest2D(int, Collection, ILocated, double)} instead
1699 *
1700 * @param <T>
1701 * @param locations
1702 * @param target
1703 * @param maxDistance
1704 * @return second nearest (in 2D ~ [x,y]) object from collection of objects that is not further than 'maxDistance'.
1705 */
1706 @Deprecated
1707 public static <T extends ILocated> T getSecondNearest2D(Collection<T> locations, ILocated target, double maxDistance) {
1708 return getNthNearest2D(2, locations, target, maxDistance);
1709 }
1710
1711 /**
1712 * Returns the second nearest (in 2D ~ [x,y]) object to 'target' that is accepted by filter.
1713 * <p><p>
1714 * WARNING: O(n) complexity!
1715 * <p><p>
1716 * DEPRECATED: use {@link #getNthNearestFiltered2D(int, Collection, ILocated, IFilter)} instead
1717 *
1718 * @param <T>
1719 * @param locations
1720 * @param target
1721 * @param filter if null behave as if ALL locations are accepted
1722 * @return second nearest (in 2D ~ [x,y]) object from collection of objects
1723 */
1724 @Deprecated
1725 public static <T extends ILocated> T getSecondNearest2DFiltered(Collection<T> locations, ILocated target, IFilter<T> filter) {
1726 if (filter == null) {
1727 return getNthNearest2D(2, locations, target);
1728 }
1729 return getNthNearest2D(2, locations, target, new FilterAdapter<T>(filter));
1730 }
1731
1732 /**
1733 * Returns the second nearest (in 2D ~ [x,y]) object to 'target' that is visible (using {@link VisibleFilter}).
1734 * <p><p>
1735 * WARNING: O(n) complexity!
1736 * <p><p>
1737 * DEPRECATED: use {@link #getNthNearestVisible2D(int, Collection, ILocated)} instead
1738 *
1739 * @param <T>
1740 * @param locations must be objects implementing {@link IViewable} as well as {@link ILocated} (so {@link Item} or {@link Player} is usable)
1741 * @param target
1742 * @return second nearest (in 2D ~ [x,y]) visible object from collection of objects
1743 */
1744 @Deprecated
1745 public static <T extends IViewable> T getSecondNearest2DVisible(Collection<T> locations, ILocated target) {
1746 return getNthNearestVisible2D(2, locations, target);
1747 }
1748
1749 }