package ij.gui;
import java.awt.*;
import java.awt.image.*;
import ij.*;
import ij.process.*;
import ij.measure.Calibration;
/** Oval region of interest */
public class OvalRoi extends Roi {
/** Creates an OvalRoi.*/
public OvalRoi(int x, int y, int width, int height) {
super(x, y, width, height);
type = OVAL;
}
/** Creates an OvalRoi using double arguments.*/
public OvalRoi(double x, double y, double width, double height) {
super(x, y, width, height);
type = OVAL;
}
/** Starts the process of creating a user-defined OvalRoi. */
public OvalRoi(int x, int y, ImagePlus imp) {
super(x, y, imp);
type = OVAL;
}
/** @deprecated */
public OvalRoi(int x, int y, int width, int height, ImagePlus imp) {
this(x, y, width, height);
setImage(imp);
}
protected void moveHandle(int sx, int sy) {
double asp;
if (clipboard!=null) return;
int ox = ic.offScreenX(sx);
int oy = ic.offScreenY(sy);
//IJ.log("moveHandle: "+activeHandle+" "+ox+" "+oy);
int x1=x, y1=y, x2=x+width, y2=y+height, xc=x+width/2, yc=y+height/2;
int w2 = (int)(0.14645*width);
int h2 = (int)(0.14645*height);
if (width > 7 && height > 7) {
asp = (double)width/(double)height;
asp_bk = asp;
} else
asp = asp_bk;
switch (activeHandle) {
case 0: x=ox-w2; y=oy-h2; break;
case 1: y=oy; break;
case 2: x2=ox+w2; y=oy-h2; break;
case 3: x2=ox; break;
case 4: x2=ox+w2; y2=oy+h2; break;
case 5: y2=oy; break;
case 6: x=ox-w2; y2=oy+h2; break;
case 7: x=ox; break;
}
//if (x<0) x=0; if (y<0) y=0;
if (x=x2) {
width=1;
x=x2=xc;
}
if(y>=y2) {
height=1;
y=y2=yc;
}
}
if (constrain) {
if(activeHandle==1 || activeHandle==5) width=height;
else height=width;
if(x>=x2) {
width=1;
x=x2=xc;
}
if (y>=y2) {
height=1;
y=y2=yc;
}
switch(activeHandle){
case 0:
x=x2-width;
y=y2-height;
break;
case 1:
x=xc-width/2;
y=y2-height;
break;
case 2:
y=y2-height;
break;
case 3:
y=yc-height/2;
break;
case 5:
x=xc-width/2;
break;
case 6:
x=x2-width;
break;
case 7:
y=yc-height/2;
x=x2-width;
break;
}
if (center){
x=xc-width/2;
y=yc-height/2;
}
}
if (aspect && !constrain) {
if(activeHandle==1 || activeHandle==5) width=(int)Math.rint((double)height*asp);
else height=(int)Math.rint((double)width/asp);
switch (activeHandle){
case 0:
x=x2-width;
y=y2-height;
break;
case 1:
x=xc-width/2;
y=y2-height;
break;
case 2:
y=y2-height;
break;
case 3:
y=yc-height/2;
break;
case 5:
x=xc-width/2;
break;
case 6:
x=x2-width;
break;
case 7:
y=yc-height/2;
x=x2-width;
break;
}
if (center){
x=xc-width/2;
y=yc-height/2;
}
// Attempt to preserve aspect ratio when roi very small:
if (width<8) {
if(width<1) width = 1;
height=(int)Math.rint((double)width/asp_bk);
}
if (height<8) {
if(height<1) height =1;
width=(int)Math.rint((double)height*asp_bk);
}
}
updateClipRect();
imp.draw(clipX, clipY, clipWidth, clipHeight);
oldX=x; oldY=y;
oldWidth=width; oldHeight=height;
cachedMask = null;
bounds = null;
}
public void draw(Graphics g) {
Color color = strokeColor!=null? strokeColor:ROIColor;
if (fillColor!=null) color = fillColor;
g.setColor(color);
mag = getMagnification();
int sw = (int)(width*mag);
int sh = (int)(height*mag);
int sx1 = screenX(x);
int sy1 = screenY(y);
if (subPixelResolution() && bounds!=null) {
sw = (int)(bounds.width*mag);
sh = (int)(bounds.height*mag);
sx1 = screenXD(bounds.x);
sy1 = screenYD(bounds.y);
}
int sw2 = (int)(0.14645*width*mag);
int sh2 = (int)(0.14645*height*mag);
int sx2 = sx1+sw/2;
int sy2 = sy1+sh/2;
int sx3 = sx1+sw;
int sy3 = sy1+sh;
Graphics2D g2d = (Graphics2D)g;
if (stroke!=null)
g2d.setStroke(getScaledStroke());
if (fillColor!=null) {
if (!overlay && isActiveOverlayRoi()) {
g.setColor(Color.cyan);
g.drawOval(sx1, sy1, sw, sh);
} else
g.fillOval(sx1, sy1, sw, sh);
} else
g.drawOval(sx1, sy1, sw, sh);
if (state!=CONSTRUCTING && clipboard==null && !overlay) {
int size2 = HANDLE_SIZE/2;
drawHandle(g, sx1+sw2-size2, sy1+sh2-size2);
drawHandle(g, sx3-sw2-size2, sy1+sh2-size2);
drawHandle(g, sx3-sw2-size2, sy3-sh2-size2);
drawHandle(g, sx1+sw2-size2, sy3-sh2-size2);
drawHandle(g, sx2-size2, sy1-size2);
drawHandle(g, sx3-size2, sy2-size2);
drawHandle(g, sx2-size2, sy3-size2);
drawHandle(g, sx1-size2, sy2-size2);
}
drawPreviousRoi(g);
if (updateFullWindow)
{updateFullWindow = false; imp.draw();}
if (state!=NORMAL) showStatus();
}
/** Draws an outline of this OvalRoi on the image. */
public void drawPixels(ImageProcessor ip) {
Polygon p = getPolygon();
if (p.npoints>0) {
int saveWidth = ip.getLineWidth();
if (getStrokeWidth()>1f)
ip.setLineWidth((int)Math.round(getStrokeWidth()));
ip.drawPolygon(p);
ip.setLineWidth(saveWidth);
}
if (Line.getWidth()>1 || getStrokeWidth()>1)
updateFullWindow = true;
}
/** Returns this OvalRoi as a Polygon. */
public Polygon getPolygon() {
ImageProcessor mask = getMask();
Wand wand = new Wand(mask);
wand.autoOutline(width/2,height/2, 255, 255);
for (int i=0; i=sx1+sw2&&sx<=sx1+sw2+size&&sy>=sy1+sh2&&sy<=sy1+sh2+size) return 0;
if (sx>=sx2&&sx<=sx2+size&&sy>=sy1&&sy<=sy1+size) return 1;
if (sx>=sx3-sw2&&sx<=sx3-sw2+size&&sy>=sy1+sh2&&sy<=sy1+sh2+size) return 2;
if (sx>=sx3&&sx<=sx3+size&&sy>=sy2&&sy<=sy2+size) return 3;
if (sx>=sx3-sw2&&sx<=sx3-sw2+size&&sy>=sy3-sh2&&sy<=sy3-sh2+size) return 4;
if (sx>=sx2&&sx<=sx2+size&&sy>=sy3&&sy<=sy3+size) return 5;
if (sx>=sx1+sw2&&sx<=sx1+sw2+size&&sy>=sy3-sh2&&sy<=sy3-sh2+size) return 6;
if (sx>=sx1&&sx<=sx1+size&&sy>=sy2&&sy<=sy2+size) return 7;
return -1;
}
public ImageProcessor getMask() {
if (cachedMask!=null && cachedMask.getPixels()!=null)
return cachedMask;
ImageProcessor mask = new ByteProcessor(width, height);
double a=width/2.0, b=height/2.0;
double a2=a*a, b2=b*b;
a -= 0.5; b -= 0.5;
double xx, yy;
int offset;
byte[] pixels = (byte[])mask.getPixels();
for (int y=0; y
Ads help maintain this website.