home *** CD-ROM | disk | FTP | other *** search
/ Chip 1998 November / Chip_1998-11_cd.bin / tema / Cafe / main.bin / Polygon.java < prev    next >
Text File  |  1997-10-01  |  9KB  |  281 lines

  1. /*
  2.  * @(#)Polygon.java    1.16 97/06/17
  3.  * 
  4.  * Copyright (c) 1995, 1996 Sun Microsystems, Inc. All Rights Reserved.
  5.  * 
  6.  * This software is the confidential and proprietary information of Sun
  7.  * Microsystems, Inc. ("Confidential Information").  You shall not
  8.  * disclose such Confidential Information and shall use it only in
  9.  * accordance with the terms of the license agreement you entered into
  10.  * with Sun.
  11.  * 
  12.  * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE
  13.  * SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
  14.  * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
  15.  * PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR ANY DAMAGES
  16.  * SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING
  17.  * THIS SOFTWARE OR ITS DERIVATIVES.
  18.  * 
  19.  * CopyrightVersion 1.1_beta
  20.  * 
  21.  */
  22. package java.awt;
  23.  
  24. /**
  25.  * The <code>Polygon</code> class encapsulates a description of a 
  26.  * closed, two-dimensional region within a coordinate space. This 
  27.  * region is bounded by an arbitrary number of line segments, each of 
  28.  * which is one side of the polygon. Internally, a polygon 
  29.  * comprises of a list of (<i>x</i>, <i>y</i>) coordinate pairs, 
  30.  * where each pair defines a <i>vertex</i> of the polygon, and two 
  31.  * successive pairs are the endpoints of a line that is a side of the 
  32.  * polygon. The first and final pairs of (<i>x</i>, <i>y</i>) 
  33.  * points are joined by a line segment that closes the polygon.
  34.  *
  35.  * @version     1.16, 06/17/97
  36.  * @author     Sami Shaio
  37.  * @author      Herb Jellinek
  38.  * @since       JDK1.0
  39.  */
  40. public class Polygon implements Shape, java.io.Serializable {
  41.  
  42.     /**
  43.      * The total number of points.
  44.      * @since JDK1.0
  45.      */
  46.     public int npoints = 0;
  47.  
  48.     /**
  49.      * The array of <i>x</i> coordinates. 
  50.      * @since   JDK1.0
  51.      */
  52.     public int xpoints[] = new int[4];
  53.  
  54.     /**
  55.      * The array of <i>y</i> coordinates. 
  56.      * @since   JDK1.0
  57.      */
  58.     public int ypoints[] = new int[4];
  59.     
  60.     /*
  61.      * Bounds of the polygon.
  62.      */
  63.     protected Rectangle bounds = null;
  64.     
  65.     /* 
  66.      * JDK 1.1 serialVersionUID 
  67.      */
  68.     private static final long serialVersionUID = -6460061437900069969L;
  69.  
  70.     /**
  71.      * Creates an empty polygon.
  72.      * @since JDK1.0
  73.      */
  74.     public Polygon() {
  75.     }
  76.  
  77.     /**
  78.      * Constructs and initializes a polygon from the specified 
  79.      * parameters. 
  80.      * @param      xpoints   an array of <i>x</i> coordinates.
  81.      * @param      ypoints   an array of <i>y</i> coordinates.
  82.      * @param      npoints   the total number of points in the polygon.
  83.      * @exception  NegativeArraySizeException if the value of
  84.      *                       <code>npoints</code> is negative.
  85.      * @since      JDK1.0
  86.      */
  87.     public Polygon(int xpoints[], int ypoints[], int npoints) {
  88.     this.npoints = npoints;
  89.     this.xpoints = new int[npoints];
  90.     this.ypoints = new int[npoints];
  91.     System.arraycopy(xpoints, 0, this.xpoints, 0, npoints);
  92.     System.arraycopy(ypoints, 0, this.ypoints, 0, npoints);    
  93.     }
  94.     
  95.     /**
  96.      * Translates the vertices by <code>deltaX</code> along the 
  97.      * <i>x</i> axis and by <code>deltaY</code> along the 
  98.      * <i>y</i> axis.
  99.      * @param deltaX the amount to translate along the <i>x</i> axis
  100.      * @param deltaY the amount to translate along the <i>y</i> axis
  101.      * @since JDK1.1
  102.      */
  103.     public void translate(int deltaX, int deltaY) {
  104.     for (int i = 0; i < npoints; i++) {
  105.         xpoints[i] += deltaX;
  106.         ypoints[i] += deltaY;
  107.     }
  108.     if (bounds != null) {
  109.         bounds.translate(deltaX, deltaY);
  110.     }
  111.     }
  112.  
  113.     /*
  114.      * Calculate the bounding box of the points passed to the constructor.
  115.      * Sets 'bounds' to the result.
  116.      */
  117.     void calculateBounds(int xpoints[], int ypoints[], int npoints) {
  118.     int boundsMinX = Integer.MAX_VALUE;
  119.     int boundsMinY = Integer.MAX_VALUE;
  120.     int boundsMaxX = Integer.MIN_VALUE;
  121.     int boundsMaxY = Integer.MIN_VALUE;
  122.     
  123.     for (int i = 0; i < npoints; i++) {
  124.         int x = xpoints[i];
  125.         boundsMinX = Math.min(boundsMinX, x);
  126.         boundsMaxX = Math.max(boundsMaxX, x);
  127.         int y = ypoints[i];
  128.         boundsMinY = Math.min(boundsMinY, y);
  129.         boundsMaxY = Math.max(boundsMaxY, y);
  130.     }
  131.     bounds = new Rectangle(boundsMinX, boundsMinY,
  132.                    boundsMaxX - boundsMinX,
  133.                    boundsMaxY - boundsMinY);
  134.     }
  135.  
  136.     /*
  137.      * Update the bounding box to fit the point x, y.
  138.      */
  139.     void updateBounds(int x, int y) {
  140.     bounds.x = Math.min(bounds.x, x);
  141.     bounds.width = Math.max(bounds.width, x - bounds.x);
  142.     bounds.y = Math.min(bounds.y, y);
  143.     bounds.height = Math.max(bounds.height, y - bounds.y);
  144.     }    
  145.  
  146.     /**
  147.      * Appends a point to this polygon. 
  148.      * <p>
  149.      * If an operation that calculates the bounding box of this polygon
  150.      * has already been performed, such as <code>getBounds</code> 
  151.      * or <code>contains</code>, then this method updates the bounding box. 
  152.      * @param       x   the <i>x</i> coordinate of the point.
  153.      * @param       y   the <i>y</i> coordinate of the point.
  154.      * @see         java.awt.Polygon#getBounds
  155.      * @see         java.awt.Polygon#contains
  156.      * @since       JDK1.0
  157.      */
  158.     public void addPoint(int x, int y) {
  159.     if (npoints == xpoints.length) {
  160.         int tmp[];
  161.  
  162.         tmp = new int[npoints * 2];
  163.         System.arraycopy(xpoints, 0, tmp, 0, npoints);
  164.         xpoints = tmp;
  165.  
  166.         tmp = new int[npoints * 2];
  167.         System.arraycopy(ypoints, 0, tmp, 0, npoints);
  168.         ypoints = tmp;
  169.     }
  170.     xpoints[npoints] = x;
  171.     ypoints[npoints] = y;
  172.     npoints++;
  173.     if (bounds != null) {
  174.         updateBounds(x, y);
  175.     }
  176.     }
  177.  
  178.     /**
  179.      * Gets the bounding box of this polygon. The bounding box is the
  180.      * smallest rectangle whose sides are parallel to the <i>x</i> and
  181.      * <i>y</i> axes of the coordinate space, and that can completely
  182.      * contain the polygon.
  183.      * @return      a rectangle that defines the bounds of this polygon.
  184.      * @since       JDK1.1
  185.      */
  186.     public Rectangle getBounds() {
  187.     return getBoundingBox();
  188.     }
  189.  
  190.     /**
  191.      * @deprecated As of JDK version 1.1,
  192.      * replaced by <code>getBounds()</code>.
  193.      */
  194.     public Rectangle getBoundingBox() {
  195.     if (bounds == null) {
  196.         calculateBounds(xpoints, ypoints, npoints);
  197.     }
  198.     return bounds;
  199.     }
  200.  
  201.     /**
  202.      * Determines whether the specified point is inside the Polygon.
  203.      * Uses an even-odd insideness rule (also known as an alternating
  204.      * rule).
  205.      * @param p the point to be tested
  206.      */
  207.     public boolean contains(Point p) {
  208.     return contains(p.x, p.y);
  209.     }
  210.  
  211.     /**
  212.      * Determines whether the specified point is contained by this polygon.   
  213.      * <p>
  214.      * (The <code>contains</code> method is based on code by 
  215.      * Hanpeter van Vliet [hvvliet@inter.nl.net].) 
  216.      * @param      x  the <i>x</i> coordinate of the point to be tested.
  217.      * @param      y  the <i>y</i> coordinate of the point to be tested.
  218.      * @return     <code>true</code> if the point (<i>x</i>, <i>y</i>) 
  219.      *                       is contained by this polygon; 
  220.      *                       <code>false</code> otherwise.
  221.      * @since      JDK1.1
  222.      */
  223.     public boolean contains(int x, int y) {
  224.     return inside(x, y);
  225.     }
  226.  
  227.     /**
  228.      * @deprecated As of JDK version 1.1,
  229.      * replaced by <code>contains(int, int)</code>.
  230.      */
  231.     public boolean inside(int x, int y) {
  232.         if (getBoundingBox().inside(x, y)) {
  233.             int hits = 0;
  234.             int ySave = 0;
  235.  
  236.             // Find a vertex that's not on the halfline
  237.             int i = 0;
  238.             while (i < npoints && ypoints[i] == y) {
  239.                 i++;
  240.         }
  241.  
  242.             // Walk the edges of the polygon
  243.             for (int n = 0; n < npoints; n++) {
  244.                 int j = (i + 1) % npoints;
  245.  
  246.                 int dx = xpoints[j] - xpoints[i];
  247.                 int dy = ypoints[j] - ypoints[i];
  248.  
  249.                 // Ignore horizontal edges completely
  250.                 if (dy != 0) {
  251.                     // Check to see if the edge intersects
  252.                     // the horizontal halfline through (x, y)
  253.                     int rx = x - xpoints[i];
  254.                     int ry = y - ypoints[i];
  255.  
  256.                     // Deal with edges starting or ending on the halfline
  257.                     if (ypoints[j] == y && xpoints[j] >= x) {
  258.                         ySave = ypoints[i];
  259.             }
  260.                     if (ypoints[i] == y && xpoints[i] >= x) {
  261.                         if ((ySave > y) != (ypoints[j] > y)) {
  262.                 hits--;
  263.             }
  264.             }
  265.  
  266.                     // Tally intersections with halfline
  267.                     float s = (float)ry / (float)dy;
  268.                     if (s >= 0.0 && s <= 1.0 && (s * dx) >= rx) {
  269.                         hits++;
  270.             }
  271.                 }
  272.                 i = j;
  273.             }
  274.  
  275.             // Inside if number of intersections odd
  276.             return (hits % 2) != 0;
  277.         }
  278.         return false;
  279.     }
  280. }
  281.