Search in sources :

Example 1 with Vector3

use of ini.trakem2.utils.Vector3 in project TrakEM2 by trakem2.

the class Pipe method makeTube.

public static double[][][] makeTube(double[] px, double[] py, double[] pz, double[] p_width_i, final int resample, final int parallels, final Calibration cal) {
    int n = px.length;
    // Resampling to get a smoother pipe
    try {
        final VectorString3D vs = new VectorString3D(px, py, pz, false);
        if (null != cal) {
            vs.calibrate(cal);
            for (int i = 0; i < p_width_i.length; i++) p_width_i[i] *= cal.pixelWidth;
        }
        vs.addDependent(p_width_i);
        // Resample to the largest of the two:
        // calibrated
        final double avg_delta = vs.getAverageDelta();
        // can't use resample, pipes would look very segmented
        final double delta = Math.max(avg_delta, 1);
        vs.resample(delta);
        // vs.resample(vs.getAverageDelta() * resample);
        px = vs.getPoints(0);
        py = vs.getPoints(1);
        pz = vs.getPoints(2);
        p_width_i = vs.getDependent(0);
        // Utils.log("lengths:  " + px.length + ", " + py.length + ", " + pz.length + ", " + p_width_i.length);
        n = vs.length();
    } catch (final Exception e) {
        IJError.print(e);
    }
    final double[][][] all_points = new double[n + 2][parallels + 1][3];
    // this was zero when not doing capping
    final int extra = 1;
    for (int cap = 0; cap < parallels + 1; cap++) {
        // p_i[0][0]; //x
        all_points[0][cap][0] = px[0];
        // p_i[1][0]; //y
        all_points[0][cap][1] = py[0];
        // z_values[0];
        all_points[0][cap][2] = pz[0];
        // p_i[0][p_i[0].length-1];
        all_points[all_points.length - 1][cap][0] = px[n - 1];
        // p_i[1][p_i[0].length-1];
        all_points[all_points.length - 1][cap][1] = py[n - 1];
        // z_values[z_values.length-1];
        all_points[all_points.length - 1][cap][2] = pz[n - 1];
    }
    // Math.toRadians(30);
    final double angle = 2 * Math.PI / parallels;
    Vector3 v3_P12;
    Vector3 v3_PR;
    final Vector3[] circle = new Vector3[parallels + 1];
    double sinn, coss;
    final int half_parallels = parallels / 2;
    for (int i = 0; i < n - 1; i++) {
        // Utils.log2(i + " : " + px[i] + ", " + py[i] + ", " + pz[i]);
        // First vector: from one realpoint to the next
        // v3_P12 = new Vector3(p_i[0][i+1] - p_i[0][i], p_i[1][i+1] - p_i[1][i], z_values[i+1] - z_values[i]);
        v3_P12 = new Vector3(px[i + 1] - px[i], py[i + 1] - py[i], pz[i + 1] - pz[i]);
        // BELOW if-else statements needed to correct the orientation of vectors, so there's no discontinuity
        if (v3_P12.y < 0) {
            v3_PR = new Vector3(v3_P12.y, -v3_P12.x, 0);
            v3_PR = v3_PR.normalize(v3_PR);
            v3_PR = v3_PR.scale(p_width_i[i], v3_PR);
            // vectors are perfectly normalized and scaled
            // The problem then must be that they are not properly ortogonal and so appear to have a smaller width.
            // -not only not ortogonal but actually messed up in some way, i.e. bad coords.
            circle[half_parallels] = v3_PR;
            for (int q = half_parallels + 1; q < parallels + 1; q++) {
                sinn = Math.sin(angle * (q - half_parallels));
                coss = Math.cos(angle * (q - half_parallels));
                circle[q] = Vector3.rotate_v_around_axis(v3_PR, v3_P12, sinn, coss);
            }
            circle[0] = circle[parallels];
            for (int qq = 1; qq < half_parallels; qq++) {
                sinn = Math.sin(angle * (qq + half_parallels));
                coss = Math.cos(angle * (qq + half_parallels));
                circle[qq] = Vector3.rotate_v_around_axis(v3_PR, v3_P12, sinn, coss);
            }
        } else {
            // thining problems disappear when both types of y coord are equal, but then shifting appears
            v3_PR = new Vector3(-v3_P12.y, v3_P12.x, 0);
            /*
				Observations:
					-if y coord shifted, then no thinnings but yes shiftings
					-if x coord shifted, THEN PERFECT
					-if both shifted, then both thinnings and shiftings
					-if none shifted, then no shiftings but yes thinnings
				*/
            v3_PR = v3_PR.normalize(v3_PR);
            if (null == v3_PR) {
                Utils.log2("vp_3r is null: most likely a point was repeated in the list, and thus the vector has length zero.");
            }
            v3_PR = v3_PR.scale(p_width_i[i], v3_PR);
            circle[0] = v3_PR;
            for (int q = 1; q < parallels; q++) {
                sinn = Math.sin(angle * q);
                coss = Math.cos(angle * q);
                circle[q] = Vector3.rotate_v_around_axis(v3_PR, v3_P12, sinn, coss);
            }
            circle[parallels] = v3_PR;
        }
        // Adding points to main array
        for (int j = 0; j < parallels + 1; j++) {
            all_points[i + extra][j][0] = /*p_i[0][i]*/
            px[i] + circle[j].x;
            all_points[i + extra][j][1] = /*p_i[1][i]*/
            py[i] + circle[j].y;
            all_points[i + extra][j][2] = /*z_values[i]*/
            pz[i] + circle[j].z;
        }
    }
    for (int k = 0; k < parallels + 1; k++) {
        all_points[n - 1 + extra][k][0] = /*p_i[0][n-1]*/
        px[n - 1] + circle[k].x;
        all_points[n - 1 + extra][k][1] = /*p_i[1][n-1]*/
        py[n - 1] + circle[k].y;
        all_points[n - 1 + extra][k][2] = /*z_values[n-1]*/
        pz[n - 1] + circle[k].z;
    }
    return all_points;
}
Also used : VectorString3D(ini.trakem2.vector.VectorString3D) Vector3(ini.trakem2.utils.Vector3)

Aggregations

Vector3 (ini.trakem2.utils.Vector3)1 VectorString3D (ini.trakem2.vector.VectorString3D)1