Measure of the angles of a segmented line

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
7 messages Options
Reply | Threaded
Open this post in threaded view
|

Measure of the angles of a segmented line

ERIC
Hi all,
Is there a macro/plugin to measure all the angles formed by a segmented
line selection ?

Thanks

--

Eric Denarier
Grenoble Institut des Neurosciences
Inserm U836
Chemin Fortuné Ferrini
38700 La Tronche
France


Tél :33 (0)4 56 52 05 38
Fax :33 (0)4 56 52 06 57

http://neurosciences.ujf-grenoble.fr/

--
ImageJ mailing list: http://imagej.nih.gov/ij/list.html
Reply | Threaded
Open this post in threaded view
|

Re: Measure of the angles of a segmented line

Rasband, Wayne (NIH/NIMH) [E]
On Dec 5, 2012, at 8:23 AM, Eric Denarier wrote:

> Hi all,
> Is there a macro/plugin to measure all the angles formed by a segmented
> line selection ?

Here is a macro that does this:

  getSelectionCoordinates(x, y);
  for (i=1; i<x.length-1; i++) {
    dotprod = (x[i+1]-x[i])*(x[i-1]-x[i])+(y[i+1]-y[i])*(y[i-1]-y[i]);
    len1 = sqrt((x[i-1]-x[i])*(x[i-1]-x[i])+(y[i-1]-y[i])*(y[i-1]-y[i]));
    len2 = sqrt((x[i+1]-x[i])*(x[i+1]-x[i])+(y[i+1]-y[i])*(y[i+1]-y[i]));
    angle = (180/PI)*acos(dotprod/(len1*len2));
    print(i, angle);
  }

I found the code for calculating an angle given 3 points using the dot product at

   http://stackoverflow.com/questions/6719563/

-wayne

--
ImageJ mailing list: http://imagej.nih.gov/ij/list.html
Reply | Threaded
Open this post in threaded view
|

Re: Measure of the angles of a segmented line

ERIC
Thanks Wayne,
That's what I needed !!!

Eric Denarier
Grenoble Institut des Neurosciences
Inserm U836
Chemin Fortuné Ferrini
38700 La Tronche
France


Tél :33 (0)4 56 52 05 38
Fax :33 (0)4 56 52 06 57

http://neurosciences.ujf-grenoble.fr/

Le 05/12/2012 19:11, Rasband, Wayne (NIH/NIMH) [E] a écrit :

> On Dec 5, 2012, at 8:23 AM, Eric Denarier wrote:
>
>> Hi all,
>> Is there a macro/plugin to measure all the angles formed by a segmented
>> line selection ?
> Here is a macro that does this:
>
>    getSelectionCoordinates(x, y);
>    for (i=1; i<x.length-1; i++) {
>      dotprod = (x[i+1]-x[i])*(x[i-1]-x[i])+(y[i+1]-y[i])*(y[i-1]-y[i]);
>      len1 = sqrt((x[i-1]-x[i])*(x[i-1]-x[i])+(y[i-1]-y[i])*(y[i-1]-y[i]));
>      len2 = sqrt((x[i+1]-x[i])*(x[i+1]-x[i])+(y[i+1]-y[i])*(y[i+1]-y[i]));
>      angle = (180/PI)*acos(dotprod/(len1*len2));
>      print(i, angle);
>    }
>
> I found the code for calculating an angle given 3 points using the dot product at
>
>     http://stackoverflow.com/questions/6719563/
>
> -wayne
>
> --
> ImageJ mailing list: http://imagej.nih.gov/ij/list.html

--
ImageJ mailing list: http://imagej.nih.gov/ij/list.html
Reply | Threaded
Open this post in threaded view
|

Re: Measure of the angles of a segmented line

vischer
In reply to this post by Rasband, Wayne (NIH/NIMH) [E]
I was using Wayne's macro below and experienced NaN values. This happened on straight lines, when
the argument of acos() was outside range -1 .. 1 due to rounding errors.
An improved version is here:

getSelectionCoordinates(x, y);
for (i=1; i<x.length-1; i++) {
        dotprod = (x[i+1]-x[i])*(x[i-1]-x[i])+(y[i+1]-y[i])*(y[i-1]-y[i]);
        len1 = sqrt((x[i-1]-x[i])*(x[i-1]-x[i])+(y[i-1]-y[i])*(y[i-1]-y[i]));
        len2 = sqrt((x[i+1]-x[i])*(x[i+1]-x[i])+(y[i+1]-y[i])*(y[i+1]-y[i]));
        val = minOf(1, dotprod/(len1*len2));
        val = maxOf(-1, val);
        angle = (180/PI)*acos(val);
        print(i, angle);
}

Norbert Vischer


> On 5. Dec 2012, at 19:11, Rasband, Wayne (NIH/NIMH) [E] wrote:
>
> On Dec 5, 2012, at 8:23 AM, Eric Denarier wrote:
>
>> Hi all,
>> Is there a macro/plugin to measure all the angles formed by a segmented
>> line selection ?
>
> Here is a macro that does this:
>
>  getSelectionCoordinates(x, y);
>  for (i=1; i<x.length-1; i++) {
>    dotprod = (x[i+1]-x[i])*(x[i-1]-x[i])+(y[i+1]-y[i])*(y[i-1]-y[i]);
>    len1 = sqrt((x[i-1]-x[i])*(x[i-1]-x[i])+(y[i-1]-y[i])*(y[i-1]-y[i]));
>    len2 = sqrt((x[i+1]-x[i])*(x[i+1]-x[i])+(y[i+1]-y[i])*(y[i+1]-y[i]));
>    angle = (180/PI)*acos(dotprod/(len1*len2));
>    print(i, angle);
>  }
>
> I found the code for calculating an angle given 3 points using the dot product at
>
>   http://stackoverflow.com/questions/6719563/
>
> -wayne

--
ImageJ mailing list: http://imagej.nih.gov/ij/list.html
Reply | Threaded
Open this post in threaded view
|

Re: Measure of the angles of a segmented line

Michael Schmid
Hi Norbert,

for calculating angles from x & y, usually the best method is the atan2 function. It is not sensitive to rounding errors and takes care of all special cases like 0°, 90°, 180° etc.
This can be also used for the angle between two vectors:

  dotprod = (x[i+1]-x[i])*(x[i-1]-x[i])+(y[i+1]-y[i])*(y[i-1]-y[i]);
  crossprod = (x[i+1]-x[i])*(y[i-1]-y[i])-(y[i+1]-y[i])*(x[i-1]-x[i]);
  angle = (180/PI)*atan2(crossprod, dotprod);

I you don't care about positive or negative angles, take the absolute value, abs(angle).


Michael
________________________________________________________________
On Jan 11, 2013, at 16:04, Norbert Vischer wrote:

> I was using Wayne's macro below and experienced NaN values. This happened on straight lines, when
> the argument of acos() was outside range -1 .. 1 due to rounding errors.
> An improved version is here:
>
> getSelectionCoordinates(x, y);
> for (i=1; i<x.length-1; i++) {
> dotprod = (x[i+1]-x[i])*(x[i-1]-x[i])+(y[i+1]-y[i])*(y[i-1]-y[i]);
> len1 = sqrt((x[i-1]-x[i])*(x[i-1]-x[i])+(y[i-1]-y[i])*(y[i-1]-y[i]));
> len2 = sqrt((x[i+1]-x[i])*(x[i+1]-x[i])+(y[i+1]-y[i])*(y[i+1]-y[i]));
> val = minOf(1, dotprod/(len1*len2));
> val = maxOf(-1, val);
> angle = (180/PI)*acos(val);
> print(i, angle);
> }
>
> Norbert Vischer
>
>
>> On 5. Dec 2012, at 19:11, Rasband, Wayne (NIH/NIMH) [E] wrote:
>>
>> On Dec 5, 2012, at 8:23 AM, Eric Denarier wrote:
>>
>>> Hi all,
>>> Is there a macro/plugin to measure all the angles formed by a segmented
>>> line selection ?
>>
>> Here is a macro that does this:
>>
>> getSelectionCoordinates(x, y);
>> for (i=1; i<x.length-1; i++) {
>>   dotprod = (x[i+1]-x[i])*(x[i-1]-x[i])+(y[i+1]-y[i])*(y[i-1]-y[i]);
>>   len1 = sqrt((x[i-1]-x[i])*(x[i-1]-x[i])+(y[i-1]-y[i])*(y[i-1]-y[i]));
>>   len2 = sqrt((x[i+1]-x[i])*(x[i+1]-x[i])+(y[i+1]-y[i])*(y[i+1]-y[i]));
>>   angle = (180/PI)*acos(dotprod/(len1*len2));
>>   print(i, angle);
>> }
>>
>> I found the code for calculating an angle given 3 points using the dot product at
>>
>>  http://stackoverflow.com/questions/6719563/
>>
>> -wayne
>
> --
> ImageJ mailing list: http://imagej.nih.gov/ij/list.html

--
ImageJ mailing list: http://imagej.nih.gov/ij/list.html
Reply | Threaded
Open this post in threaded view
|

Re: Measure of the angles of a segmented line

vischer
Hi Michael,

very elegant - as I can now distinguish between left-turn and right-turn.
 

Norbert


> On 11. Jan 2013, at 17:09, Michael Schmid wrote:
>
> Hi Norbert,
>
> for calculating angles from x & y, usually the best method is the atan2 function. It is not sensitive to rounding errors and takes care of all special cases like 0°, 90°, 180° etc.
> This can be also used for the angle between two vectors:
>
>  dotprod = (x[i+1]-x[i])*(x[i-1]-x[i])+(y[i+1]-y[i])*(y[i-1]-y[i]);
>  crossprod = (x[i+1]-x[i])*(y[i-1]-y[i])-(y[i+1]-y[i])*(x[i-1]-x[i]);
>  angle = (180/PI)*atan2(crossprod, dotprod);
>
> I you don't care about positive or negative angles, take the absolute value, abs(angle).
>
>
> Michael
> ________________________________________________________________
> On Jan 11, 2013, at 16:04, Norbert Vischer wrote:
>
>> I was using Wayne's macro below and experienced NaN values. This happened on straight lines, when
>> the argument of acos() was outside range -1 .. 1 due to rounding errors.
>> An improved version is here:
>>
>> getSelectionCoordinates(x, y);
>> for (i=1; i<x.length-1; i++) {
>> dotprod = (x[i+1]-x[i])*(x[i-1]-x[i])+(y[i+1]-y[i])*(y[i-1]-y[i]);
>> len1 = sqrt((x[i-1]-x[i])*(x[i-1]-x[i])+(y[i-1]-y[i])*(y[i-1]-y[i]));
>> len2 = sqrt((x[i+1]-x[i])*(x[i+1]-x[i])+(y[i+1]-y[i])*(y[i+1]-y[i]));
>> val = minOf(1, dotprod/(len1*len2));
>> val = maxOf(-1, val);
>> angle = (180/PI)*acos(val);
>> print(i, angle);
>> }
>>
>> Norbert Vischer
>>
>>
>>> On 5. Dec 2012, at 19:11, Rasband, Wayne (NIH/NIMH) [E] wrote:
>>>
>>> On Dec 5, 2012, at 8:23 AM, Eric Denarier wrote:
>>>
>>>> Hi all,
>>>> Is there a macro/plugin to measure all the angles formed by a segmented
>>>> line selection ?
>>>
>>> Here is a macro that does this:
>>>
>>> getSelectionCoordinates(x, y);
>>> for (i=1; i<x.length-1; i++) {
>>>  dotprod = (x[i+1]-x[i])*(x[i-1]-x[i])+(y[i+1]-y[i])*(y[i-1]-y[i]);
>>>  len1 = sqrt((x[i-1]-x[i])*(x[i-1]-x[i])+(y[i-1]-y[i])*(y[i-1]-y[i]));
>>>  len2 = sqrt((x[i+1]-x[i])*(x[i+1]-x[i])+(y[i+1]-y[i])*(y[i+1]-y[i]));
>>>  angle = (180/PI)*acos(dotprod/(len1*len2));
>>>  print(i, angle);
>>> }
>>>
>>> I found the code for calculating an angle given 3 points using the dot product at
>>>
>>> http://stackoverflow.com/questions/6719563/
>>>
>>> -wayne
>

--
ImageJ mailing list: http://imagej.nih.gov/ij/list.html
Reply | Threaded
Open this post in threaded view
|

Re: Measure of the angles of a segmented line

kelpny
In reply to this post by Rasband, Wayne (NIH/NIMH) [E]
I am trying to adapt Wayne's code to fit my use but am new to writing code.
My goal was to get the angle and length of the first line of the first angle
recorded in the results table along with the slice number which I was able
to to with the code below...although this gives me all the numbers I need it
does give me *too much* information and would be easier if I could just have
certain parts of the data recorded.

For example: Using a 5 point segmented line (4 total lines)
1. adds length of line 1 and 2=total length
2.  gives just the angle between line 2 and 3
3. and gives length of line 4
4. All within 1 row of the results table

Current Code:
macro "Segmented Line Angles [a]" {
getSelectionCoordinates(x, y);
  for (i=1; i<x.length-1; i++) {
    dotprod = (x[i+1]-x[i])*(x[i-1]-x[i])+(y[i+1]-y[i])*(y[i-1]-y[i]);
    len1 = sqrt((x[i-1]-x[i])*(x[i-1]-x[i])+(y[i-1]-y[i])*(y[i-1]-y[i]));
    len2 = sqrt((x[i+1]-x[i])*(x[i+1]-x[i])+(y[i+1]-y[i])*(y[i+1]-y[i]));
    angle = (180/PI)*acos(dotprod/(len1*len2));
    slice = getSliceNumber();
    row = nResults();
    setResult(&quot;Angle&quot;, row, angle);
    setResult(&quot;Length&quot;, row, len1);
    setResult(&quot;Slice&quot;, row, slice);
    updateResults();
 
After Running :
&lt;nabble_img src=&quot;2_line.png&quot; border=&quot;0&quot;/>



--
Sent from: http://imagej.1557.x6.nabble.com/

--
ImageJ mailing list: http://imagej.nih.gov/ij/list.html