Login  Register

Re: measure particle distance to an arbitrary line

Posted by ctrueden on Feb 22, 2006; 6:34pm
URL: http://imagej.273.s1.nabble.com/measure-particle-distance-to-an-arbitrary-line-tp3703628p3703630.html

Hi Javier,

> I am interested in measuring the (shortest) distance of multiple
> particles to a manually drawn straight line in an image. This could be
> done manually for each particle, but the results would be less
> accurate and the process very time-consuming. Since each image
> contains between 50 and 100 well defined particles, the manual
> approach is not reasonable.
>
> Any ideas?


I wrote some Java code (below) to measure the distance between a point
and a line (either a "true" line or a line segment). You could take this
code, throw it into a Java source file, then write a plugin or macro
that for each particle, measures the distance to the user-defined line
and spits it out to a text file or something. (I am assuming there is
one manually drawn line, and you want the distance to that same line for
all 50-100 particles?)

Good luck,
-Curtis

-----

  /**
   * Computes the minimum distance between the point v and the line a-b.
   *
   * @param a Coordinates of the line's first endpoint
   * @param b Coordinates of the line's second endpoint
   * @param v Coordinates of the standalone endpoint
   * @param segment Whether distance computation should be
   *                constrained to the given line segment
   */
  public static double getDistance(double[] a, double[] b, double[] v,
    boolean segment)
  {
    int len = a.length;

    // vectors
    double[] ab = new double[len];
    double[] va = new double[len];
    for (int i=0; i<len; i++) {
      ab[i] = a[i] - b[i];
      va[i] = v[i] - a[i];
    }

    // project v onto (a, b)
    double numer = 0;
    double denom = 0;
    for (int i=0; i<len; i++) {
      numer += va[i] * ab[i];
      denom += ab[i] * ab[i];
    }
    double c = numer / denom;
    double[] p = new double[len];
    for (int i=0; i<len; i++) p[i] = c * ab[i] + a[i];

    // determine which point (a, b or p) to use in distance computation
    int flag = 0;
    if (segment) {
      for (int i=0; i<len; i++) {
        if (p[i] > a[i] && p[i] > b[i]) flag = a[i] > b[i] ? 1 : 2;
        else if (p[i] < a[i] && p[i] < b[i]) flag = a[i] < b[i] ? 1 : 2;
        else continue;
        break;
      }
    }

    double sum = 0;
    for (int i=0; i<len; i++) {
      double q;
      if (flag == 0) q = p[i] - v[i]; // use p
      else if (flag == 1) q = a[i] - v[i]; // use a
      else q = b[i] - v[i]; // flag == 2, use b
      sum += q * q;
    }

    return Math.sqrt(sum);
  }