import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.HashSet; import java.util.List; public final class FacesFromMesh { public static void main(String[] aArgs) { final List perimeterFormatQ = Arrays.asList( 8, 1, 3 ); final List perimeterFormatR = Arrays.asList( 1, 3, 8 ); final List perimeterFormatU = Arrays.asList( 18, 8, 14, 10, 12, 17, 19 ); final List perimeterFormatV = Arrays.asList( 8, 14, 10, 12, 17, 19, 18 ); final List edgeFormatE = Arrays.asList( new Edge(1, 11), new Edge(7, 11), new Edge(1, 7) ); final List edgeFormatF = Arrays.asList( new Edge(11, 23), new Edge(1, 17), new Edge(17, 23), new Edge(1, 11) ); final List edgeFormatG = Arrays.asList( new Edge(8, 14), new Edge(17, 19), new Edge(10, 12), new Edge(10, 14), new Edge(12, 17), new Edge(8, 18), new Edge(18, 19) ); final List edgeFormatH = Arrays.asList( new Edge(1, 3), new Edge(9, 11), new Edge(3, 11), new Edge(1, 11) ); System.out.println("PerimeterFormat equality checks:"); boolean sameFace = isSameFace(perimeterFormatQ, perimeterFormatR); System.out.println(perimeterFormatQ + " == " + perimeterFormatR + ": " + sameFace); sameFace = isSameFace(perimeterFormatU, perimeterFormatV); System.out.println(perimeterFormatU + " == " + perimeterFormatV + ": " + sameFace); System.out.println(System.lineSeparator() + "EdgeFormat to PerimeterFormat conversions:"); List> edgeFormatFaces = List.of( edgeFormatE, edgeFormatF, edgeFormatG, edgeFormatH ); for ( List edgeFormatFace : edgeFormatFaces ) { List perimeterFormatFace = toPerimeterFormatFace(edgeFormatFace); if ( perimeterFormatFace.isEmpty() ) { System.out.println(edgeFormatFace + " has invalid edge format"); } else { System.out.println(edgeFormatFace + " => " + perimeterFormatFace); } } } private static boolean isSameFace(List aOne, List aTwo) { if ( aOne.size() != aTwo.size() || aOne.isEmpty() || ! new HashSet(aOne).equals( new HashSet(aTwo) )) { return false; } List copyTwo = new ArrayList(aTwo); for ( int i = 0; i < 2; i++ ) { int start = copyTwo.indexOf(aOne.get(0)); List test = new ArrayList(copyTwo.subList(start, copyTwo.size())); test.addAll(copyTwo.subList(0, start)); if ( aOne.equals(test) ) { return true; } Collections.reverse(copyTwo); } return false; } private static List toPerimeterFormatFace(List aEdgeFormatFace) { if ( aEdgeFormatFace.isEmpty() ) { return Collections.emptyList(); } List edges = new ArrayList(aEdgeFormatFace); List result = new ArrayList(); Edge firstEdge = edges.remove(0); int nextVertex = firstEdge.first; result.add(nextVertex); while ( ! edges.isEmpty() ) { int index = -1; for ( Edge edge : edges ) { if ( edge.first == nextVertex || edge.second == nextVertex ) { index = edges.indexOf(edge); nextVertex = ( nextVertex == edge.first ) ? edge.second : edge.first; break; } } if ( index == -1 ) { return Collections.emptyList(); } result.add(nextVertex); edges.remove(index); } if ( nextVertex != firstEdge.second ) { return Collections.emptyList(); } return result; } private static class Edge { public Edge(int aFirst, int aSecond) { first = aFirst; second = aSecond; } @Override public String toString() { return "(" + first + ", " + second + ")"; } private int first, second; } }