Search in sources :

Example 11 with Vertex

use of net.imagej.ops.geom.geom3d.mesh.Vertex in project imagej-ops by imagej.

the class DefaultConvexHull3D method createSimplex.

/**
 * Computes an initial simplex of four facets. The simplex consists of the
 * four points v0-v3. v0 and v1 have the largest possible distance in one
 * dimension. v2 is the point with the largest distance to v0----v1. v3 is the
 * point with the largest distance to the plane described by v0, v1, v2.
 */
private double createSimplex(final Set<Vertex> vertices, final List<TriangularFacet> facets, final List<TriangularFacet> facetsWithPointInFront) {
    final Pair<Double, Vertex[]> minMax = computeMinMax(vertices);
    final double epsilon = minMax.getA();
    int i = getMaxDistPointIndex(minMax.getB());
    Vertex v0 = minMax.getB()[i];
    Vertex v1 = minMax.getB()[i + 3];
    vertices.remove(v0);
    vertices.remove(v1);
    Vertex v2 = getV2(epsilon, vertices, v0, v1);
    vertices.remove(v2);
    Vertex v3 = getV3(epsilon, vertices, v0, v1, v2);
    vertices.remove(v3);
    TriangularFacet f0 = new TriangularFacet(v0, v1, v2);
    if (f0.distanceToPlane(v3) > epsilon) {
        // change triangle orientation to counter clockwise
        Vertex tmp = v1;
        v1 = v2;
        v2 = tmp;
        f0 = new TriangularFacet(v0, v1, v2);
    }
    // v3 is behind f0
    assert f0.distanceToPlane(v3) < epsilon;
    TriangularFacet f1 = new TriangularFacet(v1, v0, v3);
    TriangularFacet f2 = new TriangularFacet(v2, v1, v3);
    TriangularFacet f3 = new TriangularFacet(v0, v2, v3);
    f0.setNeighbor(0, f3);
    f0.setNeighbor(1, f1);
    f0.setNeighbor(2, f2);
    f1.setNeighbor(0, f2);
    f1.setNeighbor(1, f0);
    f1.setNeighbor(2, f3);
    f2.setNeighbor(0, f3);
    f2.setNeighbor(1, f0);
    f2.setNeighbor(2, f1);
    f3.setNeighbor(0, f1);
    f3.setNeighbor(1, f0);
    f3.setNeighbor(2, f2);
    assert f0.distanceToPlane(v3) < epsilon;
    assert f1.distanceToPlane(v2) < epsilon;
    assert f2.distanceToPlane(v0) < epsilon;
    assert f3.distanceToPlane(v1) < epsilon;
    List<TriangularFacet> newFacets = new ArrayList<>();
    newFacets.add(f0);
    newFacets.add(f1);
    newFacets.add(f2);
    newFacets.add(f3);
    assignPointsToFacets(epsilon, vertices, newFacets, facets, facetsWithPointInFront);
    return epsilon;
}
Also used : Vertex(net.imagej.ops.geom.geom3d.mesh.Vertex) TriangularFacet(net.imagej.ops.geom.geom3d.mesh.TriangularFacet) ArrayList(java.util.ArrayList)

Example 12 with Vertex

use of net.imagej.ops.geom.geom3d.mesh.Vertex in project imagej-ops by imagej.

the class DefaultMarchingCubes method calculate.

@SuppressWarnings({ "unchecked" })
@Override
public DefaultMesh calculate(final RandomAccessibleInterval<T> input) {
    DefaultMesh output = new DefaultMesh();
    ExtendedRandomAccessibleInterval<T, RandomAccessibleInterval<T>> extended = Views.extendValue(input, (T) new BoolType(false));
    Cursor<T> c = Views.interval(extended, new FinalInterval(new long[] { input.min(0) - 1, input.min(1) - 1, input.min(2) - 1 }, new long[] { input.max(0) + 1, input.max(1) + 1, input.max(2) + 1 })).localizingCursor();
    while (c.hasNext()) {
        c.next();
        int cursorX = c.getIntPosition(0);
        int cursorY = c.getIntPosition(1);
        int cursorZ = c.getIntPosition(2);
        Cursor<T> cu = getCube(extended, cursorX, cursorY, cursorZ);
        int i = 0;
        double[] vertex_values = new double[8];
        while (cu.hasNext()) {
            vertex_values[i++] = (cu.next().get()) ? 1 : 0;
        }
        // 6------7
        // /| /|
        // 2-----3 |
        // | 4---|-5
        // |/ |/
        // 0-----1
        vertex_values = mapFlatIterableToLookUpCube(vertex_values);
        // 4------5
        // /| /|
        // 7-----6 |
        // | 0---|-1
        // |/ |/
        // 3-----2
        int cubeindex = getCubeIndex(vertex_values);
        if (EDGE_TABLE[cubeindex] != 0) {
            int[] p0 = new int[] { 0 + cursorX, 0 + cursorY, 1 + cursorZ };
            int[] p1 = new int[] { 1 + cursorX, 0 + cursorY, 1 + cursorZ };
            int[] p2 = new int[] { 1 + cursorX, 0 + cursorY, 0 + cursorZ };
            int[] p3 = new int[] { 0 + cursorX, 0 + cursorY, 0 + cursorZ };
            int[] p4 = new int[] { 0 + cursorX, 1 + cursorY, 1 + cursorZ };
            int[] p5 = new int[] { 1 + cursorX, 1 + cursorY, 1 + cursorZ };
            int[] p6 = new int[] { 1 + cursorX, 1 + cursorY, 0 + cursorZ };
            int[] p7 = new int[] { 0 + cursorX, 1 + cursorY, 0 + cursorZ };
            double[][] vertlist = new double[12][];
            /* Find the vertices where the surface intersects the cube */
            if (0 != (EDGE_TABLE[cubeindex] & 1)) {
                vertlist[0] = interpolatePoint(p0, p1, vertex_values[0], vertex_values[1]);
            }
            if (0 != (EDGE_TABLE[cubeindex] & 2)) {
                vertlist[1] = interpolatePoint(p1, p2, vertex_values[1], vertex_values[2]);
            }
            if (0 != (EDGE_TABLE[cubeindex] & 4)) {
                vertlist[2] = interpolatePoint(p2, p3, vertex_values[2], vertex_values[3]);
            }
            if (0 != (EDGE_TABLE[cubeindex] & 8)) {
                vertlist[3] = interpolatePoint(p3, p0, vertex_values[3], vertex_values[0]);
            }
            if (0 != (EDGE_TABLE[cubeindex] & 16)) {
                vertlist[4] = interpolatePoint(p4, p5, vertex_values[4], vertex_values[5]);
            }
            if (0 != (EDGE_TABLE[cubeindex] & 32)) {
                vertlist[5] = interpolatePoint(p5, p6, vertex_values[5], vertex_values[6]);
            }
            if (0 != (EDGE_TABLE[cubeindex] & 64)) {
                vertlist[6] = interpolatePoint(p6, p7, vertex_values[6], vertex_values[7]);
            }
            if (0 != (EDGE_TABLE[cubeindex] & 128)) {
                vertlist[7] = interpolatePoint(p7, p4, vertex_values[7], vertex_values[4]);
            }
            if (0 != (EDGE_TABLE[cubeindex] & 256)) {
                vertlist[8] = interpolatePoint(p0, p4, vertex_values[0], vertex_values[4]);
            }
            if (0 != (EDGE_TABLE[cubeindex] & 512)) {
                vertlist[9] = interpolatePoint(p1, p5, vertex_values[1], vertex_values[5]);
            }
            if (0 != (EDGE_TABLE[cubeindex] & 1024)) {
                vertlist[10] = interpolatePoint(p2, p6, vertex_values[2], vertex_values[6]);
            }
            if (0 != (EDGE_TABLE[cubeindex] & 2048)) {
                vertlist[11] = interpolatePoint(p3, p7, vertex_values[3], vertex_values[7]);
            }
            /* Create the triangle */
            for (i = 0; TRIANGLE_TABLE[cubeindex][i] != -1; i += 3) {
                TriangularFacet face = new TriangularFacet(new Vertex(vertlist[TRIANGLE_TABLE[cubeindex][i + 2]][0], vertlist[TRIANGLE_TABLE[cubeindex][i + 2]][1], vertlist[TRIANGLE_TABLE[cubeindex][i + 2]][2]), new Vertex(vertlist[TRIANGLE_TABLE[cubeindex][i + 1]][0], vertlist[TRIANGLE_TABLE[cubeindex][i + 1]][1], vertlist[TRIANGLE_TABLE[cubeindex][i + 1]][2]), new Vertex(vertlist[TRIANGLE_TABLE[cubeindex][i]][0], vertlist[TRIANGLE_TABLE[cubeindex][i]][1], vertlist[TRIANGLE_TABLE[cubeindex][i]][2]));
                face.getArea();
                output.addFace(face);
            }
        }
    }
    return output;
}
Also used : BoolType(net.imglib2.type.logic.BoolType) Vertex(net.imagej.ops.geom.geom3d.mesh.Vertex) TriangularFacet(net.imagej.ops.geom.geom3d.mesh.TriangularFacet) DefaultMesh(net.imagej.ops.geom.geom3d.mesh.DefaultMesh) RandomAccessibleInterval(net.imglib2.RandomAccessibleInterval) ExtendedRandomAccessibleInterval(net.imglib2.view.ExtendedRandomAccessibleInterval) FinalInterval(net.imglib2.FinalInterval)

Example 13 with Vertex

use of net.imagej.ops.geom.geom3d.mesh.Vertex in project imagej-ops by imagej.

the class QuickHull3DTest method quickhull_4_Test.

@Test
public void quickhull_4_Test() {
    LinkedHashSet<RealLocalizable> points = new LinkedHashSet<>();
    points.add(new Vertex(0, 0, 0));
    points.add(new Vertex(1, 0, 0));
    points.add(new Vertex(0, 0, 1));
    points.add(new Vertex(0, 1, 0));
    DefaultMesh df = new DefaultMesh(points);
    DefaultMesh convexHull = (DefaultMesh) ops.run(DefaultConvexHull3D.class, df);
    assertTrue(isConvex(convexHull.getFacets(), convexHull.getEpsilon()));
    assertEquals(4, convexHull.getVertices().size());
}
Also used : RealLocalizable(net.imglib2.RealLocalizable) LinkedHashSet(java.util.LinkedHashSet) Vertex(net.imagej.ops.geom.geom3d.mesh.Vertex) DefaultMesh(net.imagej.ops.geom.geom3d.mesh.DefaultMesh) DefaultConvexHull3D(net.imagej.ops.geom.geom3d.DefaultConvexHull3D) AbstractOpTest(net.imagej.ops.AbstractOpTest) Test(org.junit.Test)

Example 14 with Vertex

use of net.imagej.ops.geom.geom3d.mesh.Vertex in project imagej-ops by imagej.

the class QuickHull3DTest method quickhull_40_Test.

@Test
public void quickhull_40_Test() {
    // 20 result points
    LinkedHashSet<RealLocalizable> points = new LinkedHashSet<>();
    points.add(new Vertex(0.3215426810286406, 0.1678336189760208, -0.2203710966001927));
    points.add(new Vertex(0.2229772524190855, -0.4213242506806965, -0.1966818060695024));
    points.add(new Vertex(0.3688830163971363, -0.1831502133823468, -0.2056387967482571));
    points.add(new Vertex(-0.1712592515826777, -0.3542439228428937, 0.2223876390814666));
    points.add(new Vertex(-0.3309556113844324, -0.370961861099081, 0.2439994981922204));
    points.add(new Vertex(-0.1004397059794885, -0.09014152417903909, -0.008600084584765189));
    points.add(new Vertex(0.458374538420117, -0.09914027349943322, -0.2505798421339875));
    points.add(new Vertex(-0.4954086979808367, -0.3339869997780649, -0.3195065691317492));
    points.add(new Vertex(0.053091190339151, 0.3036317017894533, 0.1380056861210668));
    points.add(new Vertex(0.4615616439483703, 0.4665423151725366, 0.1766835406205464));
    points.add(new Vertex(-0.4797380864431505, 0.0419809916447671, -0.4254776681079321));
    points.add(new Vertex(-0.003168473023146823, -0.2525299883005488, -0.27151530400991));
    points.add(new Vertex(-0.3577162826971303, -0.1375644040643837, -0.04494194644032229));
    points.add(new Vertex(-0.3392973838740004, 0.4288679723896719, -0.01599531622230571));
    points.add(new Vertex(0.1667164640191164, 0.003605551555385444, -0.4014989499947977));
    points.add(new Vertex(0.00714666676441833, 0.1140243407469469, 0.407090128778564));
    points.add(new Vertex(-0.03621271768232132, 0.3728502838619522, 0.4947140370446388));
    points.add(new Vertex(-0.3411871756810576, -0.3328629143842151, -0.4270033635450559));
    points.add(new Vertex(0.3544683273457627, -0.450828987127942, -0.0827870439577727));
    points.add(new Vertex(-0.4018510635028137, 0.08917494033386464, -0.2367824197158054));
    points.add(new Vertex(0.3978697768392692, -0.002667689232777493, 0.1641431727112673));
    points.add(new Vertex(-0.245701439441835, 0.495905311308713, -0.3194406286994373));
    points.add(new Vertex(0.161352035739787, -0.1563404972258401, 0.3852604361113724));
    points.add(new Vertex(0.07214279572678994, -0.4960366976410492, 0.1112227161519441));
    points.add(new Vertex(0.3201855824516951, 0.359077846965825, 0.02136723140381946));
    points.add(new Vertex(0.1190541238701475, -0.05734495917087884, 0.2032677509852384));
    points.add(new Vertex(0.3210853052521919, 0.4807189479290684, 0.4433501688235907));
    points.add(new Vertex(0.3862800354941562, 0.2085496142586224, 0.09336129957191763));
    points.add(new Vertex(0.1233572616459404, 0.265491605052251, 0.117400122450106));
    points.add(new Vertex(0.1438531872293476, -0.2594872752758556, -0.2026374435076839));
    points.add(new Vertex(0.2724846394476338, -0.3506708492996831, 0.2750346518820475));
    points.add(new Vertex(-0.4926118841325975, -0.3279366743079728, 0.3683135596740186));
    points.add(new Vertex(0.2459906458351674, 0.3647787136629026, -0.1641662355178652));
    points.add(new Vertex(-0.141922976953837, -0.2994764654892278, -0.3009570467294725));
    points.add(new Vertex(-0.1850859398814719, 0.2606059478228967, 0.004159106876849283));
    points.add(new Vertex(-0.09789466634196664, -0.3156603563722785, -0.303610991503681));
    points.add(new Vertex(0.2100642609503719, -0.4499717643018549, 0.3245569875692548));
    points.add(new Vertex(-0.1707163766685095, -0.2301452446078371, -0.05112823569320907));
    points.add(new Vertex(-0.312260808713977, -0.1674135249735914, 0.2808831662692904));
    points.add(new Vertex(-0.1966306233747216, 0.2291105671125563, -0.3387042454804333));
    DefaultMesh df = new DefaultMesh(points);
    DefaultMesh convexHull = (DefaultMesh) ops.run(DefaultConvexHull3D.class, df);
    assertTrue(isConvex(convexHull.getFacets(), convexHull.getEpsilon()));
    assertEquals(20, convexHull.getVertices().size());
}
Also used : RealLocalizable(net.imglib2.RealLocalizable) LinkedHashSet(java.util.LinkedHashSet) Vertex(net.imagej.ops.geom.geom3d.mesh.Vertex) DefaultMesh(net.imagej.ops.geom.geom3d.mesh.DefaultMesh) DefaultConvexHull3D(net.imagej.ops.geom.geom3d.DefaultConvexHull3D) AbstractOpTest(net.imagej.ops.AbstractOpTest) Test(org.junit.Test)

Example 15 with Vertex

use of net.imagej.ops.geom.geom3d.mesh.Vertex in project imagej-ops by imagej.

the class QuickHull3DTest method quickhull_6_Test.

@Test
public void quickhull_6_Test() {
    LinkedHashSet<RealLocalizable> points = new LinkedHashSet<>();
    points.add(new Vertex(3.2, 4.8, 4.4));
    points.add(new Vertex(0, -4.9, 1.1));
    points.add(new Vertex(-2.4, 4.9, -3.1));
    points.add(new Vertex(4.5, -0.9, -2.5));
    points.add(new Vertex(-4.7, 0.4, -4.2));
    points.add(new Vertex(-1.9, 2.2, -3.3));
    DefaultMesh df = new DefaultMesh(points);
    DefaultMesh convexHull = (DefaultMesh) ops.run(DefaultConvexHull3D.class, df);
    assertTrue(isConvex(convexHull.getFacets(), convexHull.getEpsilon()));
    assertEquals(5, convexHull.getVertices().size());
}
Also used : RealLocalizable(net.imglib2.RealLocalizable) LinkedHashSet(java.util.LinkedHashSet) Vertex(net.imagej.ops.geom.geom3d.mesh.Vertex) DefaultMesh(net.imagej.ops.geom.geom3d.mesh.DefaultMesh) DefaultConvexHull3D(net.imagej.ops.geom.geom3d.DefaultConvexHull3D) AbstractOpTest(net.imagej.ops.AbstractOpTest) Test(org.junit.Test)

Aggregations

Vertex (net.imagej.ops.geom.geom3d.mesh.Vertex)17 DefaultMesh (net.imagej.ops.geom.geom3d.mesh.DefaultMesh)8 TriangularFacet (net.imagej.ops.geom.geom3d.mesh.TriangularFacet)8 LinkedHashSet (java.util.LinkedHashSet)6 RealLocalizable (net.imglib2.RealLocalizable)6 Test (org.junit.Test)5 ArrayList (java.util.ArrayList)4 AbstractOpTest (net.imagej.ops.AbstractOpTest)4 DefaultConvexHull3D (net.imagej.ops.geom.geom3d.DefaultConvexHull3D)4 Vector3D (org.apache.commons.math3.geometry.euclidean.threed.Vector3D)2 IOException (java.io.IOException)1 URISyntaxException (java.net.URISyntaxException)1 Random (java.util.Random)1 AbstractFeatureTest (net.imagej.ops.features.AbstractFeatureTest)1 DefaultMarchingCubes (net.imagej.ops.geom.geom3d.DefaultMarchingCubes)1 Facet (net.imagej.ops.geom.geom3d.mesh.Facet)1 Horizon (net.imagej.ops.geom.geom3d.mesh.Horizon)1 FinalInterval (net.imglib2.FinalInterval)1 RandomAccessibleInterval (net.imglib2.RandomAccessibleInterval)1 RealPoint (net.imglib2.RealPoint)1