Macro for 'polyline' tool with constant length of segments

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

Macro for 'polyline' tool with constant length of segments

Jeremias Brand
Hi,

I am working on a macro that allows me to draw a segmented line and then
measures all the angles between the segments.
Measuring the angles works fine, but I also need to have segments of
equal length to assure repeatability. I am working of this macro for the
polygon:
http://imagej.nih.gov/ij/macros/tools/PolygonTool.txt 
<mailto:[hidden email]>
How can I fix the length of the segments? I have figured out how to
terminate the first segment at a specific length, but I do not know how
to continue the next segment form that point onward.
Here is my code so far:
macro "Polygon Tool -C00bB12P51f1f2b6b7eafb1b151451" {
         requires("1.45n");
         toolName = IJ.getToolName();
         size = 6/getZoom;
         x = newArray(2000);
         y = newArray(2000);
         getCursorLoc(x2, y2, z2, flags);
         x[0] = x2; y[0] = y2;
         x[1] = x2; y[1] = y2;
         n = 2;
         setOption("DisablePopupMenu", true);
         Overlay.drawRect(x[0]-size, y[0]-size, size*2, size*2);
         Overlay.show;
         while (flags&20!=0) // left and right click
          getCursorLoc(x2, y2, z2, flags);
         while (true) {
             getCursorLoc(x2, y2, z2, flags);
             if (flags&20!=0) {
                modKey = flags&14!=0; //right-click, control or alt
                while (flags&16!=0)
                   getCursorLoc(x2, y2, z2, flags);
                if (modKey) {
                      makeSelection("polyline", x, y, n);
                   Overlay.removeSelection(Overlay.size-1);
                   setOption("DisablePopupMenu", false);
                   exit;
                }
                n++;
              }
             run("Measure");
             length = getResult('Length', nResults-1);
                 if (length>=200) {
             exit;
                 }
             x[n-1] = x2;
             y[n-1] = y2;
             makeSelection("freeline", x, y, n);
             wait(10);
         }
    }

Please forgive me if this is a very amateur question. I just started
writing macros. Any help would really be appreciated!

Cheers,
Jeremias


--
*****************************
Jeremias Brand
University of Basel
Zoological Institute, Evolutionary Biology
Vesalgasse 1
4051 Basel
Switzerland

http://evolution.unibas.ch/scharer


--
*****************************
Jeremias Brand
University of Basel
Zoological Institute, Evolutionary Biology
Vesalgasse 1
4051 Basel
Switzerland

http://evolution.unibas.ch/scharer


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

Re: Macro for 'polyline' tool with constant length of segments

Rasband, Wayne (NIH/NIMH) [E]
On Nov 26, 2014, at 3:43 PM, Jeremias Brand <[hidden email]> wrote:
>
> Hi,
>
> I am working on a macro that allows me to draw a segmented line and then measures all the angles between the segments.
> Measuring the angles works fine, but I also need to have segments of equal length to assure repeatability. I am working of this macro for the polygon:
> http://imagej.nih.gov/ij/macros/tools/PolygonTool.txt <mailto:[hidden email]>
> How can I fix the length of the segments? I have figured out how to terminate the first segment at a specific length, but I do not know how to continue the next segment form that point onward.

The following macro tool creates segmented lines with equal length segments. Double click on the tool icon to set the segment length (the default is 80). Click in the box at the starting point, right-click, alt-click or control-click to finalize the polyline.

-wayne


   var segmentLength = 80;
 
   macro "Polyline Tool -C00bB12Pf6b21213792e0" {
        toolName = IJ.getToolName();  
        size = 6/getZoom;
        x = newArray(2000);
        y = newArray(2000);
        getCursorLoc(x2, y2, z2, flags);
        x[0] = x2; y[0] = y2;
        x[1] = x2; y[1] = y2;
        n = 2;
        setOption("DisablePopupMenu", true);
        Overlay.drawRect(x[0]-size, y[0]-size, size*2, size*2);
        Overlay.show;
        while (flags&20!=0) // left and right click
            getCursorLoc(x2, y2, z2, flags);
        while (true) {
            getCursorLoc(x2, y2, z2, flags);
            if (flags&20!=0) {
               modKey = flags&14!=0; //right-click, control or alt
               while (flags&16!=0)
                  getCursorLoc(x2, y2, z2, flags);
               inBox = x2>x[0]-size&&x2<x[0]+size&&y2>y[0]-size&&y2<y[0]+size;
               if (inBox || modKey) {
                  if (inBox)
                     makeSelection("polyline", x, y, n-1);
                  else
                     makeSelection("polyline", x, y, n);
                  Overlay.removeSelection(Overlay.size-1);
                  setOption("DisablePopupMenu", false);
                  exit;
               }
               dx = x2 - x[n-2];
               dy = y2 - y[n-2];
               length = sqrt(dx*dx+dy*dy);
               dx = dx/length;
               dy = dy/length;
               x[n-1] = x[n-2] + dx*segmentLength;
               y[n-1] = y[n-2] + dy*segmentLength;
               n++;
             }
            x[n-1] = x2;
            y[n-1] = y2;
            makeSelection("freeline", x, y, n);
            if (toolName!=IJ.getToolName()) {
               run("Select None");
               Overlay.removeSelection(Overlay.size-1);
               exit;
            }
            wait(10);
        }
   }

   macro 'Polyline Tool Options...' {
      segmentLength = getNumber("Segment Length (pixels):", segmentLength);
   }

 

> Here is my code so far:
> macro "Polygon Tool -C00bB12P51f1f2b6b7eafb1b151451" {
>        requires("1.45n");
>        toolName = IJ.getToolName();
>        size = 6/getZoom;
>        x = newArray(2000);
>        y = newArray(2000);
>        getCursorLoc(x2, y2, z2, flags);
>        x[0] = x2; y[0] = y2;
>        x[1] = x2; y[1] = y2;
>        n = 2;
>        setOption("DisablePopupMenu", true);
>        Overlay.drawRect(x[0]-size, y[0]-size, size*2, size*2);
>        Overlay.show;
>        while (flags&20!=0) // left and right click
>         getCursorLoc(x2, y2, z2, flags);
>        while (true) {
>            getCursorLoc(x2, y2, z2, flags);
>            if (flags&20!=0) {
>               modKey = flags&14!=0; //right-click, control or alt
>               while (flags&16!=0)
>                  getCursorLoc(x2, y2, z2, flags);
>               if (modKey) {
>                     makeSelection("polyline", x, y, n);
>                  Overlay.removeSelection(Overlay.size-1);
>                  setOption("DisablePopupMenu", false);
>                  exit;
>               }
>               n++;
>             }
>            run("Measure");
>            length = getResult('Length', nResults-1);
>                if (length>=200) {
>            exit;
>                }
>            x[n-1] = x2;
>            y[n-1] = y2;
>            makeSelection("freeline", x, y, n);
>            wait(10);
>        }
>   }
>
> Please forgive me if this is a very amateur question. I just started writing macros. Any help would really be appreciated!
>
> Cheers,
> Jeremias
>
>
> --
> *****************************
> Jeremias Brand
> University of Basel
> Zoological Institute, Evolutionary Biology
> Vesalgasse 1
> 4051 Basel
> Switzerland
>
> http://evolution.unibas.ch/scharer
>
>
> --
> *****************************
> Jeremias Brand
> University of Basel
> Zoological Institute, Evolutionary Biology
> Vesalgasse 1
> 4051 Basel
> Switzerland
>
> http://evolution.unibas.ch/scharer

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

Re: Macro for 'polyline' tool with constant length of segments

Jeremias Brand
In reply to this post by Jeremias Brand
Hi Wayne,

Thank you very much! I have also figured out a way now, but your version
is more precise.
I've used a if statement to get a cursor lock as soon as the length is
too long.

[...]
             xd = x[n-1] - x[n-2];
             yd = y[n-1] - y[n-2];
             distance = sqrt(xd*xd + yd*yd);

             if(distance >= maxLength) {
                 getCursorLoc(x2, y2, z2, flags);
                 n++;
             }

             x[n-1] = x2;
             y[n-1] = y2;
[...]

This makes it more intuitive to draw but also less precise because of
the lag between detection of the distance and getting the cursor lock.
I'll try to combine both approaches.
Thanks again!

Jeremias


Am 28.11.2014 um 07:35 schrieb Rasband, Wayne (NIH/NIMH) [E]:

> On Nov 26, 2014, at 3:43 PM, Jeremias Brand <[hidden email]> wrote:
>> Hi,
>>
>> I am working on a macro that allows me to draw a segmented line and then measures all the angles between the segments.
>> Measuring the angles works fine, but I also need to have segments of equal length to assure repeatability. I am working of this macro for the polygon:
>> http://imagej.nih.gov/ij/macros/tools/PolygonTool.txt <mailto:[hidden email]>
>> How can I fix the length of the segments? I have figured out how to terminate the first segment at a specific length, but I do not know how to continue the next segment form that point onward.
> The following macro tool creates segmented lines with equal length segments. Double click on the tool icon to set the segment length (the default is 80). Click in the box at the starting point, right-click, alt-click or control-click to finalize the polyline.
>
> -wayne
>
>
>     var segmentLength = 80;
>  
>     macro "Polyline Tool -C00bB12Pf6b21213792e0" {
>          toolName = IJ.getToolName();
>          size = 6/getZoom;
>          x = newArray(2000);
>          y = newArray(2000);
>          getCursorLoc(x2, y2, z2, flags);
>          x[0] = x2; y[0] = y2;
>          x[1] = x2; y[1] = y2;
>          n = 2;
>          setOption("DisablePopupMenu", true);
>          Overlay.drawRect(x[0]-size, y[0]-size, size*2, size*2);
>          Overlay.show;
>          while (flags&20!=0) // left and right click
>              getCursorLoc(x2, y2, z2, flags);
>          while (true) {
>              getCursorLoc(x2, y2, z2, flags);
>              if (flags&20!=0) {
>                 modKey = flags&14!=0; //right-click, control or alt
>                 while (flags&16!=0)
>                    getCursorLoc(x2, y2, z2, flags);
>                 inBox = x2>x[0]-size&&x2<x[0]+size&&y2>y[0]-size&&y2<y[0]+size;
>                 if (inBox || modKey) {
>                    if (inBox)
>                       makeSelection("polyline", x, y, n-1);
>                    else
>                       makeSelection("polyline", x, y, n);
>                    Overlay.removeSelection(Overlay.size-1);
>                    setOption("DisablePopupMenu", false);
>                    exit;
>                 }
>                 dx = x2 - x[n-2];
>                 dy = y2 - y[n-2];
>                 length = sqrt(dx*dx+dy*dy);
>                 dx = dx/length;
>                 dy = dy/length;
>                 x[n-1] = x[n-2] + dx*segmentLength;
>                 y[n-1] = y[n-2] + dy*segmentLength;
>                 n++;
>               }
>              x[n-1] = x2;
>              y[n-1] = y2;
>              makeSelection("freeline", x, y, n);
>              if (toolName!=IJ.getToolName()) {
>                 run("Select None");
>                 Overlay.removeSelection(Overlay.size-1);
>                 exit;
>              }
>              wait(10);
>          }
>     }
>
>     macro 'Polyline Tool Options...' {
>        segmentLength = getNumber("Segment Length (pixels):", segmentLength);
>     }
>
>  
>> Here is my code so far:
>> macro "Polygon Tool -C00bB12P51f1f2b6b7eafb1b151451" {
>>         requires("1.45n");
>>         toolName = IJ.getToolName();
>>         size = 6/getZoom;
>>         x = newArray(2000);
>>         y = newArray(2000);
>>         getCursorLoc(x2, y2, z2, flags);
>>         x[0] = x2; y[0] = y2;
>>         x[1] = x2; y[1] = y2;
>>         n = 2;
>>         setOption("DisablePopupMenu", true);
>>         Overlay.drawRect(x[0]-size, y[0]-size, size*2, size*2);
>>         Overlay.show;
>>         while (flags&20!=0) // left and right click
>>          getCursorLoc(x2, y2, z2, flags);
>>         while (true) {
>>             getCursorLoc(x2, y2, z2, flags);
>>             if (flags&20!=0) {
>>                modKey = flags&14!=0; //right-click, control or alt
>>                while (flags&16!=0)
>>                   getCursorLoc(x2, y2, z2, flags);
>>                if (modKey) {
>>                      makeSelection("polyline", x, y, n);
>>                   Overlay.removeSelection(Overlay.size-1);
>>                   setOption("DisablePopupMenu", false);
>>                   exit;
>>                }
>>                n++;
>>              }
>>             run("Measure");
>>             length = getResult('Length', nResults-1);
>>                 if (length>=200) {
>>             exit;
>>                 }
>>             x[n-1] = x2;
>>             y[n-1] = y2;
>>             makeSelection("freeline", x, y, n);
>>             wait(10);
>>         }
>>    }
>>
>> Please forgive me if this is a very amateur question. I just started writing macros. Any help would really be appreciated!
>>
>> Cheers,
>> Jeremias
>>
>>
>> --
>> *****************************
>> Jeremias Brand
>> University of Basel
>> Zoological Institute, Evolutionary Biology
>> Vesalgasse 1
>> 4051 Basel
>> Switzerland
>>
>> http://evolution.unibas.ch/scharer
>>
>>
>> --
>> *****************************
>> Jeremias Brand
>> University of Basel
>> Zoological Institute, Evolutionary Biology
>> Vesalgasse 1
>> 4051 Basel
>> Switzerland
>>
>> http://evolution.unibas.ch/scharer
> --
> ImageJ mailing list: http://imagej.nih.gov/ij/list.html

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