Inheritance diagram for CanvasChain::

Public Methods | |
| CanvasChain (int[] chain, double x, double y) | |
| CanvasChain (int[] chain, double x, double y, Color color) | |
| CanvasChain (int[] chain, double x, double y, Color color, boolean stroke, float linew, float trans, double ccs_scale) | |
| void | draw (Graphics g) | 
| Draw CanvasObject on 'g', using internal CCS values. More... | |
| Object | clone () | 
| Return an identical copy of this CanvasObject. More... | |
| boolean | isInside (double x, double y) | 
| boolean | isNear (double x, double y) | 
| void | setDimension (double w, double h) | 
| Resize CanvasObject to width 'w' and height 'h'. More... | |
| void | doPixelFit (double zoomFactor) | 
| Round internal ICS values to nearest natural number. More... | |
| void | doMove (double w, double h) | 
| Move CanvasObject 'w' positions in x-direction, and 'h' posi- tions in y-direction. More... | |
| void | setColor (Color newColor) | 
| double | getFirstX () | 
| double | getFirstY () | 
| double[] | getXPoints () | 
| double[] | getYPoints () | 
| int | getNrPoints () | 
| int[] | getChain () | 
| boolean | isCircular () | 
| void | setCircular (boolean b) | 
| boolean | isInsideCcs (int x, int y) | 
| To be removed. More... | |
| boolean | isNearCcs (int x, int y) | 
| To be removed. More... | |
| void | setDimension (int w, int h) | 
| void | doMove (int w, int h) | 
| int | changePoint (int index, int x, int y) | 
Protected Methods | |
| void | initChain (int[] chain, double x, double y) | 
| void | transformICStoCCS () | 
| Perform a full ICS to CCS coordinate transformation. More... | |
| void | makeFreemanPoly (double x, double y, int[] chain) | 
| void | makePixelChain () | 
| void | setBox () | 
Protected Attributes | |
| int[] | freeman = null | 
| double[] | ics_xPoints = null | 
| double[] | ics_yPoints = null | 
| Polygon | ccs_poly = null | 
| boolean | circular = false | 
| Image | image = null | 
      
  | 
  ||||||||||||||||
| 
 
 
  | 
  
      
  | 
  ||||||||||||||||||||
| 
 
 
  | 
  
      
  | 
  ||||||||||||||||||||||||||||||||||||
| 
 
 
  | 
  
      
  | 
  
| 
 Draw CanvasObject on 'g', using internal CCS values. 
 Reimplemented from CanvasObject. 
 00057     {
00058         if (!getTransformOK()) {
00059             transformICStoCCS();
00060         }
00061 
00062         if (ccs_poly != null) {
00063             setupDrawMode(g);
00064             int shift = (int)getZoomFactor();
00065             int half  = (int)(getZoomFactor()/2);
00066             g.drawImage(image, getX1Ccs() - half, getY1Ccs() - half,
00067                                getWidthCcs()+shift, getHeightCcs()+shift, null);
00068             g.setColor(new Color(drawColor.getRGB() ^ 0xFFFFFFFF));
00069             g.drawPolyline(ccs_poly.xpoints,
00070                            ccs_poly.ypoints, ccs_poly.npoints);
00071         }
00072     }
 | 
  
      
  | 
  
| 
 Return an identical copy of this CanvasObject. 
 Reimplemented from CanvasObject. 
 00076     {
00077         Color color = drawColor;
00078         if (hasNoColor) {
00079             color = NO_COLOR;
00080         }
00081         return (new CanvasChain(freeman, ics_xPoints[0], ics_yPoints[0],
00082                                 color, strokeSet, lineWidth,
00083                                 transparency, getZoomFactor()));
00084     }
 | 
  
      
  | 
  ||||||||||||
| 
 
 
 00088     {
00089         if (circular) {
00090             double[] ics_vals = { x, y };
00091             int[]    ccs_vals = Converter.ICStoCCS(ics_vals, getZoomFactor());
00092 
00093             if (!getTransformOK()) {
00094                 transformICStoCCS();
00095             }
00096 
00097             return (ccs_poly.contains(ccs_vals[0], ccs_vals[1]));
00098         }
00099         return false;
00100     }
 | 
  
      
  | 
  ||||||||||||
| 
 
 
 00104     {
00105         // adapted from 'Graphics Gems II' - James Arvo,
00106         // chap. 1.3, 'Distance from a point to a line', pages 10-13.
00107 
00108 
00109         // check if inside enlarged bounding box (== box + SPHERE)
00110 
00111         if (!((x >= getX1() - SPHERE) && (x < getX1() + getWidth() + SPHERE) &&
00112               (y >= getY1() - SPHERE) && (y < getY1() + getHeight() + SPHERE))) {
00113             return false;
00114         }
00115 
00116 
00117         // we are inside the box, now check each line of the polygon
00118 
00119         double min_x, min_y, max_x, max_y;
00120         double area, abs1, abs2, distance;
00121 
00122         for (int i=0, j=1; i<ics_xPoints.length; i++, j++) {
00123 
00124             if (j == ics_xPoints.length) {
00125                 if (!circular) {
00126                     break;
00127                 }
00128                 j = 0;
00129             }
00130 
00131             min_x = Math.min(ics_xPoints[i], ics_xPoints[j]);
00132             min_y = Math.min(ics_yPoints[i], ics_yPoints[j]);
00133             max_x = Math.max(ics_xPoints[i], ics_xPoints[j]);
00134             max_y = Math.max(ics_yPoints[i], ics_yPoints[j]);
00135 
00136 
00137             // check if inside enlarged bounding box of line
00138 
00139             if ((x >= min_x - SPHERE) && (x < max_x + SPHERE) &&
00140                 (y >= min_y - SPHERE) && (y < max_y + SPHERE)) {
00141 
00142 
00143                 // calculate the area of the triangle formed by the two
00144                 // CanvasPolyline points and the 'check' point
00145 
00146                 area = (y - ics_yPoints[i])*
00147                        (ics_xPoints[j] - ics_xPoints[i]) -
00148                        (x - ics_xPoints[i])*
00149                        (ics_yPoints[j] - ics_yPoints[i]);
00150 
00151 
00152                 // calculate approximation of distance perpendicular to
00153                 // CanvasLine
00154 
00155 
00156                 abs1 = Math.abs(ics_xPoints[j] - ics_xPoints[i]);
00157                 abs2 = Math.abs(ics_yPoints[j] - ics_yPoints[i]);
00158 
00159                 distance = (int)(Math.abs(area) /
00160                            (abs1 + abs2 - 0.5 * Math.min(abs1, abs2)));
00161 
00162 
00163                 // this approximation can also be used as an
00164                 // approximation for the 'true' distance
00165 
00166                 if (distance <= SPHERE) {
00167                     return true;
00168                 }
00169             }
00170         }
00171         return false;
00172     }
 | 
  
      
  | 
  ||||||||||||
| 
 Resize CanvasObject to width 'w' and height 'h'. Parameters are assumed Image Coordinate System values. Reimplemented from ScribbleObject. 
 00176     {
00177         // overrule super.setDimension(w, h), and do nothing
00178 
00179         return;
00180     }
 | 
  
      
  | 
  
| 
 Round internal ICS values to nearest natural number. Although the ICS values are changed, they are not converted to 'integer' internally. Reimplemented from ScribbleObject. 
 00184     {
00185         super.doPixelFit(zoomFactor);
00186 
00187         // Round ICS values of polyline...
00188 
00189         for (int i=0; i < ics_xPoints.length; i++) {
00190             ics_xPoints[i] = Math.round(ics_xPoints[i]);
00191             ics_yPoints[i] = Math.round(ics_yPoints[i]);
00192         }
00193 
00194         setTransformOK(false);
00195     }
 | 
  
      
  | 
  ||||||||||||
| 
 Move CanvasObject 'w' positions in x-direction, and 'h' posi- tions in y-direction. Parameters are assumed Image Coordinate System values. Reimplemented from ScribbleObject. 
 00199     {
00200         super.doMove(w, h);
00201 
00202         for (int i=0; i < ics_xPoints.length; i++) {
00203             ics_xPoints[i] += w;
00204             ics_yPoints[i] += h;
00205         }
00206 
00207         setTransformOK(false);
00208     }
 | 
  
      
  | 
  
| 
 
 Reimplemented from ScribbleFigure. 
 00212     {
00213         super.setColor(newColor);
00214         if (getWidth() > 0. && getHeight() > 0.) {
00215             makePixelChain();
00216         }
00217     }
 | 
  
      
  | 
  
| 
 
 
 00221     {
00222         if (ics_xPoints != null) {
00223             return ics_xPoints[0];
00224         }
00225         return Double.NaN;
00226     }
 | 
  
      
  | 
  
| 
 
 
 00230     {
00231         if (ics_yPoints != null) {
00232             return ics_yPoints[0];
00233         }
00234         return Double.NaN;
00235     }
 | 
  
      
  | 
  
| 
 
 
 00239     {
00240         return ics_xPoints;
00241     }
 | 
  
      
  | 
  
| 
 
 
 00245     {
00246         return ics_yPoints;
00247     }
 | 
  
      
  | 
  
| 
 
 
 00251     {
00252         return ics_xPoints.length;
00253     }
 | 
  
      
  | 
  
| 
 
 
 00257     {
00258         return freeman;
00259     }
 | 
  
      
  | 
  
| 
 
 
 00263     {
00264         return circular;
00265     }
 | 
  
      
  | 
  
| 
 
 
 00269     {
00270         circular = b;
00271     }
 | 
  
      
  | 
  ||||||||||||
| 
 To be removed. 
 Reimplemented from CanvasObject. 
 00289     {
00290         if (circular) {
00291             if (!getTransformOK()) {
00292                 transformICStoCCS();
00293             }
00294 
00295             if (ccs_poly != null) {
00296                 return (ccs_poly.contains(x, y));
00297             }
00298         }
00299         return false;
00300     }
 | 
  
      
  | 
  ||||||||||||
| 
 To be removed. 
 Reimplemented from CanvasObject. 
 00304     {
00305         if (!getTransformOK()) {
00306             transformICStoCCS();
00307         }
00308 
00309         // adapted from 'Graphics Gems II' - James Arvo,
00310         // chap. 1.3, 'Distance from a point to a line', pages 10-13.
00311 
00312 
00313         // check if inside enlarged bounding box (== box + SPHERE)
00314 
00315         if (!((x >= getX1Ccs() - SPHERE) && (x < getX1Ccs() + getWidthCcs() + SPHERE) &&
00316               (y >= getY1Ccs() - SPHERE) && (y < getY1Ccs() + getHeightCcs() + SPHERE))) {
00317             return false;
00318         }
00319 
00320 
00321         // we are inside the box, now check each line of the polygon
00322 
00323         int min_x, min_y, max_x, max_y;
00324         int area, abs1, abs2, distance;
00325 
00326         for (int i=0, j=1; i<ccs_poly.npoints; i++, j++) {
00327 
00328             if (j == ccs_poly.npoints) {
00329                 if (!circular) {
00330                     break;
00331                 }
00332                 j = 0;
00333             }
00334 
00335             min_x = Math.min(ccs_poly.xpoints[i], ccs_poly.xpoints[j]);
00336             min_y = Math.min(ccs_poly.ypoints[i], ccs_poly.ypoints[j]);
00337             max_x = Math.max(ccs_poly.xpoints[i], ccs_poly.xpoints[j]);
00338             max_y = Math.max(ccs_poly.ypoints[i], ccs_poly.ypoints[j]);
00339 
00340 
00341             // check if inside enlarged bounding box of line
00342 
00343             if ((x >= min_x - SPHERE) && (x < max_x + SPHERE) &&
00344                 (y >= min_y - SPHERE) && (y < max_y + SPHERE)) {
00345 
00346 
00347                 // calculate the area of the triangle formed by the two
00348                 // CanvasPolyline points and the 'check' point
00349 
00350                 area = (y - ccs_poly.ypoints[i])*
00351                        (ccs_poly.xpoints[j] - ccs_poly.xpoints[i]) -
00352                        (x - ccs_poly.xpoints[i])*
00353                        (ccs_poly.ypoints[j] - ccs_poly.ypoints[i]);
00354 
00355 
00356                 // calculate approximation of distance perpendicular to
00357                 // CanvasLine
00358 
00359 
00360                 abs1 = Math.abs(ccs_poly.xpoints[j] - ccs_poly.xpoints[i]);
00361                 abs2 = Math.abs(ccs_poly.ypoints[j] - ccs_poly.ypoints[i]);
00362 
00363                 distance = (int)(Math.abs(area) /
00364                            (abs1 + abs2 - 0.5 * Math.min(abs1, abs2)));
00365 
00366 
00367                 // this approximation can also be used as an
00368                 // approximation for the 'true' distance
00369 
00370                 if (distance <= SPHERE) {
00371                     return true;
00372                 }
00373             }
00374         }
00375         return false;
00376     }
 | 
  
      
  | 
  ||||||||||||
| 
 
 Reimplemented from ScribbleObject. 
 00380     {
00381         // overrule super.setDimension(w, h), and do nothing
00382 
00383         return;
00384     }
 | 
  
      
  | 
  ||||||||||||
| 
 
 Reimplemented from ScribbleObject. 
 00388     {
00389         double shift_x = getX1();
00390         double shift_y = getY1();
00391 
00392         super.doMove(w, h);
00393 
00394         shift_x -= getX1();
00395         shift_y -= getY1();
00396 
00397         if (ccs_poly != null) {
00398             for (int i=0; i < ccs_poly.npoints; i++) {
00399                 ics_xPoints[i] -= shift_x;
00400                 ics_yPoints[i] -= shift_y;
00401             }
00402             transformICStoCCS();
00403         }
00404     }
 | 
  
      
  | 
  ||||||||||||||||
| 
 
 Reimplemented from ScribbleFigure. 
 00408     {
00409         // overrule super.changePoint(index, x, y), and do nothing
00410 
00411         return index;
00412     }
 | 
  
      
  | 
  ||||||||||||||||
| 
 
 
 00426     {
00427         resizeable = false;
00428 
00429         if (chain != null) {
00430             makeFreemanPoly(x, y, chain);
00431             transformICStoCCS();
00432             makePixelChain();
00433         }
00434     }
 | 
  
      
  | 
  
| 
 Perform a full ICS to CCS coordinate transformation. 
 Reimplemented from CanvasObject. 
 00438     {
00439         if (ics_xPoints != null) {
00440             int[] xs = Converter.ICStoCCS(ics_xPoints, getZoomFactor());
00441             int[] ys = Converter.ICStoCCS(ics_yPoints, getZoomFactor());
00442             ccs_poly = new Polygon(xs, ys, xs.length);
00443             setBox();
00444             super.transformICStoCCS();
00445         }
00446     }
 | 
  
      
  | 
  ||||||||||||||||
| 
 
 
 00450     {
00451         freeman = new int[chain.length];
00452         for (int i=0; i<chain.length; i++) {
00453             freeman[i] = chain[i];
00454         }
00455 
00456         ics_xPoints = new double[chain.length + 1];
00457         ics_yPoints = new double[chain.length + 1];
00458 
00459         ics_xPoints[0] = x;
00460         ics_yPoints[0] = y;
00461 
00462         for (int i=0; i<chain.length; i++) {
00463             int direction = chain[i];
00464 
00465             switch (direction) {
00466                 case 0 : ics_xPoints[i+1] = ics_xPoints[i] + 1.;
00467                          ics_yPoints[i+1] = ics_yPoints[i];
00468                          break;
00469                 case 1 : ics_xPoints[i+1] = ics_xPoints[i] + 1.;
00470                          ics_yPoints[i+1] = ics_yPoints[i] - 1.;
00471                          break;
00472                 case 2 : ics_xPoints[i+1] = ics_xPoints[i];
00473                          ics_yPoints[i+1] = ics_yPoints[i] - 1.;
00474                          break;
00475                 case 3 : ics_xPoints[i+1] = ics_xPoints[i] - 1.;
00476                          ics_yPoints[i+1] = ics_yPoints[i] - 1.;
00477                          break;
00478                 case 4 : ics_xPoints[i+1] = ics_xPoints[i] - 1.;
00479                          ics_yPoints[i+1] = ics_yPoints[i];
00480                          break;
00481                 case 5 : ics_xPoints[i+1] = ics_xPoints[i] - 1.;
00482                          ics_yPoints[i+1] = ics_yPoints[i] + 1.;
00483                          break;
00484                 case 6 : ics_xPoints[i+1] = ics_xPoints[i];
00485                          ics_yPoints[i+1] = ics_yPoints[i] + 1.;
00486                          break;
00487                 case 7 : ics_xPoints[i+1] = ics_xPoints[i] + 1.;
00488                          ics_yPoints[i+1] = ics_yPoints[i] + 1.;
00489                          break;
00490             }
00491         }
00492 
00493         if ((ics_xPoints[0] == ics_xPoints[chain.length]) &&
00494             (ics_yPoints[0] == ics_yPoints[chain.length])) {
00495            circular = true;
00496         }
00497         setTransformOK(false);
00498     }
 | 
  
      
  | 
  
| 
 
 
 00502     {
00503         int color = drawColor.getRGB();
00504 
00505         int im_w     = (int)(getWidth() + 0.5) + 1;
00506         int im_h     = (int)(getHeight() + 0.5) + 1;
00507         int[] pixels = new int[im_w * im_h];
00508 
00509         for (int i=0; i<pixels.length; i++) {
00510             pixels[i] = 0x00000000;
00511         }
00512 
00513         for (int i=0; i<freeman.length+1; i++) {
00514             int im_x = (int)(ics_xPoints[i] - getX1() + 0.5);
00515             int im_y = (int)(ics_yPoints[i] - getY1() + 0.5);
00516             pixels[im_w*im_y + im_x] = color;
00517         }
00518         ImageBuffer ib = new ImageBuffer(pixels, im_w, im_h);
00519         image = ib.toImage();
00520     }
 | 
  
      
  | 
  
| 
 
 
 00524     {
00525         if (freeman != null) {
00526             double ics_maxX = 0.;
00527             double ics_maxY = 0.;
00528 
00529             setX1(Double.MAX_VALUE);
00530             setY1(Double.MAX_VALUE);
00531 
00532             for (int i=0; i < ics_xPoints.length; i++) {
00533                 if (ics_xPoints[i] < getX1()) {
00534                     setX1(ics_xPoints[i]);
00535                 }
00536                 if (ics_yPoints[i] < getY1()) {
00537                     setY1(ics_yPoints[i]);
00538                 }
00539                 if (ics_xPoints[i] > ics_maxX) {
00540                     ics_maxX = ics_xPoints[i];
00541                 }
00542                 if (ics_yPoints[i] > ics_maxY) {
00543                     ics_maxY = ics_yPoints[i];
00544                 }
00545             }
00546             setWidth(ics_maxX - getX1());
00547             setHeight(ics_maxY - getY1());
00548 
00549             setTransformOK(false);
00550         }
00551     }
 | 
  
      
  | 
  
| 
 
  | 
  
      
  | 
  
| 
 
  | 
  
      
  | 
  
| 
 
  | 
  
      
  | 
  
| 
 
  | 
  
      
  | 
  
| 
 
  | 
  
      
  | 
  
| 
 
  | 
  
1.2.12 written by Dimitri van Heesch,
 © 1997-2001