Horus Doc || Java GUI Reference || Doxygen's quick Index  

CanvasChain Class Reference

Inheritance diagram for CanvasChain::

ScribbleFigure ScribbleObject CanvasObject List of all members.

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

Constructor & Destructor Documentation

CanvasChain::CanvasChain int    chain[],
double    x,
double    y
[inline]
 

00030     {
00031         this(chain, x, y,
00032              NO_COLOR, false, DEF_LINEW, DEF_TRANS, DEF_SCALE);
00033     }

CanvasChain::CanvasChain int    chain[],
double    x,
double    y,
Color    color
[inline]
 

00037     {
00038         this(chain, x, y,
00039              color, false, DEF_LINEW, DEF_TRANS, DEF_SCALE);
00040     }

CanvasChain::CanvasChain int    chain[],
double    x,
double    y,
Color    color,
boolean    stroke,
float    linew,
float    trans,
double    ccs_scale
[inline]
 

00046     {
00047         super(x, y, 0., 0., COPY_MODE,
00048               color, stroke, linew, trans, ccs_scale);
00049         initChain(chain, x, y);
00050     }


Member Function Documentation

void CanvasChain::draw Graphics    g [inline, virtual]
 

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     }

Object CanvasChain::clone   [inline, virtual]
 

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     }

boolean CanvasChain::isInside double    x,
double    y
[inline]
 

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     }

boolean CanvasChain::isNear double    x,
double    y
[inline]
 

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     }

void CanvasChain::setDimension double    w,
double    h
[inline]
 

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     }

void CanvasChain::doPixelFit double    zoomFactor [inline]
 

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     }

void CanvasChain::doMove double    w,
double    h
[inline]
 

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     }

void CanvasChain::setColor Color    newColor [inline]
 

Reimplemented from ScribbleFigure.

00212     {
00213         super.setColor(newColor);
00214         if (getWidth() > 0. && getHeight() > 0.) {
00215             makePixelChain();
00216         }
00217     }

double CanvasChain::getFirstX   [inline]
 

00221     {
00222         if (ics_xPoints != null) {
00223             return ics_xPoints[0];
00224         }
00225         return Double.NaN;
00226     }

double CanvasChain::getFirstY   [inline]
 

00230     {
00231         if (ics_yPoints != null) {
00232             return ics_yPoints[0];
00233         }
00234         return Double.NaN;
00235     }

double [] CanvasChain::getXPoints   [inline]
 

00239     {
00240         return ics_xPoints;
00241     }

double [] CanvasChain::getYPoints   [inline]
 

00245     {
00246         return ics_yPoints;
00247     }

int CanvasChain::getNrPoints   [inline]
 

00251     {
00252         return ics_xPoints.length;
00253     }

int [] CanvasChain::getChain   [inline]
 

00257     {
00258         return freeman;
00259     }

boolean CanvasChain::isCircular   [inline]
 

00263     {
00264         return circular;
00265     }

void CanvasChain::setCircular boolean    b [inline]
 

00269     {
00270         circular = b;
00271     }

boolean CanvasChain::isInsideCcs int    x,
int    y
[inline]
 

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     }

boolean CanvasChain::isNearCcs int    x,
int    y
[inline]
 

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     }

void CanvasChain::setDimension int    w,
int    h
[inline]
 

Reimplemented from ScribbleObject.

00380     {
00381         // overrule super.setDimension(w, h), and do nothing
00382 
00383         return;
00384     }

void CanvasChain::doMove int    w,
int    h
[inline]
 

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     }

int CanvasChain::changePoint int    index,
int    x,
int    y
[inline]
 

Reimplemented from ScribbleFigure.

00408     {
00409         // overrule super.changePoint(index, x, y), and do nothing
00410 
00411         return index;
00412     }

void CanvasChain::initChain int    chain[],
double    x,
double    y
[inline, protected]
 

00426     {
00427         resizeable = false;
00428 
00429         if (chain != null) {
00430             makeFreemanPoly(x, y, chain);
00431             transformICStoCCS();
00432             makePixelChain();
00433         }
00434     }

void CanvasChain::transformICStoCCS   [inline, protected]
 

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     }

void CanvasChain::makeFreemanPoly double    x,
double    y,
int    chain[]
[inline, protected]
 

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     }

void CanvasChain::makePixelChain   [inline, protected]
 

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     }

void CanvasChain::setBox   [inline, protected]
 

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     }


Member Data Documentation

int [] CanvasChain::freeman = null [protected]
 

double [] CanvasChain::ics_xPoints = null [protected]
 

double [] CanvasChain::ics_yPoints = null [protected]
 

Polygon CanvasChain::ccs_poly = null [protected]
 

boolean CanvasChain::circular = false [protected]
 

Image CanvasChain::image = null [protected]
 


The documentation for this class was generated from the following file:
Generated on Tue Feb 3 14:19:38 2004 for JavaReference by doxygen1.2.12 written by Dimitri van Heesch, © 1997-2001