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