All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.microemu.device.impl.Polygon Maven / Gradle / Ivy

The newest version!
/*
 *  MicroEmulator
 *  GeoTools java GIS tookit (c) The Centre for Computational Geography 2002
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License as published by the Free Software Foundation; either
 *  version 2.1 of the License, or (at your option) any later version.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

package org.microemu.device.impl;

/**
 * This class is intended for storing georaphical polygons such as boundary data
 * for wards, coastlines etc.

* * Extracted from uk.ac.leeds.ccg.geotools.GeoPolygon * * @author James Macgill * @author Mathieu Van Loon - getPointsAsArrayX, getPointsAsArrayY, dropVector * @since 0.5.0 */ public class Polygon extends Shape { /** * Number of points in polygon. */ public int npoints; /** * Array of points. */ public int xpoints[]; /** * Array of points. */ public int[] ypoints; private Rectangle bounds = new Rectangle(); /** * Create an empty polygon. */ public Polygon() { } /** * Construct a polygon with full details. * * @param id Polygon ID. * @param xcent X-coordinate of centroid. * @param ycent Y-coordinate of centroid. * @param xpoints Array of x values (npoints in size). * @param ypoints Array of y values (npoints in size). * @param npoints Number of points. */ public Polygon(int[] xpoints, int[] ypoints, int npoints) { this.xpoints = new int[npoints]; this.ypoints = new int[npoints]; this.npoints = npoints; //Add a try here to catch failed array copy System.arraycopy(xpoints, 0, this.xpoints, 0, npoints); System.arraycopy(ypoints, 0, this.ypoints, 0, npoints); for (int i = 0; i < npoints; i++) { bounds.add(xpoints[i], ypoints[i]); } } /** * Construct a GeoPolygon based on an existing GeoPolygon. * * @param poly GeoPolygon to clone. */ public Polygon(Polygon poly) { this(poly.xpoints, poly.ypoints, poly.npoints); } /** * Add a vertex to the polygon. * * @param x X-coordinate of point to add. * @param y Y-coordinate of point to add. */ public void addPoint(int x, int y) { if (npoints > 0) { int xtemp[]; int ytemp[]; xtemp = xpoints; ytemp = ypoints; xpoints = new int[npoints + 1]; System.arraycopy(xtemp, 0, xpoints, 0, npoints); xtemp = null; ypoints = new int[npoints + 1]; System.arraycopy(ytemp, 0, ypoints, 0, npoints); ytemp = null; } else { xpoints = new int[1]; ypoints = new int[1]; } npoints++; xpoints[npoints - 1] = x;//-1 to account for 0 array indexing ypoints[npoints - 1] = y; bounds.add(x, y); } public Rectangle getBounds() { return bounds; } /** * Tests to see if a point is contained by this polygon. * * @param p * The GeoPoint to test. * @return boolean True if point is contained by this polygon. */ public boolean contains(int x, int y) { /*if(!getMultiPartBounds().contains(p)){ return false; }*/ if (getBounds().contains(x, y)) { // Tested and work just fine boolean c = false; for (int i = 0, j = npoints - 1; i < npoints; j = i++) { if ((((ypoints[i] <= y) && (y < ypoints[j])) || ((ypoints[j] <= y) && (y < ypoints[i]))) && (x < ((double)(xpoints[j] - xpoints[i]) * (y - ypoints[i])) / (ypoints[j] - ypoints[i]) + xpoints[i])) { c = !c; } } return c; // This code does not work as expected even after fixes for double // // /* Start andys code */ // int number_of_lines_crossed = 0; // holds lines intersecting with // number_of_lines_crossed = 0; // set lines crossed = 0 for each polygon // // lets us know which part start we're looking for // for (int i = 0; i < npoints - 1; i++) { // //GeoPoint A = new GeoPoint(); // //GeoPoint B = new GeoPoint(); // //A.y = ypoints[i]; // get y-coordinate // //A.x = xpoints[i]; // get x-coordinate // //B.y = ypoints[i+1]; // get next y-coordinate // //B.x = xpoints[i+1]; // get next x-coordinate // // if (y != ypoints[i + 1] && (y <= Math.max(ypoints[i], ypoints[i + 1])) // && (y >= Math.min(ypoints[i], ypoints[i + 1])) && ((xpoints[i] >= x) || (xpoints[i + 1] >= x))) { // if polygon contains a suitable value // if (((xpoints[i] >= x) && (xpoints[i + 1] >= x))) { // number_of_lines_crossed++;//simple case // } else { // double gradient; // calc. gradient // if (xpoints[i] > xpoints[i + 1]) { // gradient = ((double) (xpoints[i] - xpoints[i + 1]) / (double) (ypoints[i] - ypoints[i + 1])); // } else { // gradient = ((double) (xpoints[i + 1] - xpoints[i]) / (double) (ypoints[i + 1] - ypoints[i])); // } // double x_intersection_axis = (xpoints[i] - (gradient * ypoints[i])); // calc. intersect with x-axis // double x_intersection_line = (gradient * y) + x_intersection_axis; // calc. intersect with y=const // // line extending from location // if ((x_intersection_line <= Math.max(xpoints[i], xpoints[i + 1])) // && // check intersect inside polygon // (x_intersection_line >= Math.min(xpoints[i], xpoints[i + 1])) // && (x_intersection_line >= x)) { // number_of_lines_crossed++; // increment line counter // } // end check for inside polygon // } // } // end of if polygon points suitable // } // end of run through points in polygon // // if ((number_of_lines_crossed != 0) && // if number of polygon lines crossed // (((number_of_lines_crossed % 2) == 1))) { // by a line in one direction from the // return true; // initial location is odd, the location // // // lies in that polygon // // } // end of run through polygons } return false; // return stuffing if things get this far } // end of method whichPolygon }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy