Skip to content

Instantly share code, notes, and snippets.

@miyu
Created November 19, 2017 12:14
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save miyu/6e32e993d93d932c419f1f46020e23f0 to your computer and use it in GitHub Desktop.
Save miyu/6e32e993d93d932c419f1f46020e23f0 to your computer and use it in GitHub Desktop.
public static IntVector2[] ConvexHull3(IntVector2 a, IntVector2 b, IntVector2 c) {
var abc = Clockness(a, b, c);
if (abc == Clk.Neither) {
var (s, t) = FindCollinearBounds(a, b, c);
return s == t ? new[] { s } : new[] { s, t };
}
if (abc == Clk.Clockwise) {
return new[] { c, b, a };
}
return new[] { a, b, c };
}
public static (IntVector2, IntVector2) FindCollinearBounds(IntVector2 a, IntVector2 b, IntVector2 c) {
var ab = a.To(b).SquaredNorm2();
var ac = a.To(c).SquaredNorm2();
var bc = b.To(c).SquaredNorm2();
if (ab > ac) {
return ab > bc ? (a, b) : (b, c);
} else {
return ac > bc ? (a, c) : (b, c);
}
}
// See https://stackoverflow.com/questions/2122305/convex-hull-of-4-points
public static IntVector2[] ConvexHull4(IntVector2 a, IntVector2 b, IntVector2 c, IntVector2 d) {
var abc = Clockness(a, b, c);
if (abc == Clk.Neither) {
var (s, t) = FindCollinearBounds(a, b, c);
return ConvexHull3(s, t, d);
}
// make abc ccw
if (abc == Clk.Clockwise) (a, c) = (c, a);
var abd = Clockness(a, b, d);
var bcd = Clockness(b, c, d);
var cad = Clockness(c, a, d);
if (abd == Clk.Neither) {
var (s, t) = FindCollinearBounds(a, b, d);
return ConvexHull3(s, t, c);
}
if (bcd == Clk.Neither) {
var (s, t) = FindCollinearBounds(b, c, d);
return ConvexHull3(s, t, a);
}
if (cad == Clk.Neither) {
var (s, t) = FindCollinearBounds(c, a, d);
return ConvexHull3(s, t, b);
}
if (abd == Clk.CounterClockwise) {
if (bcd == Clk.CounterClockwise && cad == Clk.CounterClockwise) return new[] { a, b, c };
if (bcd == Clk.CounterClockwise && cad == Clk.Clockwise) return new[] { a, b, c, d };
if (bcd == Clk.Clockwise && cad == Clk.CounterClockwise) return new[] { a, b, d, c };
if (bcd == Clk.Clockwise && cad == Clk.Clockwise) return new[] { a, b, d };
throw new InvalidStateException();
} else {
if (bcd == Clk.CounterClockwise && cad == Clk.CounterClockwise) return new[] { a, d, b, c };
if (bcd == Clk.CounterClockwise && cad == Clk.Clockwise) return new[] { d, b, c };
if (bcd == Clk.Clockwise && cad == Clk.CounterClockwise) return new[] { a, d, c };
// 4th state impossible
throw new InvalidStateException();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment