
ij.gui.PolygonRoi Maven / Gradle / Ivy
Go to download
ImageJ is an open source Java image processing program inspired by NIH Image for the Macintosh.
package ij.gui;
import ij.*;
import ij.process.*;
import ij.measure.*;
import ij.plugin.frame.*;
import java.awt.*;
import java.awt.image.*;
import java.awt.geom.*;
import java.awt.event.*;
/** This class represents a polygon region of interest or polyline of interest. */
public class PolygonRoi extends Roi {
protected int maxPoints = 1000; // will be increased if necessary
protected int[] xp, yp; // image coordinates relative to origin of roi bounding box
protected float[] xpf, ypf; // or alternative sub-pixel coordinates
protected int[] xp2, yp2; // absolute screen coordinates
protected int nPoints;
protected float[] xSpline,ySpline; // relative image coordinates
protected int splinePoints = 200;
Rectangle clip;
private double angle1, degrees=Double.NaN;
private int xClipMin, yClipMin, xClipMax, yClipMax;
private boolean userCreated;
private boolean subPixel;
private boolean drawOffset;
long mouseUpTime = 0;
/** Creates a new polygon or polyline ROI from x and y coordinate arrays.
Type must be Roi.POLYGON, Roi.FREEROI, Roi.TRACED_ROI, Roi.POLYLINE, Roi.FREELINE or Roi.ANGLE.*/
public PolygonRoi(int[] xPoints, int[] yPoints, int nPoints, int type) {
super(0, 0, null);
init1(nPoints, type);
xp = xPoints;
yp = yPoints;
if (type!=TRACED_ROI) {
xp = new int[nPoints];
yp = new int[nPoints];
for (int i=0; i1 && isLine())
updateWideLine(lineWidth);
finishPolygon();
}
/** Creates a new polygon or polyline ROI from a Polygon. Type must be Roi.POLYGON,
Roi.FREEROI, Roi.TRACED_ROI, Roi.POLYLINE, Roi.FREELINE or Roi.ANGLE.*/
public PolygonRoi(Polygon p, int type) {
this(p.xpoints, p.ypoints, p.npoints, type);
}
/** Creates a new polygon or polyline ROI from a FloatPolygon. Type must be Roi.POLYGON,
Roi.FREEROI, Roi.TRACED_ROI, Roi.POLYLINE, Roi.FREELINE or Roi.ANGLE.*/
public PolygonRoi(FloatPolygon p, int type) {
this(p.xpoints, p.ypoints, p.npoints, type);
}
/** @deprecated */
public PolygonRoi(int[] xPoints, int[] yPoints, int nPoints, ImagePlus imp, int type) {
this(xPoints, yPoints, nPoints, type);
setImage(imp);
}
/** Starts the process of creating a new user-generated polygon or polyline ROI. */
public PolygonRoi(int sx, int sy, ImagePlus imp) {
super(sx, sy, imp);
int tool = Toolbar.getToolId();
switch (tool) {
case Toolbar.POLYGON:
type = POLYGON;
break;
case Toolbar.FREEROI:
type = FREEROI;
break;
case Toolbar.FREELINE:
type = FREELINE;
if (Prefs.subPixelResolution)
subPixel = true;
break;
case Toolbar.ANGLE:
type = ANGLE;
break;
default:
type = POLYLINE;
if (Prefs.subPixelResolution)
subPixel = true;
break;
}
if (this instanceof EllipseRoi)
subPixel = true;
x = ic.offScreenX(sx);
y = ic.offScreenY(sy);
startXD = subPixelResolution()?ic.offScreenXD(sx):x;
startYD = subPixelResolution()?ic.offScreenYD(sy):y;
if (subPixelResolution()) {
setLocation(ic.offScreenXD(sx), ic.offScreenYD(sy));
xpf = new float[maxPoints];
ypf = new float[maxPoints];
double xbase = getXBase();
double ybase = getYBase();
xpf[0] = (float)(startXD-xbase);
ypf[0] = (float)(startYD-ybase);
xpf[1] = xpf[0];
ypf[1] = ypf[0];
} else {
xp = new int[maxPoints];
yp = new int[maxPoints];
}
xp2 = new int[maxPoints];
yp2 = new int[maxPoints];
nPoints = 2;
width=1;
height=1;
clipX = x;
clipY = y;
clipWidth = 1;
clipHeight = 1;
state = CONSTRUCTING;
userCreated = true;
if (lineWidth>1 && isLine())
updateWideLine(lineWidth);
drawOffset = subPixelResolution();
}
private void drawStartBox(Graphics g) {
if (type!=ANGLE) {
double offset = getOffset(0.5);
g.drawRect(ic.screenXD(startXD+offset)-4, ic.screenYD(startYD+offset)-4, 8, 8);
}
}
public void draw(Graphics g) {
updatePolygon();
Color color = strokeColor!=null?strokeColor:ROIColor;
boolean hasHandles = xSpline!=null||type==POLYGON||type==POLYLINE||type==ANGLE;
boolean isActiveOverlayRoi = !overlay && isActiveOverlayRoi();
if (isActiveOverlayRoi && !hasHandles) {
if (color==Color.cyan)
color = Color.magenta;
else
color = Color.cyan;
}
boolean fill = false;
mag = getMagnification();
if (fillColor!=null && !isLine() && state!=CONSTRUCTING) {
color = fillColor;
fill = true;
}
g.setColor(color);
Graphics2D g2d = (Graphics2D)g;
if (stroke!=null && !isActiveOverlayRoi)
g2d.setStroke(getScaledStroke());
if (xSpline!=null) {
if (type==POLYLINE || type==FREELINE) {
drawSpline(g, xSpline, ySpline, splinePoints, false, fill, isActiveOverlayRoi);
if (wideLine && !overlay) {
g2d.setStroke(onePixelWide);
g.setColor(getColor());
drawSpline(g, xSpline, ySpline, splinePoints, false, fill, isActiveOverlayRoi);
}
} else
drawSpline(g, xSpline, ySpline, splinePoints, true, fill, isActiveOverlayRoi);
} else {
if (type==POLYLINE || type==FREELINE || type==ANGLE || state==CONSTRUCTING) {
g.drawPolyline(xp2, yp2, nPoints);
if (wideLine && !overlay) {
g2d.setStroke(onePixelWide);
g.setColor(getColor());
g.drawPolyline(xp2, yp2, nPoints);
}
} else {
if (fill) {
if (isActiveOverlayRoi) {
g.setColor(Color.cyan);
g.drawPolygon(xp2, yp2, nPoints);
} else
g.fillPolygon(xp2, yp2, nPoints);
} else
g.drawPolygon(xp2, yp2, nPoints);
}
if (state==CONSTRUCTING && type!=FREEROI && type!=FREELINE)
drawStartBox(g);
}
if (hasHandles && clipboard==null && !overlay) {
int size2 = HANDLE_SIZE/2;
if (activeHandle>0)
drawHandle(g, xp2[activeHandle-1]-size2, yp2[activeHandle-1]-size2);
if (activeHandle1f)
ip.setLineWidth((int)Math.round(getStrokeWidth()));
double xbase = getXBase();
double ybase = getYBase();
if (xSpline!=null) {
ip.moveTo((int)Math.round(xbase+xSpline[0]), (int)Math.round(ybase+ySpline[0]));
for (int i=1; i1) {
double x1, y1, x2, y2;
if (xpf!=null) {
x1 = xpf[nPoints-2];
y1 = ypf[nPoints-2];
x2 = xpf[nPoints-1];
y2 = ypf[nPoints-1];
} else {
x1 = xp[nPoints-2];
y1 = yp[nPoints-2];
x2 = xp[nPoints-1];
y2 = yp[nPoints-1];
}
degrees = getAngle((int)Math.round(x1), (int)Math.round(y1), (int)Math.round(x2), (int)Math.round(y2));
if (tool!=Toolbar.ANGLE) {
Calibration cal = imp.getCalibration();
double pw=cal.pixelWidth, ph=cal.pixelHeight;
if (IJ.altKeyDown()) {pw=1.0; ph=1.0;}
len = Math.sqrt((x2-x1)*pw*(x2-x1)*pw + (y2-y1)*ph*(y2-y1)*ph);
}
}
if (tool==Toolbar.ANGLE) {
if (nPoints==2)
angle1 = degrees;
else if (nPoints==3) {
double angle2 = getAngle(xp[1], yp[1], xp[2], yp[2]);
degrees = Math.abs(180-Math.abs(angle1-angle2));
if (degrees>180.0)
degrees = 360.0-degrees;
}
}
String length = len!=-1?", length=" + IJ.d2s(len):"";
double degrees2 = tool==Toolbar.ANGLE&&nPoints==3&&Prefs.reflexAngle?360.0-degrees:degrees;
String angle = !Double.isNaN(degrees)?", angle=" + IJ.d2s(degrees2):"";
int ox = ic!=null?ic.offScreenX(sx):sx;
int oy = ic!=null?ic.offScreenY(sy):sy;
IJ.showStatus(imp.getLocationAsString(ox,oy) + length + angle);
}
void drawRubberBand(int sx, int sy) {
double oxd = ic!=null?ic.offScreenXD(sx):sx;
double oyd = ic!=null?ic.offScreenYD(sy):sy;
int ox = (int)oxd;
int oy = (int)oyd;
int x1, y1, x2, y2;
if (xpf!=null) {
x1 = (int)xpf[nPoints-2]+x;
y1 = (int)ypf[nPoints-2]+y;
x2 = (int)xpf[nPoints-1]+x;
y2 = (int)ypf[nPoints-1]+y;
} else {
x1 = xp[nPoints-2]+x;
y1 = yp[nPoints-2]+y;
x2 = xp[nPoints-1]+x;
y2 = yp[nPoints-1]+y;
}
int xmin=Integer.MAX_VALUE, ymin=Integer.MAX_VALUE, xmax=0, ymax=0;
if (x1xmax) xmax=x1;
if (x2>xmax) xmax=x2;
if (ox>xmax) xmax=ox;
if (y1ymax) ymax=y1;
if (y2>ymax) ymax=y2;
if (oy>ymax) ymax=oy;
//clip = new Rectangle(xmin, ymin, xmax-xmin, ymax-ymin);
int margin = 4;
if (ic!=null) {
double mag = ic.getMagnification();
if (mag<1.0) margin = (int)(margin/mag);
}
margin = (int)(margin+getStrokeWidth());
if (xpf!=null) {
xpf[nPoints-1] = (float)(oxd-getXBase());
ypf[nPoints-1] = (float)(oyd-getYBase());
} else {
xp[nPoints-1] = ox-x;
yp[nPoints-1] = oy-y;
}
if (type==POLYLINE && subPixelResolution()) {
fitSpline();
imp.draw();
} else
imp.draw(xmin-margin, ymin-margin, (xmax-xmin)+margin*2, (ymax-ymin)+margin*2);
}
void finishPolygon() {
if (xpf!=null) {
float xbase0 = (float)getXBase();
float ybase0 = (float)getYBase();
FloatPolygon poly = new FloatPolygon(xpf, ypf, nPoints);
Rectangle r = poly.getBounds();
x = r.x;
y = r.y;
width = r.width;
height = r.height;
bounds = poly.getFloatBounds();
float xbase = (float)bounds.getX();
float ybase = (float)bounds.getY();
for (int i=0; i1 && isLine()) || ignoreClipRect)
imp.draw();
else
imp.draw(clipX, clipY, clipWidth, clipHeight);
oldX = x;
oldY = y;
oldWidth = width;
oldHeight=height;
}
*/
protected void moveHandle(int sx, int sy) {
if (clipboard!=null) return;
int ox = ic.offScreenX(sx);
int oy = ic.offScreenY(sy);
if (xpf!=null) {
double offset = getOffset(-0.5);
double xbase = getXBase();
double ybase = getYBase();
xpf[activeHandle] = (float)(ic.offScreenXD(sx)-xbase+offset);
ypf[activeHandle] = (float)(ic.offScreenYD(sy)-ybase+offset);
} else {
xp[activeHandle] = ox-x;
yp[activeHandle] = oy-y;
}
if (xSpline!=null) {
fitSpline(splinePoints);
imp.draw();
} else {
if (!subPixelResolution())
resetBoundingRect();
if (type==POINT && width==0 && height==0)
{width=1; height=1;}
updateClipRectAndDraw();
}
String angle = type==ANGLE?getAngleAsString():"";
IJ.showStatus(imp.getLocationAsString(ox,oy) + angle);
}
/** After handle is moved, find clip rect and repaint. */
void updateClipRectAndDraw() {
if (xpf!=null) {
xp = toInt(xpf, xp, nPoints);
yp = toInt(ypf, yp, nPoints);
}
int xmin=Integer.MAX_VALUE, ymin=Integer.MAX_VALUE, xmax=0, ymax=0;
int x2, y2;
if (activeHandle>0)
{x2=x+xp[activeHandle-1]; y2=y+yp[activeHandle-1];}
else
{x2=x+xp[nPoints-1]; y2=y+yp[nPoints-1];}
if (x2xmax) xmax = x2;
if (y2>ymax) ymax = y2;
x2=x+xp[activeHandle]; y2=y+yp[activeHandle];
if (x2xmax) xmax = x2;
if (y2>ymax) ymax = y2;
if (activeHandlexmax) xmax = x2;
if (y2>ymax) ymax = y2;
int xmin2=xmin, ymin2=ymin, xmax2=xmax, ymax2=ymax;
if (xClipMinxmax2) xmax2 = xClipMax;
if (yClipMax>ymax2) ymax2 = yClipMax;
xClipMin=xmin; yClipMin=ymin; xClipMax=xmax; yClipMax=ymax;
double mag = ic.getMagnification();
int handleSize = type==POINT?HANDLE_SIZE+12:HANDLE_SIZE;
double strokeWidth = getStrokeWidth();
if (strokeWidth<1.0) strokeWidth=1.0;
if (handleSizexmax) xmax=xx;
yy = yp[i];
if (yyymax) ymax=yy;
}
if (xmin!=0) {
for (int i=0; i180.0)
degrees = 360.0-degrees;
double degrees2 = Prefs.reflexAngle&&type==ANGLE?360.0-degrees:degrees;
return ", angle=" + IJ.d2s(degrees2);
}
protected void mouseDownInHandle(int handle, int sx, int sy) {
if (state==CONSTRUCTING)
return;
int ox=ic.offScreenX(sx), oy=ic.offScreenY(sy);
double oxd=ic.offScreenXD(sx), oyd=ic.offScreenYD(sy);
if (IJ.altKeyDown() && !(nPoints<=3 && type!=POINT)) {
deleteHandle(oxd, oyd);
return;
} else if (IJ.shiftKeyDown() && type!=POINT) {
addHandle(oxd, oyd);
return;
}
state = MOVING_HANDLE;
activeHandle = handle;
int m = (int)(10.0/ic.getMagnification());
xClipMin=ox-m; yClipMin=oy-m; xClipMax=ox+m; yClipMax=oy+m;
}
public void deleteHandle(double ox, double oy) {
if (imp==null) return;
if (nPoints<=1)
{imp.deleteRoi(); return;}
boolean splineFit = xSpline != null;
xSpline = null;
FloatPolygon points = getFloatPolygon();
modState = NO_MODS;
if (previousRoi!=null) previousRoi.modState = NO_MODS;
int pointToDelete = getClosestPoint(ox, oy, points);
FloatPolygon points2 = new FloatPolygon();
for (int i=0; ixmax) xmax=xs;
xSpline[i] = xs;
ys = (float)sfy.evalSpline(xvalue);
if (ysymax) ymax=ys;
ySpline[i] = ys;
}
cachedMask = null;
// update protected xp and yp arrays for backward compatibility
xp = toInt(xpf, xp, nPoints);
yp = toInt(ypf, yp, nPoints);
if (state==NORMAL)
resetBoundingRect();
}
public void fitSpline() {
double length = getUncalibratedLength();
int evaluationPoints = (int)(length/2.0);
if (ic!=null) {
double mag = ic.getMagnification();
if (mag<1.0)
evaluationPoints *= mag;;
}
if (evaluationPoints<100)
evaluationPoints = 100;
fitSpline(evaluationPoints);
}
public void removeSplineFit() {
xSpline = null;
ySpline = null;
}
/** Returns 'true' if this selection has been fitted with a spline. */
public boolean isSplineFit() {
return xSpline!=null;
}
/* Creates a spline fitted polygon with one pixel segment lengths
that can be retrieved using the getFloatPolygon() method. */
public void fitSplineForStraightening() {
fitSpline((int)getUncalibratedLength()*2);
if (xSpline==null || splinePoints==0) return;
float[] xpoints = new float[splinePoints*2];
float[] ypoints = new float[splinePoints*2];
xpoints[0] = xSpline[0];
ypoints[0] = ySpline[0];
int n=1, n2;
double inc = 0.01;
double distance=0.0, distance2=0.0, dx=0.0, dy=0.0, xinc, yinc;
double x, y, lastx, lasty, x1, y1, x2=xSpline[0], y2=ySpline[0];
for (int i=1; i=1.0-inc/2.0 && n0);
}
xSpline = xpoints;
ySpline = ypoints;
splinePoints = n;
//IJ.log("xSpline="+xSpline+" splinePoints="+splinePoints);
}
public double getUncalibratedLength() {
ImagePlus saveImp = imp;
imp = null;
double length = getLength();
imp = saveImp;
return length;
}
/** With segmented selections, ignore first mouse up and finalize
when user double-clicks, control-clicks or clicks in start box. */
protected void handleMouseUp(int sx, int sy) {
if (state==MOVING) {
state = NORMAL;
return;
}
if (state==MOVING_HANDLE) {
cachedMask = null; //mask is no longer valid
state = NORMAL;
updateClipRect();
oldX=x; oldY=y;
oldWidth=width; oldHeight=height;
if (subPixelResolution())
resetBoundingRect();
return;
}
if (state!=CONSTRUCTING)
return;
if (IJ.spaceBarDown()) // is user scrolling image?
return;
boolean samePoint = false;
if (xpf!=null)
samePoint = (xpf[nPoints-2]==xpf[nPoints-1] && ypf[nPoints-2]==ypf[nPoints-1]);
else
samePoint = (xp[nPoints-2]==xp[nPoints-1] && yp[nPoints-2]==yp[nPoints-1]);
Rectangle biggerStartBox = new Rectangle(ic.screenXD(startXD)-5, ic.screenYD(startYD)-5, 10, 10);
if (nPoints>2 && (biggerStartBox.contains(sx, sy)
|| (ic.offScreenXD(sx)==startXD && ic.offScreenYD(sy)==startYD)
|| (samePoint && (System.currentTimeMillis()-mouseUpTime)<=500))) {
nPoints--;
addOffset();
finishPolygon();
return;
} else if (!samePoint) {
mouseUpTime = System.currentTimeMillis();
if (type==ANGLE && nPoints==3) {
addOffset();
finishPolygon();
return;
}
//add point to polygon
if (xpf!=null) {
xpf[nPoints] = xpf[nPoints-1];
ypf[nPoints] = ypf[nPoints-1];
nPoints++;
if (nPoints==xpf.length)
enlargeArrays();
} else {
xp[nPoints] = xp[nPoints-1];
yp[nPoints] = yp[nPoints-1];
nPoints++;
if (nPoints==xp.length)
enlargeArrays();
}
//if (lineWidth>1) fitSpline();
}
}
protected void addOffset() {
if (xpf!=null) {
double xbase = getXBase();
double ybase = getYBase();
for (int i=0; i=sx2 && sx<=sx2+size && sy>=sy2 && sy<=sy2+size) {
handle = i;
break;
}
}
return handle;
}
/** Override Roi.nudge() to support splines. */
//public void nudge(int key) {
// super.nudge(key);
// if (xSpline!=null) {
// fitSpline();
// updateFullWindow = true;
// imp.draw();
// }
//}
public ImageProcessor getMask() {
if (cachedMask!=null && cachedMask.getPixels()!=null
&& cachedMask.getWidth()==width && cachedMask.getHeight()==height)
return cachedMask;
PolygonFiller pf = new PolygonFiller();
if (xSpline!=null)
pf.setPolygon(toIntR(xSpline), toIntR(ySpline), splinePoints);
else if (xpf!=null)
pf.setPolygon(toIntR(xpf), toIntR(ypf), nPoints);
else
pf.setPolygon(xp, yp, nPoints);
cachedMask = pf.getMask(width, height);
return cachedMask;
}
/** Returns the length of this line selection after
smoothing using a 3-point running average.*/
double getSmoothedLineLength() {
if (subPixelResolution() && xpf!=null)
return getFloatSmoothedLineLength();
double length = 0.0;
double w2 = 1.0;
double h2 = 1.0;
double dx, dy;
if (imp!=null) {
Calibration cal = imp.getCalibration();
w2 = cal.pixelWidth*cal.pixelWidth;
h2 = cal.pixelHeight*cal.pixelHeight;
}
dx = (xp[0]+xp[1]+xp[2])/3.0-xp[0];
dy = (yp[0]+yp[1]+yp[2])/3.0-yp[0];
length += Math.sqrt(dx*dx*w2+dy*dy*h2);
for (int i=1; i1 || !corner) {
corner = true;
nCorners++;
} else
corner = false;
dx1 = dx2;
dy1 = dy2;
side1 = side2;
}
double w=1.0,h=1.0;
if (imp!=null) {
Calibration cal = imp.getCalibration();
w = cal.pixelWidth;
h = cal.pixelHeight;
}
return sumdx*w+sumdy*h-(nCorners*((w+h)-Math.sqrt(w*w+h*h)));
}
/** Returns the perimeter (for ROIs) or length (for lines).*/
public double getLength() {
if (type==TRACED_ROI)
return getTracedPerimeter();
if (nPoints>2) {
if (type==FREEROI)
return getSmoothedPerimeter();
else if (type==FREELINE && !(width==0 || height==0))
return getSmoothedLineLength();
}
double length = 0.0;
int dx, dy;
double w2=1.0, h2=1.0;
if (imp!=null) {
Calibration cal = imp.getCalibration();
w2 = cal.pixelWidth*cal.pixelWidth;
h2 = cal.pixelHeight*cal.pixelHeight;
}
if (xSpline!=null) {
double fdx, fdy;
for (int i=0; i<(splinePoints-1); i++) {
fdx = xSpline[i+1]-xSpline[i];
fdy = ySpline[i+1]-ySpline[i];
length += Math.sqrt(fdx*fdx*w2+fdy*fdy*h2);
}
if (type==POLYGON) {
fdx = xSpline[0]-xSpline[splinePoints-1];
fdy = ySpline[0]-ySpline[splinePoints-1];
length += Math.sqrt(fdx*fdx*w2+fdy*fdy*h2);
}
} else if (xpf!=null) {
double fdx, fdy;
for (int i=0; i<(nPoints-1); i++) {
fdx = xpf[i+1]-xpf[i];
fdy = ypf[i+1]-ypf[i];
length += Math.sqrt(fdx*fdx*w2+fdy*fdy*h2);
}
if (type==POLYGON) {
fdx = xpf[0]-xpf[nPoints-1];
fdy = ypf[0]-ypf[nPoints-1];
length += Math.sqrt(fdx*fdx*w2+fdy*fdy*h2);
}
} else {
for (int i=0; i<(nPoints-1); i++) {
dx = xp[i+1]-xp[i];
dy = yp[i+1]-yp[i];
length += Math.sqrt(dx*dx*w2+dy*dy*h2);
}
if (type==POLYGON) {
dx = xp[0]-xp[nPoints-1];
dy = yp[0]-yp[nPoints-1];
length += Math.sqrt(dx*dx*w2+dy*dy*h2);
}
}
return length;
}
/** Returns the angle in degrees between the first two segments of this polyline.*/
public double getAngle() {
return degrees;
}
/** Returns the number of XY coordinates. */
public int getNCoordinates() {
if (xSpline!=null)
return splinePoints;
else
return nPoints;
}
/** Obsolete; replaced by either getPolygon() or getFloatPolygon(). */
public int[] getXCoordinates() {
if (xSpline!=null)
return toIntR(xSpline);
else if (xpf!=null)
return toIntR(xpf);
else
return xp;
}
/** Obsolete; replaced by either getPolygon() or getFloatPolygon(). */
public int[] getYCoordinates() {
if (xSpline!=null)
return toIntR(ySpline);
else if (ypf!=null)
return toIntR(ypf);
else
return yp;
}
public Polygon getNonSplineCoordinates() {
if (xpf!=null)
return new Polygon(toIntR(xpf), toIntR(ypf), nPoints);
else
return new Polygon(xp, yp, nPoints);
}
public FloatPolygon getNonSplineFloatPolygon() {
if (xpf!=null) {
FloatPolygon p = (new FloatPolygon(xpf, ypf, nPoints)).duplicate();
float xbase = (float)getXBase();
float ybase = (float)getYBase();
for (int i=0; i0)
{x2=x3; y2=y3; p2=p3;}
p3 += 1;
if (p3==n) p3 = 0;
} while (p3!=p1);
if (n210) return null;
}
p1 = p2;
} while (p1!=pstart);
return new Polygon(xx, yy, n2);
}
public FloatPolygon getInterpolatedPolygon(double interval, boolean smooth) {
FloatPolygon p = getFloatPolygon();
if (smooth && (type==TRACED_ROI || type==FREEROI || type==FREELINE)) {
for (int i=1; i "+newSize);
maxPoints = newSize;
}
private double getOffset(double value) {
return getDrawOffset()&&getMagnification()>1.0?value:0.0;
}
public boolean getDrawOffset() {
return drawOffset;
}
public void setDrawOffset(boolean drawOffset) {
this.drawOffset = drawOffset && subPixelResolution();
}
public void setLocation(double x, double y) {
super.setLocation(x, y);
if ((int)x!=x || (int)y!=y) {
subPixel = true;
if (xpf==null && xp!=null) {
xpf = toFloat(xp);
ypf = toFloat(yp);
}
}
}
public void enableSubPixelResolution() {
super.enableSubPixelResolution();
if (xpf==null) {
xpf = toFloat(xp);
ypf = toFloat(yp);
}
}
public String getDebugInfo() {
String s = "ROI Debug Properties\n";
s += " bounds: "+bounds+"\n";
s += " x,y,w,h: "+x+","+y+","+width+","+height+"\n";
if (xpf!=null && xpf.length>0)
s += " xpf[0],ypf[0]: "+xpf[0]+","+ypf[0]+"\n";
return s;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy