diff --git a/runelite-api/src/main/java/net/runelite/api/model/Jarvis.java b/runelite-api/src/main/java/net/runelite/api/model/Jarvis.java index ba29c86b6d..0c60b84462 100644 --- a/runelite-api/src/main/java/net/runelite/api/model/Jarvis.java +++ b/runelite-api/src/main/java/net/runelite/api/model/Jarvis.java @@ -24,9 +24,9 @@ */ package net.runelite.api.model; -import java.util.ArrayList; import java.util.List; import net.runelite.api.Point; +import net.runelite.api.geometry.SimplePolygon; /** * Provides utility methods for computing the convex hull of a list of @@ -41,92 +41,147 @@ public class Jarvis /** * Computes and returns the convex hull of the passed points. *
- * The size of the list must be at least 4, otherwise this method will
+ * The size of the list must be at least 3, otherwise this method will
* return null.
*
* @param points list of points
* @return list containing the points part of the convex hull
*/
+ @Deprecated
public static List
+ * The size of the list must be at least 3, otherwise this method will
+ * return null.
+ *
+ * @return a shape the points part of the convex hull
+ */
+ public static SimplePolygon convexHull(int[] xs, int[] ys)
+ {
+ int length = xs.length;
+
+ // remove any invalid entries
+ {
+ int i = 0, offset = 0;
+ for (; i < length; i++)
+ {
+ if (xs[i] == Integer.MIN_VALUE)
+ {
+ offset++;
+ i++;
+ break;
+ }
+ }
+ for (; i < length; i++)
+ {
+ if (xs[i] == Integer.MIN_VALUE)
+ {
+ offset++;
+ continue;
+ }
+ xs[i - offset] = xs[i];
+ ys[i - offset] = ys[i];
+ }
+ length -= offset;
+ }
+
+ if (length < 3)
+ {
+ return null;
+ }
// find the left most point
- Point left = findLeftMost(points);
+ int left = findLeftMost(xs, ys, length);
// current point we are on
- Point current = left;
+ int current = left;
+
+ SimplePolygon out = new SimplePolygon(new int[16], new int[16], 0);
do
{
- ch.add(current);
- assert ch.size() <= points.size() : "hull has more points than graph";
- if (ch.size() > points.size())
+ int cx = xs[current];
+ int cy = ys[current];
+ out.pushRight(cx, cy);
+
+ if (out.size() > length)
{
- // Just to make sure we never somehow get stuck in this loop
return null;
}
// the next point - all points are to the right of the
// line between current and next
- Point next = null;
+ int next = 0;
+ int nx = xs[next];
+ int ny = ys[next];
- for (Point p : points)
+ for (int i = 1; i < length; i++)
{
- if (next == null)
+ long cp = crossProduct(cx, cy, xs[i], ys[i], nx, ny);
+ if (cp > 0 || (cp == 0 && square(cx - xs[i]) + square(cy - ys[i]) > square(cx - nx) + square(cy - ny)))
{
- next = p;
- continue;
+ next = i;
+ nx = xs[next];
+ ny = ys[next];
}
-
- long cp = crossProduct(current, p, next);
- if (cp > 0 || (cp == 0 && current.distanceTo(p) > current.distanceTo(next)))
- {
- next = p;
- }
- }
-
- // Points can be null if they are behind or very close to the camera.
- if (next == null)
- {
- return null;
}
current = next;
}
while (current != left);
- return ch;
+ return out;
}
- private static Point findLeftMost(List