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);
}
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());
}
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;
}
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;
}
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;
}
Aggregations