Re: Arc overlay
Posted by vischer on Jun 29, 2010; 8:36pm
URL: http://imagej.273.s1.nabble.com/Arc-overlay-tp3687784p3687785.html
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;
}