diff --git a/common/src/main/java/com/hellblazer/luciferase/geometry/Geometry.java b/common/src/main/java/com/hellblazer/luciferase/geometry/Geometry.java index 1e3476d..4389cf4 100644 --- a/common/src/main/java/com/hellblazer/luciferase/geometry/Geometry.java +++ b/common/src/main/java/com/hellblazer/luciferase/geometry/Geometry.java @@ -823,6 +823,52 @@ public static double inSphere(float[] pa, float[] pb, float[] pc, float[] pd, fl return inSphere(pa[0], pa[1], pa[2], pb[0], pb[1], pb[2], pc[0], pc[1], pc[2], pd[0], pd[1], pd[2], pe[0], pe[1], pe[2]); } + /** + * Determines if a point e is inside the sphere defined by the points a, b, c, + * and d. The latter are assumed to be in CCW order, such that the method + * {@link #leftOfPlane} would return a positive number. + *
+ * Note: this fast method may return an incorrect result. + * + * @return positive, if inside the sphere; negative, if outside the sphere; + * zero, otherwise. + */ + public static float inSphereFast(float xa, float ya, float za, float xb, float yb, float zb, float xc, + float yc, float zc, float xd, float yd, float zd, float xe, float ye, + float ze) { + float aex = xa - xe; + float bex = xb - xe; + float cex = xc - xe; + float dex = xd - xe; + float aey = ya - ye; + float bey = yb - ye; + float cey = yc - ye; + float dey = yd - ye; + float aez = za - ze; + float bez = zb - ze; + float cez = zc - ze; + float dez = zd - ze; + + float ab = aex * bey - bex * aey; + float bc = bex * cey - cex * bey; + float cd = cex * dey - dex * cey; + float da = dex * aey - aex * dey; + + float ac = aex * cey - cex * aey; + float bd = bex * dey - dex * bey; + + float abc = aez * bc - bez * ac + cez * ab; + float bcd = bez * cd - cez * bd + dez * bc; + float cda = cez * da + dez * ac + aez * cd; + float dab = dez * ab + aez * bd + bez * da; + + float alift = aex * aex + aey * aey + aez * aez; + float blift = bex * bex + bey * bey + bez * bez; + float clift = cex * cex + cey * cey + cez * cez; + float dlift = dex * dex + dey * dey + dez * dez; + + return dlift * abc - clift * dab + (blift * cda - alift * bcd); + } /** * Determines if a point e is inside the sphere defined by the points a, b, c, @@ -1136,6 +1182,47 @@ public static double leftOfPlaneFast(double xa, double ya, double za, double xb, return adx * (bdy * cdz - bdz * cdy) + bdx * (cdy * adz - cdz * ady) + cdx * (ady * bdz - adz * bdy); } + + public static float leftOfPlaneFastFloat(float xa, float ya, float za, float xb, float yb, float zb, float xc, + float yc, float zc, float xd, float yd, float zd) { + float adx = xa - xd; + float bdx = xb - xd; + float cdx = xc - xd; + float ady = ya - yd; + float bdy = yb - yd; + float cdy = yc - yd; + float adz = za - zd; + float bdz = zb - zd; + float cdz = zc - zd; + + return adx * (bdy * cdz - bdz * cdy) + bdx * (cdy * adz - cdz * ady) + cdx * (ady * bdz - adz * bdy); + } + + /** + * Determines if a point d is left of the plane defined by the points a, b, and + * c. The latter are assumed to be in CCW order, as viewed from the right side + * of the plane. + *
+ * Note: this fast method may return an incorrect result. + * + * @return positive, if left of plane; negative, if right of plane; zero, + * otherwise. + */ +// public static float leftOfPlaneFast(float xa, float ya, float za, float xb, float yb, float zb, float xc, +// float yc, float zc, float xd, float yd, float zd) { +// float adx = xa - xd; +// float bdx = xb - xd; +// float cdx = xc - xd; +// float ady = ya - yd; +// float bdy = yb - yd; +// float cdy = yc - yd; +// float adz = za - zd; +// float bdz = zb - zd; +// float cdz = zc - zd; +// +// return adx * (bdy * cdz - bdz * cdy) + bdx * (cdy * adz - cdz * ady) + cdx * (ady * bdz - adz * bdy); +// } + /** * Determines if a point d is left of the plane defined by the points a, b, and * c. The latter are assumed to be in CCW order, as viewed from the right side diff --git a/lucien/src/main/java/com/hellblazer/luciferase/lucien/grid/OrientedFace.java b/lucien/src/main/java/com/hellblazer/luciferase/lucien/grid/OrientedFace.java index 05544b4..eda9c73 100644 --- a/lucien/src/main/java/com/hellblazer/luciferase/lucien/grid/OrientedFace.java +++ b/lucien/src/main/java/com/hellblazer/luciferase/lucien/grid/OrientedFace.java @@ -339,7 +339,7 @@ public V getAdjacentVertexOrdinal() { abstract public Vertex getVertex(int anIndex); public boolean hasAdjacent() { - return getAdjacentVertexOrdinal() != null; + return getAdjacent() != null; } abstract public boolean includes(Vertex v); @@ -422,13 +422,13 @@ private boolean inSphere(Vertex query, Vertex b, Vertex c, Vertex d) { b = a; a = tmp; } - return query.inSphere(a, b, c, d) > 0.0; + return query.inSphere(a, b, c, d) > 0.0d; } private boolean isFlippable3ear(Vertex n) { var opposingFace = getIncident().getFace(n); opposingFace.getAdjacent().getFace(opposingFace.getAdjacentVertex()); - return opposingFace.orientationOf(n) > 0.0; + return opposingFace.orientationOf(n) > 0.0d; } diff --git a/lucien/src/main/java/com/hellblazer/luciferase/lucien/grid/Tetrahedron.java b/lucien/src/main/java/com/hellblazer/luciferase/lucien/grid/Tetrahedron.java index 7f28529..3c1befb 100644 --- a/lucien/src/main/java/com/hellblazer/luciferase/lucien/grid/Tetrahedron.java +++ b/lucien/src/main/java/com/hellblazer/luciferase/lucien/grid/Tetrahedron.java @@ -325,7 +325,7 @@ public boolean includes(Vertex query) { * @return */ public boolean inSphere(Vertex query) { - return query.inSphere(a, b, c, d) > 0.0; + return query.inSphere(a, b, c, d) > 0.0d; } /** @@ -1144,7 +1144,13 @@ public boolean isConvex(int vertex) { @Override public boolean isReflex(int vertex) { - var adjacentVertex = getAdjacentVertex(); + Tetrahedron adjacent = getAdjacent(); + var current = adjacent == null ? null : adjacent.ordinalOf(getIncident()); + if (current == null) { + return false; + } + + var adjacentVertex = adjacent.getVertex(current); if (adjacentVertex == null) { return false; } @@ -1265,7 +1271,12 @@ public boolean isConvex(int vertex) { @Override public boolean isReflex(int vertex) { - var adjacentVertex = getAdjacentVertex(); + Tetrahedron adjacent = getAdjacent(); + var current = adjacent == null ? null : adjacent.ordinalOf(getIncident()); + if (current == null) { + return false; + } + var adjacentVertex = adjacent.getVertex(current); if (adjacentVertex == null) { return false; }