Back to index

moin  1.9.0~rc2
Public Member Functions | Static Public Member Functions | Protected Attributes | Static Package Attributes | Private Attributes | Static Private Attributes
CH.ifa.draw.contrib.PolygonFigure Class Reference

A scalable, rotatable polygon with an arbitrary number of points. More...

List of all members.

Public Member Functions

 PolygonFigure ()
 PolygonFigure (int x, int y)
 PolygonFigure (Polygon p)
Rectangle displayBox ()
boolean isEmpty ()
Vector handles ()
void basicDisplayBox (Point origin, Point corner)
Polygon getPolygon ()
 return a copy of the raw polygon
Point center ()
Enumeration points ()
int pointCount ()
void basicMoveBy (int dx, int dy)
void drawBackground (Graphics g)
void drawFrame (Graphics g)
boolean containsPoint (int x, int y)
Connector connectorAt (int x, int y)
void addPoint (int x, int y)
 Adds a node to the list of points.
void setPointAt (Point p, int i)
 Changes the position of a node.
void insertPointAt (Point p, int i)
 Insert a node at the given point.
void removePointAt (int i)
void scaleRotate (Point anchor, Polygon originalPolygon, Point p)
 Scale and rotate relative to anchor.
void smoothPoints ()
 Remove points that are nearly colinear with others.
int splitSegment (int x, int y)
 Splits the segment at the given point if a segment was hit.
Point pointAt (int i)
Point outermostPoint ()
 Return the point on the polygon that is furthest from the center.
int findSegment (int x, int y)
 Gets the segment that is hit by the given point.
Point chop (Point p)
String getMap ()
void write (StorableOutput dw)
void read (StorableInput dr) throws IOException

Static Public Member Functions

static Locator locator (final int pointIndex)
 Creates a locator for the point with the given index.
static double distanceFromLine (int xa, int ya, int xb, int yb, int xc, int yc)
 compute distance of point from line segment, or Double.MAX_VALUE if perpendicular projection is outside segment; or If pts on line are same, return distance from point
static Rectangle bounds (Polygon p)
 replacement for builtin Polygon.getBounds that doesn't always update?
static Point center (Polygon p)
static Point chop (Polygon poly, Point p)

Protected Attributes

Polygon fPoly = new Polygon()

Static Package Attributes

static final int TOO_CLOSE = 2
 Distance threshold for smoothing away or locating points.

Private Attributes

int polygonFigureSerializedDataVersion = 1

Static Private Attributes

static final long serialVersionUID = 6254089689239215026L

Detailed Description

A scalable, rotatable polygon with an arbitrary number of points.

Definition at line 20 of file PolygonFigure.java.


Constructor & Destructor Documentation

Definition at line 35 of file PolygonFigure.java.

                           {
       super();
    }

Here is the caller graph for this function:

CH.ifa.draw.contrib.PolygonFigure.PolygonFigure ( int  x,
int  y 
) [inline]

Definition at line 39 of file PolygonFigure.java.

                                       {
       fPoly.addPoint(x, y);
    }

Definition at line 43 of file PolygonFigure.java.

                                    {
       fPoly = new Polygon(p.xpoints, p.ypoints, p.npoints);
    }

Member Function Documentation

void CH.ifa.draw.contrib.PolygonFigure.addPoint ( int  x,
int  y 
) [inline]

Adds a node to the list of points.

Definition at line 123 of file PolygonFigure.java.

                                        {
       fPoly.addPoint(x, y);
       changed();
    }

Here is the caller graph for this function:

void CH.ifa.draw.contrib.PolygonFigure.basicDisplayBox ( Point  origin,
Point  corner 
) [inline]

Definition at line 67 of file PolygonFigure.java.

                                                            {
       Rectangle r = displayBox();
       int dx = origin.x - r.x;
       int dy = origin.y - r.y;
       fPoly.translate(dx, dy);
       r = displayBox();
       Point oldCorner = new Point(r.x + r.width, r.y + r.height);
       Polygon p = getPolygon();
       scaleRotate(oldCorner, p, corner);
    }

Here is the call graph for this function:

void CH.ifa.draw.contrib.PolygonFigure.basicMoveBy ( int  dx,
int  dy 
) [inline]

Definition at line 100 of file PolygonFigure.java.

                                            {
       fPoly.translate(dx, dy);
    }
static Rectangle CH.ifa.draw.contrib.PolygonFigure.bounds ( Polygon  p) [inline, static]

replacement for builtin Polygon.getBounds that doesn't always update?

Definition at line 440 of file PolygonFigure.java.

                                              {
       int minx = Integer.MAX_VALUE;
       int miny = Integer.MAX_VALUE;
       int maxx = Integer.MIN_VALUE;
       int maxy = Integer.MIN_VALUE;
       int n = p.npoints;
       for (int i = 0; i < n; i++) {
           int x = p.xpoints[i];
           int y = p.ypoints[i];
           if (x > maxx) maxx = x;
           if (x < minx) minx = x;
           if (y > maxy) maxy = y;
           if (y < miny) miny = y;
       }
       
       return new Rectangle(minx, miny, maxx-minx, maxy-miny);
    }

Here is the caller graph for this function:

Definition at line 85 of file PolygonFigure.java.

                          {
       return center(fPoly);
    }

Here is the caller graph for this function:

static Point CH.ifa.draw.contrib.PolygonFigure.center ( Polygon  p) [inline, static]

Definition at line 458 of file PolygonFigure.java.

                                          {
       long sx = 0;
       long sy = 0;
       int n = p.npoints;
       for (int i = 0; i < n; i++) {
           sx += p.xpoints[i];
           sy += p.ypoints[i];
       }
       
       return new Point((int)(sx/n), (int)(sy/n));
    }
Point CH.ifa.draw.contrib.PolygonFigure.chop ( Point  p) [inline]

Definition at line 307 of file PolygonFigure.java.

                               {
       return chop(fPoly, p);
    }

Here is the caller graph for this function:

static Point CH.ifa.draw.contrib.PolygonFigure.chop ( Polygon  poly,
Point  p 
) [inline, static]

Definition at line 470 of file PolygonFigure.java.

                                                    {
       Point ctr = center(poly);
       int cx = -1;
       int cy = -1;
       long len = Long.MAX_VALUE;
       
       // Try for points along edge
       
       for (int i = 0; i < poly.npoints; ++i) {
           int nxt = (i + 1) % poly.npoints;
           Point chop = Geom.intersect(poly.xpoints[i],
                                   poly.ypoints[i],
                                   poly.xpoints[nxt],
                                   poly.ypoints[nxt],
                                   p.x,
                                   p.y,
                                   ctr.x,
                                   ctr.y);
           if (chop != null) {
              long cl = Geom.length2(chop.x, chop.y, p.x, p.y);
              if (cl < len) {
                  len = cl;
                  cx = chop.x;
                  cy = chop.y;
              }
           }
       }
       // if none found, pick closest vertex
       //if (len ==  Long.MAX_VALUE) {
       { // try anyway
           for (int i = 0; i < poly.npoints; ++i) {
              long l = Geom.length2(poly.xpoints[i], poly.ypoints[i], p.x, p.y);
              if (l < len) {
                  len = l;
                  cx = poly.xpoints[i];
                  cy = poly.ypoints[i];
              }
           }
       }
       return new Point(cx, cy);
    }

Here is the call graph for this function:

Connector CH.ifa.draw.contrib.PolygonFigure.connectorAt ( int  x,
int  y 
) [inline]

Definition at line 116 of file PolygonFigure.java.

                                               {
       return new ChopPolygonConnector(this);
    }
boolean CH.ifa.draw.contrib.PolygonFigure.containsPoint ( int  x,
int  y 
) [inline]

Definition at line 112 of file PolygonFigure.java.

                                               {
       return fPoly.contains(x, y);
    }

Definition at line 47 of file PolygonFigure.java.

                                  {
       return bounds(fPoly);
    }

Here is the call graph for this function:

Here is the caller graph for this function:

static double CH.ifa.draw.contrib.PolygonFigure.distanceFromLine ( int  xa,
int  ya,
int  xb,
int  yb,
int  xc,
int  yc 
) [inline, static]

compute distance of point from line segment, or Double.MAX_VALUE if perpendicular projection is outside segment; or If pts on line are same, return distance from point

Definition at line 370 of file PolygonFigure.java.

                                                     {
       
       
       // source:http://vision.dai.ed.ac.uk/andrewfg/c-g-a-faq.html#q7
       //Let the point be C (XC,YC) and the line be AB (XA,YA) to (XB,YB).
       //The length of the
       //      line segment AB is L:
       //
       //                    ___________________
       //                   |        2         2
       //              L = \| (XB-XA) + (YB-YA)
       //and
       //
       //                  (YA-YC)(YA-YB)-(XA-XC)(XB-XA)
       //              r = -----------------------------
       //                              L**2
       //
       //                  (YA-YC)(XB-XA)-(XA-XC)(YB-YA)
       //              s = -----------------------------
       //                              L**2
       //
       //      Let I be the point of perpendicular projection of C onto AB, the
       //
       //              XI=XA+r(XB-XA)
       //              YI=YA+r(YB-YA)
       //
       //      Distance from A to I = r*L
       //      Distance from C to I = s*L
       //
       //      If r < 0 I is on backward extension of AB
       //      If r>1 I is on ahead extension of AB
       //      If 0<=r<=1 I is on AB
       //
       //      If s < 0 C is left of AB (you can just check the numerator)
       //      If s>0 C is right of AB
       //      If s=0 C is on AB
       
       int xdiff = xb - xa;
       int ydiff = yb - ya;
       long l2 = xdiff*xdiff + ydiff*ydiff;
       
       if (l2 == 0) return Geom.length(xa, ya, xc, yc);
       
       double rnum =  (ya-yc) * (ya-yb) - (xa-xc) * (xb-xa);
       double r = rnum / l2;
       
       if (r < 0.0 || r > 1.0) return Double.MAX_VALUE;
       
       double xi = xa + r * xdiff;
       double yi = ya + r * ydiff;
       double xd = xc - xi;
       double yd = yc - yi;
       return Math.sqrt(xd * xd + yd * yd);
       
       /*
         for directional version, instead use
         double snum =  (ya-yc) * (xb-xa) - (xa-xc) * (yb-ya);
         double s = snum / l2;
         
         double l = Math.sqrt((double)l2);
         return = s * l;
       */
    }

Here is the call graph for this function:

Here is the caller graph for this function:

void CH.ifa.draw.contrib.PolygonFigure.drawBackground ( Graphics  g) [inline]

Definition at line 104 of file PolygonFigure.java.

                                           {
       g.fillPolygon(fPoly);
    }
void CH.ifa.draw.contrib.PolygonFigure.drawFrame ( Graphics  g) [inline]

Definition at line 108 of file PolygonFigure.java.

                                      {
       g.drawPolygon(fPoly);
    }
int CH.ifa.draw.contrib.PolygonFigure.findSegment ( int  x,
int  y 
) [inline]

Gets the segment that is hit by the given point.

Returns:
the index of the segment or -1 if no segment was hit.

Definition at line 290 of file PolygonFigure.java.

                                         {
       double dist = TOO_CLOSE;
       int best = -1;
       
       for (int i = 0; i < fPoly.npoints; i++) {
           int n = (i + 1) % fPoly.npoints;
           double d =  distanceFromLine(fPoly.xpoints[i], fPoly.ypoints[i],
                                    fPoly.xpoints[n], fPoly.ypoints[n],
                                    x, y);
           if (d < dist) {
              dist = d;
              best = i;
           }
       }
       return best;
    }

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 311 of file PolygonFigure.java.

                           {
       String sense = (String)getAttribute("Sensitive");
       if (sense == null || sense.length() == 0)
           return "";
       try {
           sense = URLDecoder.decode(sense);
       } catch (Exception e) {}
       Rectangle box = displayBox();
       String coords = "";
       for (int i = 0; i < fPoly.npoints; i++) {
           if (i > 0)
              coords += ",";
           coords += fPoly.xpoints[i] + "," + fPoly.ypoints[i];
       }
       return "<area shape=\"poly\" coords=\"" +
           coords + "\" />\n";
    }

Here is the call graph for this function:

return a copy of the raw polygon

Definition at line 81 of file PolygonFigure.java.

                                {
       return new Polygon(fPoly.xpoints, fPoly.ypoints, fPoly.npoints);
    }

Here is the caller graph for this function:

Definition at line 57 of file PolygonFigure.java.

                            {
       Vector handles = new Vector(fPoly.npoints);
       for (int i = 0; i < fPoly.npoints; i++)
           handles.addElement(new PolygonHandle(this, locator(i), i));
       handles.addElement(new PolygonScaleHandle(this));
       //handles.addElement(new PolygonPointAddHandle(this));
       return handles;
    }

Here is the call graph for this function:

void CH.ifa.draw.contrib.PolygonFigure.insertPointAt ( Point  p,
int  i 
) [inline]

Insert a node at the given point.

Definition at line 142 of file PolygonFigure.java.

                                               {
       willChange();
       int n = fPoly.npoints + 1;
       int[] xs = new int[n];
       int[] ys = new int[n];
       for (int j = 0; j < i; ++j) {
           xs[j] = fPoly.xpoints[j];
           ys[j] = fPoly.ypoints[j];
       }
       xs[i] = p.x;
       ys[i] = p.y;
       for (int j = i; j < fPoly.npoints; ++j) {
           xs[j+1] = fPoly.xpoints[j];
           ys[j+1] = fPoly.ypoints[j];
       }
       
       fPoly = new Polygon(xs, ys, n);
       changed();
    }

Here is the caller graph for this function:

Definition at line 52 of file PolygonFigure.java.

                             {
       return (fPoly.npoints < 3 ||
              (size().width < TOO_CLOSE) && (size().height < TOO_CLOSE));
    }

Here is the call graph for this function:

static Locator CH.ifa.draw.contrib.PolygonFigure.locator ( final int  pointIndex) [inline, static]

Creates a locator for the point with the given index.

Definition at line 353 of file PolygonFigure.java.

                                                        {
       return new AbstractLocator() {
              public Point locate(Figure owner) {
                  PolygonFigure plf = (PolygonFigure)owner;
                  // guard against changing PolygonFigures -> temporary hack
                  if (pointIndex < plf.pointCount())
                     return ((PolygonFigure)owner).pointAt(pointIndex);
                  return new Point(-1, -1);
              }
           };
    }

Here is the call graph for this function:

Here is the caller graph for this function:

Return the point on the polygon that is furthest from the center.

Definition at line 269 of file PolygonFigure.java.

                                  {
       Point ctr = center();
       int outer = 0;
       long dist = 0;
       
       for (int i = 0; i < fPoly.npoints; ++i) {
           long d = Geom.length2(ctr.x, ctr.y, fPoly.xpoints[i], fPoly.ypoints[i]);
           if (d > dist) {
              dist = d;
              outer = i;
           }
       }
       
       return new Point(fPoly.xpoints[outer], fPoly.ypoints[outer]);
    }

Here is the call graph for this function:

Point CH.ifa.draw.contrib.PolygonFigure.pointAt ( int  i) [inline]

Definition at line 262 of file PolygonFigure.java.

                                {
       return new Point(fPoly.xpoints[i], fPoly.ypoints[i]);
    }

Here is the caller graph for this function:

Definition at line 96 of file PolygonFigure.java.

                            {
       return fPoly.npoints;
    }

Here is the caller graph for this function:

Enumeration CH.ifa.draw.contrib.PolygonFigure.points ( ) [inline]

Definition at line 89 of file PolygonFigure.java.

                                {
       Vector pts = new Vector(fPoly.npoints);
       for (int i = 0; i < fPoly.npoints; ++i)
           pts.addElement(new Point(fPoly.xpoints[i], fPoly.ypoints[i]));
       return pts.elements();
    }
void CH.ifa.draw.contrib.PolygonFigure.read ( StorableInput  dr) throws IOException [inline]

Definition at line 338 of file PolygonFigure.java.

                                                          {
       super.read(dr);
       int size = dr.readInt();
       int[] xs = new int[size];
       int[] ys = new int[size];
       for (int i = 0; i < size; i++) {
           xs[i] = dr.readInt();
           ys[i] = dr.readInt();
       }
       fPoly = new Polygon(xs, ys, size);
    }

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 162 of file PolygonFigure.java.

                                      {
       willChange();
       int n = fPoly.npoints - 1;
       int[] xs = new int[n];
       int[] ys = new int[n];
       for (int j = 0; j < i; ++j) {
           xs[j] = fPoly.xpoints[j];
           ys[j] = fPoly.ypoints[j];
       }
       for (int j = i; j < n; ++j) {
           xs[j] = fPoly.xpoints[j+1];
           ys[j] = fPoly.ypoints[j+1];
       }
       fPoly = new Polygon(xs, ys, n);
       changed();
    }
void CH.ifa.draw.contrib.PolygonFigure.scaleRotate ( Point  anchor,
Polygon  originalPolygon,
Point  p 
) [inline]

Scale and rotate relative to anchor.

Definition at line 182 of file PolygonFigure.java.

                                                                             {
       willChange();
       
       // use center to determine relative angles and lengths
       Point ctr = center(originalPolygon);
       double anchorLen = Geom.length(ctr.x, ctr.y, anchor.x, anchor.y);
       
       if (anchorLen > 0.0) {
           double newLen = Geom.length(ctr.x, ctr.y, p.x, p.y);
           double ratio = newLen / anchorLen;
           
           double anchorAngle = Math.atan2(anchor.y - ctr.y, anchor.x - ctr.x);
           double newAngle = Math.atan2(p.y - ctr.y, p.x - ctr.x);
           double rotation = newAngle - anchorAngle;
           
           int n = originalPolygon.npoints;
           int[] xs = new int[n];
           int[] ys = new int[n];
           
           for (int i = 0; i < n; ++i) {
              int x = originalPolygon.xpoints[i];
              int y = originalPolygon.ypoints[i];
              double l = Geom.length(ctr.x, ctr.y, x, y) * ratio;
              double a = Math.atan2(y - ctr.y, x - ctr.x) + rotation;
              xs[i] = (int)(ctr.x + l * Math.cos(a) + 0.5);
              ys[i] = (int)(ctr.y + l * Math.sin(a) + 0.5);
           }
           fPoly =  new Polygon(xs, ys, n);
       }
       changed();
    }

Here is the call graph for this function:

Here is the caller graph for this function:

void CH.ifa.draw.contrib.PolygonFigure.setPointAt ( Point  p,
int  i 
) [inline]

Changes the position of a node.

Definition at line 132 of file PolygonFigure.java.

                                            {
       willChange();
       fPoly.xpoints[i] = p.x;
       fPoly.ypoints[i] = p.y;
       changed();
    }

Here is the caller graph for this function:

Remove points that are nearly colinear with others.

Definition at line 218 of file PolygonFigure.java.

                               {
       willChange();
       boolean removed = false;
       int n = fPoly.npoints;
       do {
           removed = false;
           int i = 0;
           while (i < n && n >= 3) {
              int nxt = (i + 1) % n;
              int prv = (i - 1 + n) % n;
              
              if ((distanceFromLine(fPoly.xpoints[prv], fPoly.ypoints[prv],
                                  fPoly.xpoints[nxt], fPoly.ypoints[nxt],
                                  fPoly.xpoints[i], fPoly.ypoints[i]) < TOO_CLOSE)) {
                  removed = true;
                  --n;
                  for (int j = i; j < n; ++j) {
                     fPoly.xpoints[j] = fPoly.xpoints[j+1];
                     fPoly.ypoints[j] = fPoly.ypoints[j+1];
                  }
              }
              else
                  ++i;
           }
       } while(removed);
       if (n != fPoly.npoints)
           fPoly =  new Polygon(fPoly.xpoints, fPoly.ypoints, n);
       changed();
    }

Here is the call graph for this function:

Here is the caller graph for this function:

int CH.ifa.draw.contrib.PolygonFigure.splitSegment ( int  x,
int  y 
) [inline]

Splits the segment at the given point if a segment was hit.

Returns:
the index of the segment or -1 if no segment was hit.

Definition at line 252 of file PolygonFigure.java.

                                          {
       int i = findSegment(x, y);
       if (i != -1) {
           insertPointAt(new Point(x, y), i+1);
           return i + 1;
       }
       else
           return -1;
    }

Here is the call graph for this function:

void CH.ifa.draw.contrib.PolygonFigure.write ( StorableOutput  dw) [inline]

Definition at line 329 of file PolygonFigure.java.

                                         {
       super.write(dw);
       dw.writeInt(fPoly.npoints);
       for (int i = 0; i < fPoly.npoints; ++i) {
           dw.writeInt(fPoly.xpoints[i]);
           dw.writeInt(fPoly.ypoints[i]);
       }
    }

Here is the caller graph for this function:


Member Data Documentation

Polygon CH.ifa.draw.contrib.PolygonFigure.fPoly = new Polygon() [protected]

Definition at line 33 of file PolygonFigure.java.

Definition at line 31 of file PolygonFigure.java.

final long CH.ifa.draw.contrib.PolygonFigure.serialVersionUID = 6254089689239215026L [static, private]

Definition at line 30 of file PolygonFigure.java.

final int CH.ifa.draw.contrib.PolygonFigure.TOO_CLOSE = 2 [static, package]

Distance threshold for smoothing away or locating points.

Definition at line 25 of file PolygonFigure.java.


The documentation for this class was generated from the following file: