Search in sources :

Example 56 with Point3f

use of org.scijava.vecmath.Point3f in project TrakEM2 by trakem2.

the class Profile method measure.

/**
 * Assumes Z-coord sorted list of profiles, as stored in a "profile_list" ProjectThing type. .
 */
public static ResultsTable measure(final Profile[] profiles, ResultsTable rt, final long profile_list_id) {
    Utils.log2("profiles.length" + profiles.length);
    if (null == profiles || 0 == profiles.length)
        return null;
    if (1 == profiles.length) {
        // don't measure if there is only one
        return rt;
    }
    for (final Profile p : profiles) {
        if (null == p || 0 == p.n_points) {
            Utils.log("Cannot measure: empty profile " + p + (null != p ? " at layer " + p.getLayer() : ""));
            return rt;
        }
    }
    if (null == rt)
        rt = Utils.createResultsTable("Profile list results", new String[] { "id", "interpolated surface", "surface: sum of length x thickness", "volume", "name-id" });
    final Calibration cal = profiles[0].getLayerSet().getCalibration();
    // else, interpolate skin and measure each triangle
    // already calibrated
    final List<Point3f> tri = makeTriangles(profiles, 1.0);
    final int n_tri = tri.size();
    if (0 != n_tri % 3) {
        Utils.log("Profile.measure error: triangle verts list not a multiple of 3 for profile list id " + profile_list_id);
        return rt;
    }
    // Surface: calibrated sum of the area of all triangles in the mesh.
    double surface = 0;
    for (int i = 2; i < n_tri; i += 3) {
        surface += M.measureArea(tri.get(i - 2), tri.get(i - 1), tri.get(i));
    }
    // add capping ends
    final double area_first = profiles[0].computeArea();
    final double area_last = profiles[profiles.length - 1].computeArea();
    if (profiles[0].closed)
        surface += area_first;
    if (profiles[profiles.length - 1].closed)
        surface += area_last;
    // Surface flat: sum of the perimeter lengths times the layer thickness
    double surface_flat = 0;
    for (int i = 0; i < profiles.length; i++) {
        if (0 == profiles[i].p_i[0].length)
            profiles[i].generateInterpolatedPoints(0.05);
        surface_flat += profiles[i].computeLength() * profiles[i].layer.getThickness() * cal.pixelWidth;
    }
    // Volume: area times layer thickness
    double volume = area_first * profiles[0].layer.getThickness();
    for (int i = 1; i < profiles.length - 1; i++) {
        volume += profiles[i].computeArea() * profiles[i].layer.getThickness();
    }
    volume += area_last * profiles[profiles.length - 1].layer.getThickness();
    // calibrate volume: the Z is still in pixels
    volume *= cal.pixelWidth;
    rt.incrementCounter();
    rt.addLabel("units", cal.getUnit());
    rt.addValue(0, profile_list_id);
    rt.addValue(1, surface);
    rt.addValue(2, surface_flat);
    rt.addValue(3, volume);
    double nameid = 0;
    try {
        nameid = Double.parseDouble(profiles[0].project.findProjectThing(profiles[0]).getParent().getTitle());
    } catch (final NumberFormatException nfe) {
    }
    rt.addValue(4, nameid);
    return rt;
}
Also used : Point3f(org.scijava.vecmath.Point3f) Calibration(ij.measure.Calibration)

Example 57 with Point3f

use of org.scijava.vecmath.Point3f in project TrakEM2 by trakem2.

the class Tree method generateSkeleton.

/**
 * @return a CustomLineMesh.PAIRWISE list for a LineMesh.
 */
public MeshData generateSkeleton(final double scale_, final int parallels, final int resample) {
    if (null == root)
        return null;
    final ArrayList<Point3f> list = new ArrayList<Point3f>();
    final ArrayList<Color3f> colors = new ArrayList<Color3f>();
    // Simulate recursion
    final LinkedList<Node<T>> todo = new LinkedList<Node<T>>();
    todo.add(root);
    final float scale = (float) scale_;
    final Calibration cal = layer_set.getCalibration();
    final float pixelWidthScaled = (float) cal.pixelWidth * scale;
    final float pixelHeightScaled = (float) cal.pixelHeight * scale;
    final int sign = cal.pixelDepth < 0 ? -1 : 1;
    final float[] fps = new float[2];
    final Map<Node<T>, Point3f> points = new HashMap<Node<T>, Point3f>();
    // A few performance tests are needed:
    // 1 - if the map caching of points helps or recomputing every time is cheaper than lookup
    // 2 - if removing no-longer-needed points from the map helps lookup or overall slows down
    // 
    // The method, by the way, is very parallelizable: each is independent.
    final HashMap<Color, Color3f> cached_colors = new HashMap<Color, Color3f>();
    final Color3f cf = new Color3f(this.color);
    cached_colors.put(this.color, cf);
    boolean go = true;
    while (go) {
        final Node<T> node = todo.removeFirst();
        // Add children to todo list if any
        if (null != node.children) {
            for (final Node<T> nd : node.children) todo.add(nd);
        }
        go = !todo.isEmpty();
        // Get node's 3D coordinate
        Point3f p = points.get(node);
        if (null == p) {
            fps[0] = node.x;
            fps[1] = node.y;
            this.at.transform(fps, 0, fps, 0, 1);
            p = new Point3f(fps[0] * pixelWidthScaled, fps[1] * pixelHeightScaled, (float) node.la.getZ() * pixelWidthScaled * sign);
            points.put(node, p);
        }
        if (null != node.parent) {
            // Create a line to the parent
            list.add(points.get(node.parent));
            list.add(p);
            if (null == node.color) {
                colors.add(cf);
                // twice: a line segment
                colors.add(cf);
            } else {
                Color3f c = cached_colors.get(node.color);
                if (null == c) {
                    c = new Color3f(node.color);
                    cached_colors.put(node.color, c);
                }
                colors.add(c);
                // twice: a line segment
                colors.add(c);
            }
            if (go && node.parent != todo.getFirst().parent) {
                // node.parent point no longer needed (last child just processed)
                points.remove(node.parent);
            }
        }
    }
    // Utils.log2("Skeleton MeshData lists of same length: " + (list.size() == colors.size()));
    return new MeshData(list, colors);
}
Also used : HashMap(java.util.HashMap) Color3f(org.scijava.vecmath.Color3f) Color(java.awt.Color) ArrayList(java.util.ArrayList) Calibration(ij.measure.Calibration) LinkedList(java.util.LinkedList) Point(java.awt.Point) Point3f(org.scijava.vecmath.Point3f)

Example 58 with Point3f

use of org.scijava.vecmath.Point3f in project TrakEM2 by trakem2.

the class Treeline method addTriangles.

private static final void addTriangles(final List<Point3f> ps, final List<Point3f> parent_verts, final List<Point3f> child_verts, final int i0, final int i1) {
    // one triangle
    ps.add(new Point3f(parent_verts.get(i0)));
    ps.add(new Point3f(parent_verts.get(i1)));
    ps.add(new Point3f(child_verts.get(i0)));
    // another
    ps.add(new Point3f(parent_verts.get(i1)));
    ps.add(new Point3f(child_verts.get(i1)));
    ps.add(new Point3f(child_verts.get(i0)));
}
Also used : Point3f(org.scijava.vecmath.Point3f)

Aggregations

Point3f (org.scijava.vecmath.Point3f)58 ArrayList (java.util.ArrayList)20 Calibration (ij.measure.Calibration)6 HashMap (java.util.HashMap)5 Color3f (org.scijava.vecmath.Color3f)5 Point (java.awt.Point)4 Color (java.awt.Color)3 Area (java.awt.geom.Area)3 Map (java.util.Map)3 TreeMap (java.util.TreeMap)3 Point3d (com.github.quickhull3d.Point3d)2 QuickHull3D (com.github.quickhull3d.QuickHull3D)2 PolygonRoi (ij.gui.PolygonRoi)2 Rectangle (java.awt.Rectangle)2 AffineTransform (java.awt.geom.AffineTransform)2 HashSet (java.util.HashSet)2 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)2 Vector3f (org.scijava.vecmath.Vector3f)2 CustomLineMesh (customnode.CustomLineMesh)1 CustomMesh (customnode.CustomMesh)1