Arc overlay

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

Arc overlay

AAM71
Dear listers,

I would like to make a grid overlay for my quantifications. The standard
grid implementation is quite simple: there are already macro and several
plugins for that. I would like to make so called Merz grid, which
consists of semicircles connected with each other to form a wavy line.
This kind of grid may be very useful for some samples because it is
isotropic in 2D space. I have tried to figure out hoe to make it in
ImageJ using non-destructive overlay but failed. Is it any way to make
an arc by means of macro language in ImageJ?

Sincerely,
Alex Mironov
Reply | Threaded
Open this post in threaded view
|

Re: Arc overlay

vischer
Hi Aleksandr,

below is a macro that uses turtle graphics that I once wrote.
I added a few extra lines at the top to create a number of non-destructive waves.
Play with the variables "step" up to "yOffset" to get desired results.

regards, Norbert






var

k57 = 180/PI,
turtleX = newArray(2000), turtleY = newArray(2000),
verticesX = newArray(2000), verticesY = newArray(2000),
turtlePhi, tPtr, vtxPtr,
;

 
 

macro "Make Waves [F1]" {
        newImage("scratch", "8-bit Ramp", 700, 500, 1);
        run("Remove Overlay");
        step = 10; //length of a step in pixels
        nSteps = 6;//
        dPhi = 8; //degrees between 2 steps
        cycles = 2;
        yStart = 100;
        yOffset = 80;
        for (waves = 0; waves < 4; waves++){
                turtleInit(20, yStart, 0);//starting point and angle
                for (kk =0; kk<cycles; kk++){
               
                        for (jj = 0; jj < nSteps; jj++){
                                turtleLine (dPhi, step );
                        }
                        for (jj = 0; jj < (nSteps); jj++){
                                turtleLine (-dPhi, step );
                        }
                        for (jj = 0; jj < (nSteps); jj++){
                                turtleLine (-dPhi, step );
                        }
                        for (jj = 0; jj < nSteps; jj++){
                                turtleLine (dPhi, step );
                        }
                       
                }
                turtleMakeSelection("polyline");
                run("Add Selection...", "stroke=red width=1");
                run("Select None");
                yStart += yOffset;
        }
}

function sqr(a){
        return a*a;
}


function pushVtx(){
        verticesX[vtxPtr] = turtleX[tPtr];
        verticesY[vtxPtr] = turtleY[tPtr];
        vtxPtr++;
}


/*
Turtle routines
===============
at any moment, the turtle has position turtleX[tPtr], turtleY[tPtr],
and orientation turtlePhi.
Turtle array is 1-based.
Negative indices count from the back, so -1 addresses last vertex.
turtleX[0] and turtleY[0] are not used.

*/
function turtleInit(xx, yy, phi){
        tPtr =1;
        turtleX[1]= xx;
        turtleY[1]= yy;
        turtlePhi= phi;
}

//append a vertex using absolute parameters
function turtleSet(xx, yy, phi){
        tPtr++;
        turtleX[tPtr]= xx;
        turtleY[tPtr]= yy;
        while(phi < 0)
                phi += 360;
        //turtlePhi[tPtr]= phi;
        turtlePhi= phi;
}

// deletes a vertex and recalculates phi
function turtleDelete(index){
        if (index < 0)
                index = tPtr + index + 1;
        if (index > 0 && index <= tPtr && tPtr>=3){
                for (jj= index; jj<tPtr; jj++){
                        turtleX[jj] = turtleX[jj+1];
                        turtleY[jj] = turtleY[jj+1];
                }
        tPtr--;
        turtleAim(-2, 180);
        }
}
//create a selection
function turtleMakeSelection(type){

        if (type != "polyline" && type != "polygon")
                return;
        xx = newArray(tPtr);
        yy = newArray(tPtr);
        for (jj = 1; jj<=tPtr; jj++){
                xx[jj-1] = turtleX[jj];
                yy[jj-1] = turtleY[jj];
        }
        makeSelection(type, xx, yy);
}

function turtleLine(dPhi, rad){
        //don't add a new vertex if rad == 0
        turtlePhi -= dPhi;
        while(turtlePhi < 0)
                turtlePhi += 360;
        while(turtlePhi >= 360)
                turtlePhi -= 360;
        if (rad == 0)
                return;

        dx = rad * cos(turtlePhi/k57);
        dy = -rad * sin(turtlePhi/k57);
        newX = turtleX[tPtr] + dx;
        newY = turtleY[tPtr] + dy;
        tPtr++;
        turtleX[tPtr] = newX;
        turtleY[tPtr] = newY;
}


function turtlePath(start, stop){
//returns the path length between start and stop vertex
        if (start < 0)
                start = tPtr + start + 1;
        if (stop < 0)
                stop = tPtr + stop + 1;
        if (start > tPtr || stop > tPtr)
                return 0;
        len = 0;
        for (jj=minOf(start, stop); jj<maxOf(start, stop); jj++){
                dx = turtleX[jj+1] - turtleX[jj];
                dy = turtleY[jj+1] - turtleY[jj];
                len += sqrt(dx*dx + dy*dy);
        }
        return len;
}

function turtlePhiOfSegment(index){
// eg if index=3, returns the angle of third segment
// east = 0 deg, north = 90 deg
        if (index < 0)
                index = tPtr + index;
        if (index > tPtr-1 || index < 0)
                return NaN;
        dx = (turtleX[index + 1] - turtleX[index]);
        dy = -(turtleY[index + 1] - turtleY[index]);
        return k57 * atan2(dy, dx);
}


function turtleAim(index, dPhi){
//changes current turtle direction to aim at a former vertex
//defined by index.
//No new vertex is added.
//negative index: count from stack top backwards
//if distance was zero, phi from aimed point is used as
        if (index < 0)
                index = tPtr + index +1;
        if (index >= tPtr || index < 0)
                exit("Turtle range error");
        dx = -(turtleX[tPtr] - turtleX[index]);
        dy = (turtleY[tPtr] - turtleY[index]);

        if (dx == 0 && dy == 0)
                newPhi = turtlePhi;//[index]);
        else
                newPhi = k57 * atan2(dy, dx);
        turtlePhi = newPhi + dPhi;
}