001: /*
002: * The Unified Mapping Platform (JUMP) is an extensible, interactive GUI
003: * for visualizing and manipulating spatial features with geometry and attributes.
004: *
005: * Copyright (C) 2003 Vivid Solutions
006: *
007: * This program is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU General Public License
009: * as published by the Free Software Foundation; either version 2
010: * of the License, or (at your option) any later version.
011: *
012: * This program is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
015: * GNU General Public License for more details.
016: *
017: * You should have received a copy of the GNU General Public License
018: * along with this program; if not, write to the Free Software
019: * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
020: *
021: * For more information, contact:
022: *
023: * Vivid Solutions
024: * Suite #1A
025: * 2328 Government Street
026: * Victoria BC V8T 5G5
027: * Canada
028: *
029: * (250)385-6040
030: * www.vividsolutions.com
031: */
032:
033: package com.vividsolutions.jump.warp;
034:
035: import java.awt.geom.Line2D;
036: import java.util.ArrayList;
037: import java.util.Collection;
038: import java.util.Iterator;
039: import java.util.List;
040:
041: import com.vividsolutions.jts.geom.Coordinate;
042: import com.vividsolutions.jts.geom.Envelope;
043: import com.vividsolutions.jts.geom.GeometryFactory;
044: import com.vividsolutions.jts.geom.Point;
045: import com.vividsolutions.jts.geom.Polygon;
046:
047: /**
048: * A simple four-sided polygon.
049: */
050: public class Quadrilateral implements Cloneable {
051: private Coordinate p1;
052: private Coordinate p2;
053: private Coordinate p3;
054: private Coordinate p4;
055: private GeometryFactory factory = new GeometryFactory();
056:
057: public Envelope getEnvelope() {
058: Envelope envelope = new Envelope(p1);
059: envelope.expandToInclude(p2);
060: envelope.expandToInclude(p3);
061: envelope.expandToInclude(p4);
062: return envelope;
063: }
064:
065: protected Object clone() {
066: return new Quadrilateral(new Coordinate(p1),
067: new Coordinate(p2), new Coordinate(p3), new Coordinate(
068: p4));
069: }
070:
071: /**
072: * Creates a Quadrilateral.
073: * @param p1 one vertex
074: * @param p2 another vertex
075: * @param p3 another vertex
076: * @param p4 another vertex
077: */
078: public Quadrilateral(Coordinate p1, Coordinate p2, Coordinate p3,
079: Coordinate p4) {
080: this .p1 = p1;
081: this .p2 = p2;
082: this .p3 = p3;
083: this .p4 = p4;
084: }
085:
086: private boolean diagonalsIntersect() {
087: return Line2D.linesIntersect(p1.x, p1.y, p3.x, p3.y, p2.x,
088: p2.y, p4.x, p4.y);
089: }
090:
091: /**
092: * Returns whether this Quadrilateral is a convex polygon.
093: * @return whether the diagonals intersect
094: */
095: public boolean isConvex() {
096: return diagonalsIntersect();
097: }
098:
099: /**
100: * Creates two Triangles from this Quadrilateral.
101: * @return two Triangles: P1-P2-P3 and P1-P4-P3
102: */
103: public List triangles() {
104: //Some callers depend on the fact that the two triangles are P1-P2-P3
105: //and P1-P4-P3. [Jon Aquino]
106: ArrayList triangles = new ArrayList();
107: triangles.add(new Triangle(p1, p2, p3));
108: triangles.add(new Triangle(p1, p4, p3));
109:
110: return triangles;
111: }
112:
113: private String toString(Coordinate c) {
114: return c.x + " " + c.y;
115: }
116:
117: public String toString() {
118: return "LINESTRING (" + toString(p1) + ", " + toString(p2)
119: + ", " + toString(p3) + ", " + toString(p4) + ", "
120: + toString(p1) + ")";
121: }
122:
123: /**
124: * Returns the first vertex.
125: * @return the first vertex
126: */
127: public Coordinate getP1() {
128: return p1;
129: }
130:
131: /**
132: * Returns the second vertex.
133: * @return the second vertex
134: */
135: public Coordinate getP2() {
136: return p2;
137: }
138:
139: /**
140: * Returns the third vertex.
141: * @return the third vertex
142: */
143: public Coordinate getP3() {
144: return p3;
145: }
146:
147: /**
148: * Returns the fourth vertex.
149: * @return the fourth vertex
150: */
151: public Coordinate getP4() {
152: return p4;
153: }
154:
155: /**
156: * Converts this Quadrilateral to a JTS Polygon.
157: * @return a new JTS Polygon with one shell and no holes
158: */
159: public Polygon toPolygon() {
160: return factory.createPolygon(
161: factory.createLinearRing(new Coordinate[] { p1, p2, p3,
162: p4, p1 }), null);
163: }
164:
165: /**
166: * Filters out points that lie inside this Quadrilateral
167: * @param vertices points to check
168: * @return those points which lie outside this Quadrilateral
169: */
170: public Collection verticesOutside(Collection vertices) {
171: ArrayList outsideVertices = new ArrayList();
172: Polygon quadrilateralPolygon = toPolygon();
173:
174: for (Iterator i = vertices.iterator(); i.hasNext();) {
175: Coordinate vertex = (Coordinate) i.next();
176: Point p = factory.createPoint(vertex);
177:
178: if (!quadrilateralPolygon.contains(p)) {
179: outsideVertices.add(vertex);
180: }
181: }
182:
183: return outsideVertices;
184: }
185: }
|