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 |
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; } |
Free forum by Nabble | Edit this page |