Ejemplo n.º 1
0
  /**
   * Transforms the specified array of times and marks. Known samples are those for which times are
   * zero, and times and marks for these known samples are used to compute times and marks for
   * unknown samples.
   *
   * @param times input/output array of times.
   * @param marks input/output array of marks.
   */
  public void apply(float[][][] times, int[][][] marks) {

    // Measure elapsed time in seconds.
    Stopwatch sw = new Stopwatch();
    sw.start();
    log.fine("TimeMarker3.apply: begin time=" + (int) sw.time());

    // Initialize all unknown times to infinity.
    for (int i3 = 0; i3 < _n3; ++i3) {
      for (int i2 = 0; i2 < _n2; ++i2) {
        for (int i1 = 0; i1 < _n1; ++i1) {
          if (times[i3][i2][i1] != 0.0f) times[i3][i2][i1] = INFINITY;
        }
      }
    }

    // Indices of known samples in random order.
    short[][] kk = indexKnownSamples(times);
    short[] k1 = kk[0];
    short[] k2 = kk[1];
    short[] k3 = kk[2];
    shuffle(k1, k2, k3);
    int nk = k1.length;

    // Array for the eikonal solution times.
    float[][][] t = new float[_n3][_n2][_n1];

    // Active list of samples used to compute times.
    ActiveList al = new ActiveList();

    // For all known samples, ...
    for (int ik = 0; ik < nk; ++ik) {
      if (ik % (1 + (nk - 1) / 100) == 0)
        log.fine("  apply: ik/nk=" + ik + "/" + nk + " time=" + (int) sw.time());
      int i1 = k1[ik];
      int i2 = k2[ik];
      int i3 = k3[ik];

      // Clear activated flags so we can tell which samples become activated.
      clearActivated();

      // Put the known sample with time zero into the active list.
      t[i3][i2][i1] = 0.0f;
      al.append(_s[i3][i2][i1]);

      // The mark for the known sample.
      int m = marks[i3][i2][i1];

      // Process the active list until empty.
      solve(al, t, m, times, marks);
    }

    // Log elapsed time.
    sw.stop();
    log.fine("TimeMarker3.apply: end time=" + (int) sw.time());
  }
Ejemplo n.º 2
0
  /*
   * Processes one sample from the A list.
   * Appends samples not yet converged to the B list.
   */
  private void solveOne(
      float[][][] t,
      int m,
      float[][][] times,
      int[][][] marks,
      Sample s,
      ActiveList bl,
      float[] d) {
    // Sample indices.
    int i1 = s.i1;
    int i2 = s.i2;
    int i3 = s.i3;

    // Current time and new time computed from all four neighbors.
    float ti = currentTime(t, i1, i2, i3);
    float ci = computeTime(t, i1, i2, i3, K1S[6], K2S[6], K3S[6], d);
    t[i3][i2][i1] = ci;

    // If new and current times are close enough (converged), then ...
    if (ci >= ti * ONE_MINUS_EPSILON) {

      // Neighbors may need to be activated if computed time is small
      // relative to the minimum time computed so far. The factor 1.5
      // improves accuracy for large anisotropy. Cost increases as the
      // square of this factor, so we do not want it to be too large.
      boolean checkNabors = ci <= 1.5f * times[i3][i2][i1];

      // If computed time less than minimum time, mark this sample.
      if (ci < times[i3][i2][i1]) {
        times[i3][i2][i1] = ci;
        marks[i3][i2][i1] = m;
      }

      // If necessary, check the neighbors.
      if (checkNabors) {

        // For all six neighbors, ...
        for (int k = 0; k < 6; ++k) {

          // Neighbor sample indices; skip if out of bounds.
          int j1 = i1 + K1[k];
          if (j1 < 0 || j1 >= _n1) continue;
          int j2 = i2 + K2[k];
          if (j2 < 0 || j2 >= _n2) continue;
          int j3 = i3 + K3[k];
          if (j3 < 0 || j3 >= _n3) continue;

          // Skip neighbor sample if computed time would be too big.
          // if (!doComputeTime(t,times,j1,j2)) continue;

          // Current and computed times for the neighbor.
          float tj = currentTime(t, j1, j2, j3);
          float cj = computeTime(t, j1, j2, j3, K1S[k], K2S[k], K3S[k], d);

          // If computed time is significantly less than current time, ...
          if (cj < tj * ONE_MINUS_EPSILON) {

            // Replace the current time.
            t[j3][j2][j1] = cj;

            // Append neighbor to the B list, thereby activating it.
            bl.append(_s[j3][j2][j1]);
          }
        }
      }
    }

    // Else, if not converged, append this sample to the B list.
    else {
      bl.append(s);
    }
  }