Last active
August 29, 2015 14:05
-
-
Save lukashaertel/c9e842c096f7b7bb787b to your computer and use it in GitHub Desktop.
This file contains hidden or 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
package eu.metatools.risk; | |
import com.badlogic.gdx.math.Intersector; | |
import com.badlogic.gdx.math.Vector2; | |
public class Borderizer { | |
private static <T> T in(T[] t, int i) { | |
return t[((i % t.length) + t.length) % t.length]; | |
} | |
private static float standart(float f) { | |
return ((f % 360.0f) + 360.0f) % 360.0f; | |
} | |
public static void borderize(float[] vertices, float radius, | |
float maxAnglePerSegment, TriangleConsumer con, boolean p) { | |
Vector2[] vs = new Vector2[vertices.length / 2]; | |
for (int i = 0; i < vertices.length / 2; i++) | |
vs[i] = new Vector2(vertices[i * 2 + 0], vertices[i * 2 + 1]); | |
borderize(vs, radius, maxAnglePerSegment, con, p); | |
} | |
/** | |
* | |
* Lower-case is normalized | |
* | |
* <pre> | |
* F G | |
* ^ r ^ s ^ t | |
* |\ |\ |\ | |
* o---->o---->o---->o | |
* A m B n C o D | |
* </pre> | |
* | |
* @param vertices | |
* @param radius | |
* @param segsPerPi | |
*/ | |
public static void borderize(Vector2[] vertices, float radius, | |
float maxAnglePerSegment, TriangleConsumer con, boolean cw) { | |
for (int i = 0; i < vertices.length; i++) { | |
// Before | |
final Vector2 a = in(vertices, i + (cw ? 0 : 3)); | |
final Vector2 b = in(vertices, i + (cw ? 1 : 2)); | |
final Vector2 c = in(vertices, i + (cw ? 2 : 1)); | |
final Vector2 d = in(vertices, i + (cw ? 3 : 0)); | |
final Vector2 m = b.cpy().sub(a).nor(); | |
final Vector2 n = c.cpy().sub(b).nor(); | |
final Vector2 o = d.cpy().sub(c).nor(); | |
final Vector2 r = m.cpy().rotate90(1); | |
final Vector2 s = n.cpy().rotate90(1); | |
final Vector2 t = o.cpy().rotate90(1); | |
// Calculate first extra point | |
final Vector2 f = new Vector2(); | |
switch ((int) Math.signum(r.dot(n))) { | |
case 1: | |
Intersector.intersectLines(a.x + r.x * radius, a.y + r.y | |
* radius, b.x + r.x * radius, b.y + r.y * radius, | |
b.x + s.x * radius, b.y + s.y * radius, c.x + s.x * radius, c.y | |
+ s.y * radius, f); | |
break; | |
case 0: | |
case -1: | |
f.set(s).scl(radius).add(b); | |
break; | |
default: | |
throw new IllegalStateException(); | |
} | |
// Calculate second extra point | |
final Vector2 g = new Vector2(); | |
switch ((int) Math.signum(s.dot(o))) { | |
case 1: | |
Intersector.intersectLines(b.x + s.x * radius, b.y + s.y | |
* radius, c.x + s.x * radius, c.y + s.y * radius, | |
c.x + t.x * radius, c.y + t.y * radius, d.x + t.x * radius, d.y | |
+ t.y * radius, g); | |
break; | |
case 0: | |
case -1: | |
g.set(s).scl(radius).add(c); | |
break; | |
default: | |
throw new IllegalStateException(); | |
} | |
con.triangle(b, f, g); | |
con.triangle(g, c, b); | |
// Add a circle segment, if starting with a right turn | |
if ((int) Math.signum(r.dot(n)) == -1) { | |
float span = standart(r.angle() - s.angle()); | |
int segs = (int) Math.ceil(span / maxAnglePerSegment); | |
Vector2 p = f; | |
for (int h = 0; h < segs; h++) { | |
s.rotate(span / segs); | |
Vector2 q = s.cpy().scl(radius).add(b); | |
con.triangle(b, p, q); | |
p = q; | |
} | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment