Last active
June 28, 2019 07:08
-
-
Save duskvirkus/c6633e69cefb7b14328cadd4b47ec00a to your computer and use it in GitHub Desktop.
Jarvis March Algorithm, also known as gift wrapping. Coding in Processing / Java and inspired by thecodingtrain.com computational geomentry.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.util.*; | |
ArrayList<PVector> jarvisMarch(ArrayList<PVector> _input) throws InvalidJarvisInputException { | |
if (_input.size() < 3) throw new InvalidJarvisInputException("Input must have at least 3 PVectors in the list."); | |
ArrayList<PVector> output = new ArrayList<PVector>(); | |
ArrayList<PVector> input = deepCopyArrayListPVector(_input); | |
Collections.sort(input, new leftSorter()); | |
output.add(input.get(0)); | |
int current = 0; // index into output | |
int next = 1; // index into input | |
while (true) { | |
for (int i = 1; i < input.size(); i++) { | |
PVector a = input.get(next).copy().sub(output.get(current)); | |
PVector b = input.get(i).copy().sub(output.get(current)); | |
PVector cross = a.cross(b); | |
if ( cross.z < 0 || (cross.z == 0 && b.mag() > a.mag()) ) { | |
next = i; | |
} | |
} | |
if (next == 0) break; | |
output.add(input.get(next)); | |
current++; | |
input.remove(output.get(current)); | |
next = 0; | |
} | |
return output; | |
} | |
class InvalidJarvisInputException extends Exception { | |
InvalidJarvisInputException(String message) { | |
super("ERROR: Invalid Arguments for jarvisMarch(). " + message); | |
} | |
} | |
class leftSorter implements Comparator<PVector> { | |
int compare(PVector a, PVector b) { | |
return round(a.x - b.x); | |
} | |
} | |
ArrayList<PVector> deepCopyArrayListPVector(ArrayList<PVector> ls) { | |
ArrayList<PVector> cp = new ArrayList<PVector>(ls.size()); | |
for (PVector v : ls) { | |
cp.add(v.copy()); | |
} | |
return cp; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
int WIDTH = 600; | |
int HEIGHT = 600; | |
ArrayList<PVector> points = new ArrayList<PVector>(); | |
ArrayList<PVector> hull; | |
void settings() { | |
size(WIDTH, HEIGHT); | |
} | |
void setup() { | |
int padding = width / 8; | |
for (int i = 0; i < 25; i++) { | |
points.add(new PVector(random(padding, width - padding), random(padding, height - padding))); | |
} | |
try { | |
hull = jarvisMarch(points); | |
} catch (Exception e) { | |
e.printStackTrace(); | |
exit(); | |
} | |
} | |
void draw() { | |
beginShape(); | |
for (int i = 0; i < hull.size(); i++) { | |
vertex(hull.get(i).x, hull.get(i).y); | |
} | |
endShape(CLOSE); | |
for (int i = 0; i < points.size(); i++) { | |
circle(points.get(i).x, points.get(i).y, 3); | |
} | |
noLoop(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment