Search in sources :

Example 1 with Point3d

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

the class VectorString3D method mirror.

/**
 * Where axis is any of VectorString.X_AXIS, .Y_AXIS or .Z_AXIS,
 *	    and the mirroring is done relative to the local 0,0 of this VectorString.
 */
public void mirror(final int axis) {
    final Transform3D t = new Transform3D();
    switch(axis) {
        case VectorString.X_AXIS:
            t.setScale(new Vector3d(-1, 1, 1));
            tags ^= MIRROR_X;
            break;
        case VectorString.Y_AXIS:
            t.setScale(new Vector3d(1, -1, 1));
            tags ^= MIRROR_Y;
            break;
        case VectorString.Z_AXIS:
            t.setScale(new Vector3d(1, 1, -1));
            tags ^= MIRROR_Z;
            break;
        default:
            return;
    }
    final Point3d p = new Point3d();
    transform(x, y, z, t, p);
    if (null != this.vx)
        transform(vx, vy, vz, t, p);
    if (null != this.rvx)
        transform(rvx, rvy, rvz, t, p);
}
Also used : Vector3d(org.scijava.vecmath.Vector3d) Point3d(org.scijava.vecmath.Point3d) Transform3D(org.scijava.java3d.Transform3D)

Example 2 with Point3d

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

the class VectorString3D method resample.

/**
 * If argument with_source is true, then returns an ArrayList of ArrayList of Point3d, with lists of all points that contributed to each point.
 */
private void resample(final boolean with_source) {
    // parameters
    final double MAX_DISTANCE = 2.5 * delta;
    final int MA = (int) (MAX_DISTANCE / getAverageDelta());
    final int MAX_AHEAD = MA < 6 ? 6 : MA;
    // convenient data carrier and editor
    final ResamplingData r = new ResamplingData(this.length, this.dep);
    final Vector vector = new Vector();
    // The source points that generate each point:
    if (with_source && null == this.source) {
        // add all original points to a new list of lists (so that many VectorString3D may be combined, while keeping all source points for each final point)
        this.source = new ArrayList<ArrayList<Point3d>>();
        for (int g = 0; g < length; g++) {
            final ArrayList<Point3d> ap = new ArrayList<Point3d>();
            ap.add(new Point3d(x[g], y[g], z[g]));
            this.source.add(ap);
        }
    }
    final ArrayList<ArrayList<Point3d>> new_source = with_source ? new ArrayList<ArrayList<Point3d>>() : null;
    // first resampled point is the same as point zero
    r.setP(0, x[0], y[0], z[0]);
    r.setDeps(0, dep, new int[] { 0 }, new double[] { 1.0 }, 1);
    if (with_source)
        new_source.add(new ArrayList<Point3d>(this.source.get(0)));
    // index over x,y,z
    int i = 1;
    // index over rx,ry,rz (resampled points)
    int j = 1;
    // some vars
    int t, s, ii, u, iu, k;
    int prev_i = i;
    double dist_ahead, dist1, dist2, sum;
    final double[] w = new double[MAX_AHEAD];
    final double[] distances = new double[MAX_AHEAD];
    final Vector[] ve = new Vector[MAX_AHEAD];
    int next_ahead;
    for (next_ahead = 0; next_ahead < MAX_AHEAD; next_ahead++) ve[next_ahead] = new Vector();
    final int[] ahead = new int[MAX_AHEAD];
    try {
        // start infinite loop
        for (; prev_i <= i; ) {
            if (prev_i > i || (!isClosed() && i == this.length - 1))
                break;
            // get distances of MAX_POINTs ahead from the previous point
            next_ahead = 0;
            for (t = 0; t < MAX_AHEAD; t++) {
                s = i + t;
                // fix 's' if it goes over the end
                if (s >= this.length) {
                    if (isClosed())
                        s -= this.length;
                    else
                        break;
                }
                dist_ahead = r.distance(j - 1, x[s], y[s], z[s]);
                if (dist_ahead < MAX_DISTANCE) {
                    ahead[next_ahead] = s;
                    distances[next_ahead] = dist_ahead;
                    next_ahead++;
                }
            }
            if (0 == next_ahead) {
                // No points (ahead of the i point) are found within MAX_DISTANCE
                // Just use the next point as target towards which create a vector of length delta
                vector.set(x[i] - r.x(j - 1), y[i] - r.y(j - 1), z[i] - r.z(j - 1));
                dist1 = vector.length();
                vector.setLength(delta);
                vector.put(j, r);
                if (with_source) {
                    // shallow clone: shared Point3d instances (but no shared lists)
                    // the next point is 'i'
                    new_source.add(new ArrayList<Point3d>(this.source.get(i)));
                }
                if (null != dep)
                    r.setDeps(j, dep, new int[] { i }, new double[] { 1.0 }, 1);
                // correct for point overtaking the not-close-enough point ahead in terms of 'delta_p' as it is represented in MAX_DISTANCE, but overtaken by the 'delta' used for subsampling:
                if (dist1 <= delta) {
                    // look for a point ahead that is over distance delta from the previous j, so that it will lay ahead of the current j
                    for (u = i; u < this.length; u++) {
                        dist2 = Math.sqrt(Math.pow(x[u] - r.x(j - 1), 2) + Math.pow(y[u] - r.y(j - 1), 2) + Math.pow(z[u] - r.z(j - 1), 2));
                        if (dist2 > delta) {
                            prev_i = i;
                            i = u;
                            break;
                        }
                    }
                }
            } else {
                // Compose a point ahead out of the found ones.
                // 
                // First, adjust weights for the points ahead
                w[0] = distances[0] / MAX_DISTANCE;
                double largest = w[0];
                for (u = 1; u < next_ahead; u++) {
                    w[u] = 1 - (distances[u] / MAX_DISTANCE);
                    if (w[u] > largest) {
                        largest = w[u];
                    }
                }
                // normalize weights: divide by largest
                sum = 0;
                for (u = 0; u < next_ahead; u++) {
                    w[u] = w[u] / largest;
                    sum += w[u];
                }
                // correct error. The closest point gets the extra
                if (sum < 1.0) {
                    w[0] += 1.0 - sum;
                } else {
                    recalculate(w, next_ahead, sum);
                }
                // Now, make a vector for each point with the corresponding weight
                vector.set(0, 0, 0);
                final ArrayList<Point3d> ap = with_source ? new ArrayList<Point3d>() : null;
                for (u = 0; u < next_ahead; u++) {
                    iu = i + u;
                    if (iu >= this.length)
                        iu -= this.length;
                    ve[u].set(x[iu] - r.x(j - 1), y[iu] - r.y(j - 1), z[iu] - r.z(j - 1));
                    ve[u].setLength(w[u] * delta);
                    // compute the length only on the last iteration
                    vector.add(ve[u], u == next_ahead - 1);
                    if (with_source) {
                        ap.addAll(this.source.get(iu));
                    }
                }
                if (with_source)
                    new_source.add(ap);
                // correct potential errors
                if (Math.abs(vector.length() - delta) > 0.00000001) {
                    vector.setLength(delta);
                }
                // set
                vector.put(j, r);
                if (null != dep)
                    r.setDeps(j, dep, ahead, w, next_ahead);
                // System.out.println("j: " + j + "  (" + next_ahead + ")   " + vector.computeLength() + "  " + vector.length());
                // find the first point that is right ahead of the newly added point
                // so: loop through points that lay within MAX_DISTANCE, and find the first one that is right past delta.
                ii = i;
                for (k = 0; k < next_ahead; k++) {
                    if (distances[k] > delta) {
                        ii = ahead[k];
                        break;
                    }
                }
                // correct for the case of unseen point (because all MAX_POINTS ahead lay under delta):
                prev_i = i;
                if (i == ii) {
                    // the one after the last.
                    i = ahead[next_ahead - 1] + 1;
                    if (i >= this.length) {
                        if (// this.length is the length of the x,y,z, the original points
                        isClosed())
                            // this.length is the length of the x,y,z, the original points
                            i = i - this.length;
                        else
                            i = this.length - 1;
                    }
                } else {
                    i = ii;
                }
            }
            // advance index in the new points
            j += 1;
        }
    // end of for loop
    } catch (final Exception e) {
        e.printStackTrace();
        System.out.println("Some data: x,y,z .length = " + x.length + "," + y.length + "," + z.length + "\nj=" + j + ", i=" + i + ", prev_i=" + prev_i);
    }
    dist_ahead = r.distance(j - 1, x[this.length - 1], y[this.length - 1], z[this.length - 1]);
    // System.out.println("delta: " + delta + "\nlast point: " + x[x.length-1] + ", " + y[y.length-1] + ", " + z[z.length-1]);
    // System.out.println("last resampled point: x,y,z " + r.x(j-1) + ", " + r.y(j-1) + ", " + r.z(j-1));
    // System.out.println("distance: " + dist_ahead);
    // see whether the subsampling terminated too early, and fill with a line of points.
    final int last_i = isClosed() ? 0 : this.length - 1;
    if (dist_ahead > delta * 1.2) {
        // TODO//System.out.println("resampling terminated too early. Why?");
        while (dist_ahead > delta * 1.2) {
            // make a vector from the last resampled point to the last point
            vector.set(x[last_i] - r.x(j - 1), y[last_i] - r.y(j - 1), z[last_i] - r.z(j - 1));
            // resize it to length delta
            vector.setLength(delta);
            vector.put(j, r);
            if (with_source)
                new_source.add(new ArrayList<Point3d>(this.source.get(last_i)));
            j++;
            dist_ahead = r.distance(j - 1, x[last_i], y[last_i], z[last_i]);
        }
    }
    // done!
    // j acts as length of resampled points and vectors
    r.put(this, j);
    if (with_source)
        this.source = new_source;
// System.out.println("resampling with_source: " + with_source + "    n_sources = " + n_sources);
// debug:
// if (with_source && j != new_source.size()) System.out.println("WARNING: len: " + j + ", sources length: " + new_source.size());
// if (with_source && n_sources > 1) System.out.println("n_sources=" + n_sources + " lengths: " + j + ", " + new_source.size());
}
Also used : Point3d(org.scijava.vecmath.Point3d) ArrayList(java.util.ArrayList)

Example 3 with Point3d

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

the class VectorString3D method getStdDevAtEachPoint.

/**
 * If null != source, compute the StdDev at each point in this VectorString3D, by comparing it with its associated source points. Returns null if there is no source.
 * What is meant for stdDev is the stdDev of the points from which any given point in this VectorString3D was generated, returned as a distance to use as radius around that point.
 */
public double[] getStdDevAtEachPoint() {
    if (null == source)
        return null;
    final double[] stdDev = new double[length];
    int i = 0;
    System.out.println("len x: " + length + "  len source: " + source.size());
    for (final ArrayList<Point3d> ap : source) {
        // 1 - Expected: the current position
        final Point3d expected = new Point3d(x[i], y[i], z[i]);
        // 2 - Sum of squares of differences of the distances to the expected position
        double sd = 0;
        for (final Point3d p : ap) sd += Math.pow(p.distance(expected), 2);
        // 3 - stdDev
        stdDev[i] = Math.sqrt(sd / ap.size());
        // Test separately for each dimension : it's the same
        /*
			double sdx = 0,
			       sdy = 0,
			       sdz = 0;
			for (Point3d p : ap) {
				sdx += Math.pow(p.x - expected.x, 2);
				sdy += Math.pow(p.y - expected.y, 2);
				sdz += Math.pow(p.z - expected.z, 2);
			}
			sdx = Math.sqrt(sdx / ap.size());
			sdy = Math.sqrt(sdy / ap.size());
			sdz = Math.sqrt(sdz / ap.size());

			sd = stdDev[i]; // from above

			// stdDev as radial distance:
			stdDev[i] = Math.sqrt(sdx*sdx + sdy*sdy + sdz*sdz);

			System.out.println("check: sd =       " + sd +
				   "       sd indep = " + stdDev[i]);
			*/
        i++;
    }
    return stdDev;
}
Also used : Point3d(org.scijava.vecmath.Point3d)

Example 4 with Point3d

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

the class Compare method makeEnvelope.

/**
 * From a condensed VectorString3D, create the radius at each point.
 *  The maximum provides the maximum radius from the condensed VectorString3D
 *  at @param c point-wise to the source points that generated it.
 *  Realize that the thickness of source VectorString3Ds is not considered,
 *  only their points.
 */
public static double[] makeEnvelope(final CATAParameters cp, final VectorString3D c) {
    if (cp.envelope_type <= 0) {
        // one std dev
        return c.getStdDevAtEachPoint();
    }
    final double[] width = new double[c.length()];
    if (cp.envelope_type < 3) {
        // 1 == 2std, 2 == 3std
        // two or three std dev
        final double[] std = c.getStdDevAtEachPoint();
        // so: 2 or 3
        final int f = cp.envelope_type + 1;
        for (int i = 0; i < std.length; i++) {
            width[i] = f * std[i];
        }
    } else if (3 == cp.envelope_type) {
        // average distance from condensed to all sources
        int i = 0;
        for (final ArrayList<Point3d> ap : c.getSource()) {
            double sum = 0;
            for (final Point3d p : ap) sum += c.distance(i, p);
            width[i] = sum / ap.size();
            i++;
        }
    } else if (4 == cp.envelope_type) {
        // max distance from condensed to all sources
        int i = 0;
        for (final ArrayList<Point3d> ap : c.getSource()) {
            double max = 0;
            for (final Point3d p : ap) max = Math.max(max, c.distance(i, p));
            width[i] = max;
            i++;
        }
    }
    return width;
}
Also used : Point3d(org.scijava.vecmath.Point3d) ArrayList(java.util.ArrayList)

Example 5 with Point3d

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

the class Compare method extractPoints.

/**
 * Extracts the list of fiduciary points from the fiducial parent and, if their name is different than "ball", adds their title as key and their first ball as a fiduciary point value of the returned map. The map is never null but could be empty.
 * The values are calibrated.
 */
public static Map<String, Tuple3d> extractPoints(final ProjectThing fiducial) {
    if (!fiducial.getType().equals("fiducial_points")) {
        Utils.log("Can only extract points from 'fiducial_points' type.");
        return null;
    }
    final ArrayList<ProjectThing> fiducials = fiducial.getChildren();
    if (null == fiducials || 0 == fiducials.size()) {
        Utils.log("No fiducial points can be extracted from " + fiducial);
        return null;
    }
    final Map<String, Tuple3d> fide = new HashMap<String, Tuple3d>();
    for (final ProjectThing child : fiducials) {
        final Ball ball;
        final String title;
        if (child.getType().equals("ball")) {
            // Method 1: use the ball title as the fiducial type
            ball = (Ball) child.getObject();
            title = ball.getTitle();
        } else {
            // Method 2: use the ball's parent type as the fiducial type
            final ArrayList<ProjectThing> balls = child.findChildrenOfType("ball");
            if (null == balls || 0 == balls.size()) {
                Utils.log2("Ignoring empty fiducial " + child);
                continue;
            }
            // pick the first one only
            ball = (Ball) balls.get(0).getObject();
            title = child.getType();
        }
        // calibrated
        final double[][] b = ball.getWorldBalls();
        if (b.length > 0) {
            // get the first one only
            fide.put(title.toLowerCase(), new Point3d(b[0][0], b[0][1], b[0][2]));
            Utils.log2("Found fiducial point " + title.toLowerCase());
        }
    }
    return fide;
}
Also used : Ball(ini.trakem2.display.Ball) HashMap(java.util.HashMap) Tuple3d(org.scijava.vecmath.Tuple3d) Point3d(org.scijava.vecmath.Point3d) ProjectThing(ini.trakem2.tree.ProjectThing)

Aggregations

Point3d (org.scijava.vecmath.Point3d)8 ArrayList (java.util.ArrayList)3 Vector3d (org.scijava.vecmath.Vector3d)2 Calibration (ij.measure.Calibration)1 Content (ij3d.Content)1 Picker (ij3d.behaviors.Picker)1 Ball (ini.trakem2.display.Ball)1 Coordinate (ini.trakem2.display.Coordinate)1 Display (ini.trakem2.display.Display)1 Layer (ini.trakem2.display.Layer)1 ProjectThing (ini.trakem2.tree.ProjectThing)1 VectorString3D (ini.trakem2.vector.VectorString3D)1 HashMap (java.util.HashMap)1 Transform3D (org.scijava.java3d.Transform3D)1 Tuple3d (org.scijava.vecmath.Tuple3d)1