Squiz Matrix  4.12.2
 All Data Structures Namespaces Functions Variables Pages
OvalRoi.java
1 package ij.gui;
2 
3 import java.awt.*;
4 import java.awt.image.*;
5 import ij.*;
6 import ij.process.*;
7 import ij.measure.Calibration;
8 
10 public class OvalRoi extends Roi {
11 
13  public OvalRoi(int x, int y, int width, int height) {
14  super(x, y, width, height);
15  type = OVAL;
16  }
17 
19  public OvalRoi(int x, int y, ImagePlus imp) {
20  super(x, y, imp);
21  type = OVAL;
22  }
23 
25  public OvalRoi(int x, int y, int width, int height, ImagePlus imp) {
26  this(x, y, width, height);
27  setImage(imp);
28  }
29 
30  protected void moveHandle(int ox, int oy) {
31  if (clipboard!=null)
32  return;
33  //IJ.log("moveHandle: "+activeHandle+" "+ox+" "+oy);
34  int x1=x, y1=y, x2=x1+width, y2=y+height;
35  int w2 = (int)(0.14645*width);
36  int h2 = (int)(0.14645*height);
37  switch (activeHandle) {
38  case 0: x=ox-w2; y=oy-h2; break;
39  case 1: y=oy; break;
40  case 2: x2=ox+w2; y=oy-h2; break;
41  case 3: x2=ox; break;
42  case 4: x2=ox+w2; y2=oy+h2; break;
43  case 5: y2=oy; break;
44  case 6: x=ox-w2; y2=oy+h2; break;
45  case 7: x=ox; break;
46  }
47  if (x<0) x=0; if (y<0) y=0;
48  if (x<x2)
49  width=x2-x;
50  else
51  {width=1; x=x2;}
52  if (y<y2)
53  height = y2-y;
54  else
55  {height=1; y=y2;}
56  if (constrain)
57  height = width;
58  if ((x+width)>xMax) width=xMax-x;
59  if ((y+height)>yMax) height=yMax-y;
60  updateClipRect();
61  imp.draw(clipX, clipY, clipWidth, clipHeight);
62  oldX=x; oldY=y;
63  oldWidth=width; oldHeight=height;
64  cachedMask = null;
65  }
66 
67  public void draw(Graphics g) {
68  if (ic==null) return;
69  g.setColor(ROIColor);
70  mag = ic!=null?ic.getMagnification():1.0;
71  int sw = (int)(width*mag);
72  int sh = (int)(height*mag);
73  int sw2 = (int)(0.14645*width*mag);
74  int sh2 = (int)(0.14645*height*mag);
75  int sx1 = ic.screenX(x);
76  int sy1 = ic.screenY(y);
77  int sx2 = sx1+sw/2;
78  int sy2 = sy1+sh/2;
79  int sx3 = sx1+sw;
80  int sy3 = sy1+sh;
81  g.drawOval(sx1, sy1, sw, sh);
82  if (state!=CONSTRUCTING && clipboard==null) {
83  int size2 = HANDLE_SIZE/2;
84  drawHandle(g, sx1+sw2-size2, sy1+sh2-size2);
85  drawHandle(g, sx3-sw2-size2, sy1+sh2-size2);
86  drawHandle(g, sx3-sw2-size2, sy3-sh2-size2);
87  drawHandle(g, sx1+sw2-size2, sy3-sh2-size2);
88  drawHandle(g, sx2-size2, sy1-size2);
89  drawHandle(g, sx3-size2, sy2-size2);
90  drawHandle(g, sx2-size2, sy3-size2);
91  drawHandle(g, sx1-size2, sy2-size2);
92  }
93  drawPreviousRoi(g);
94  if (updateFullWindow)
95  {updateFullWindow = false; imp.draw();}
96  if (state!=NORMAL) showStatus();
97  }
98 
100  public void drawPixels() {
101  if (imp==null) return;
102  Polygon p = getPolygon();
103  ImageProcessor ip = imp.getProcessor();
104  ip.drawPolygon(p);
105  if (Line.getWidth()>1)
106  updateFullWindow = true;
107  }
108 
110  public Polygon getPolygon() {
111  ImageProcessor mask = getMask();
112  Wand wand = new Wand(mask);
113  wand.autoOutline(width/2,height/2, 255, 255);
114  for (int i=0; i<wand.npoints; i++) {
115  wand.xpoints[i] += x;
116  wand.ypoints[i] += y;
117  }
118  return new Polygon(wand.xpoints, wand.ypoints, wand.npoints);
119  }
120 
121  public boolean contains(int x, int y) {
122  // equation for an ellipse is x^2/a^2 + y^2/b^2 = 1
123  if (!super.contains(x, y))
124  return false;
125  else {
126  x = Math.abs(x - (this.x + width/2));
127  y = Math.abs(y - (this.y + height/2));
128  double a = width/2;
129  double b = height/2;
130  return (x*x/(a*a) + y*y/(b*b)) <= 1;
131  }
132  }
133 
136  public int isHandle(int sx, int sy) {
137  if (clipboard!=null || ic==null) return -1;
138  double mag = ic.getMagnification();
139  int size = HANDLE_SIZE+3;
140  int halfSize = size/2;
141  int sx1 = ic.screenX(x) - halfSize;
142  int sy1 = ic.screenY(y) - halfSize;
143  int sx3 = ic.screenX(x+width) - halfSize;
144  int sy3 = ic.screenY(y+height) - halfSize;
145  int sx2 = sx1 + (sx3 - sx1)/2;
146  int sy2 = sy1 + (sy3 - sy1)/2;
147 
148  int sw2 = (int)(0.14645*(sx3-sx1));
149  int sh2 = (int)(0.14645*(sy3-sy1));
150 
151  if (sx>=sx1+sw2&&sx<=sx1+sw2+size&&sy>=sy1+sh2&&sy<=sy1+sh2+size) return 0;
152  if (sx>=sx2&&sx<=sx2+size&&sy>=sy1&&sy<=sy1+size) return 1;
153  if (sx>=sx3-sw2&&sx<=sx3-sw2+size&&sy>=sy1+sh2&&sy<=sy1+sh2+size) return 2;
154  if (sx>=sx3&&sx<=sx3+size&&sy>=sy2&&sy<=sy2+size) return 3;
155  if (sx>=sx3-sw2&&sx<=sx3-sw2+size&&sy>=sy3-sh2&&sy<=sy3-sh2+size) return 4;
156  if (sx>=sx2&&sx<=sx2+size&&sy>=sy3&&sy<=sy3+size) return 5;
157  if (sx>=sx1+sw2&&sx<=sx1+sw2+size&&sy>=sy3-sh2&&sy<=sy3-sh2+size) return 6;
158  if (sx>=sx1&&sx<=sx1+size&&sy>=sy2&&sy<=sy2+size) return 7;
159  return -1;
160  }
161 
162  public ImageProcessor getMask() {
163  if (cachedMask!=null)
164  return cachedMask;
165  ImageProcessor mask = new ByteProcessor(width, height);
166  double a=width/2.0, b=height/2.0;
167  double a2=a*a, b2=b*b;
168  a -= 0.5; b -= 0.5;
169  double xx, yy;
170  int offset;
171  byte[] pixels = (byte[])mask.getPixels();
172  for (int y=0; y<height; y++) {
173  offset = y*width;
174  for (int x=0; x<width; x++) {
175  xx = x - a;
176  yy = y - b;
177  if ((xx*xx/a2+yy*yy/b2)<=1.0)
178  pixels[offset+x] = -1;
179  }
180  }
181  cachedMask = mask;
182  return mask;
183  }
184 
186  public double getLength() {
187  double pw=1.0, ph=1.0;
188  if (imp!=null) {
189  Calibration cal = imp.getCalibration();
190  pw = cal.pixelWidth;
191  ph = cal.pixelHeight;
192  }
193  return Math.PI*(width*pw+height*ph)/2.0;
194  }
195 
198  public double getFeretsDiameter() {
199  double pw=1.0, ph=1.0;
200  if (imp!=null) {
201  Calibration cal = imp.getCalibration();
202  pw = cal.pixelWidth;
203  ph = cal.pixelHeight;
204  }
205  return width*pw>=height*ph?width*pw:height*ph;
206  }
207 
208 }