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: * JUMP is Copyright (C) 2003 Vivid Solutions
006: *
007: * This program implements extensions to JUMP and is
008: * Copyright (C) 2004 Integrated Systems Analysts, Inc.
009: *
010: * This program is free software; you can redistribute it and/or
011: * modify it under the terms of the GNU General Public License
012: * as published by the Free Software Foundation; either version 2
013: * of the License, or (at your option) any later version.
014: *
015: * This program is distributed in the hope that it will be useful,
016: * but WITHOUT ANY WARRANTY; without even the implied warranty of
017: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
018: * GNU General Public License for more details.
019: *
020: * You should have received a copy of the GNU General Public License
021: * along with this program; if not, write to the Free Software
022: * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
023: *
024: * For more information, contact:
025: *
026: * Integrated Systems Analysts, Inc.
027: * 630C Anchors St., Suite 101
028: * Fort Walton Beach, Florida
029: * USA
030: *
031: * (850)862-7321
032: */
033:
034: package org.openjump.core.ui.plugin.edittoolbox.cursortools;
035:
036: import java.awt.Shape;
037: import java.awt.geom.GeneralPath;
038: import java.awt.geom.NoninvertibleTransformException;
039: import java.awt.geom.Point2D;
040:
041: import org.openjump.core.geomutils.Arc;
042: import org.openjump.core.geomutils.GeoUtils;
043: import org.openjump.core.geomutils.MathVector;
044:
045: import com.vividsolutions.jts.geom.Coordinate;
046: import com.vividsolutions.jts.geom.CoordinateList;
047:
048: /**
049: * A VisualIndicatorTool that allows the user to draw shapes with multiple
050: * vertices. Double-clicking ends the gesture.
051: */
052: public abstract class ConstrainedMultiClickArcTool extends
053: ConstrainedMultiClickTool {
054: protected boolean clockwise = true;
055: protected double fullAngle = 0.0;
056:
057: protected Shape getShape() throws NoninvertibleTransformException {
058: if (coordinates.size() > 1) {
059: GeneralPath path = new GeneralPath();
060: Coordinate firstCoordinate = (Coordinate) coordinates
061: .get(0);
062: Point2D firstPoint = getPanel().getViewport().toViewPoint(
063: firstCoordinate);
064: path.moveTo((float) firstPoint.getX(), (float) firstPoint
065: .getY());
066:
067: Coordinate secondCoordinate = (Coordinate) coordinates
068: .get(1);
069: Point2D secondPoint = getPanel().getViewport().toViewPoint(
070: secondCoordinate);
071: path.lineTo((float) secondPoint.getX(), (float) secondPoint
072: .getY());
073:
074: MathVector v1 = (new MathVector(secondCoordinate))
075: .vectorBetween(new MathVector(firstCoordinate));
076: MathVector v2 = (new MathVector(tentativeCoordinate))
077: .vectorBetween(new MathVector(firstCoordinate));
078: double arcAngle = v1.angleDeg(v2);
079:
080: boolean toRight = new GeoUtils().pointToRight(
081: tentativeCoordinate, firstCoordinate,
082: secondCoordinate);
083:
084: boolean cwQuad = ((fullAngle >= 0.0) && (fullAngle <= 90.0) && clockwise);
085: boolean ccwQuad = ((fullAngle < 0.0)
086: && (fullAngle >= -90.0) && !clockwise);
087: if ((arcAngle <= 90.0) && (cwQuad || ccwQuad)) {
088: if (toRight)
089: clockwise = true;
090: else
091: clockwise = false;
092: }
093:
094: if ((fullAngle > 90.0) || (fullAngle < -90)) {
095: if ((clockwise && !toRight) || (!clockwise && toRight))
096: fullAngle = 360 - arcAngle;
097: else
098: fullAngle = arcAngle;
099: } else {
100: fullAngle = arcAngle;
101: }
102:
103: if (!clockwise)
104: fullAngle = -fullAngle;
105:
106: Arc arc = new Arc(firstCoordinate, secondCoordinate,
107: fullAngle);
108: CoordinateList coords = arc.getCoordinates();
109:
110: for (int i = 1; i < coords.size(); i++) {
111: Point2D nextPoint = getPanel().getViewport()
112: .toViewPoint((Coordinate) coords.get(i));
113: path.lineTo((int) nextPoint.getX(), (int) nextPoint
114: .getY());
115: }
116: return path;
117: } else {
118: return super.getShape();
119: }
120: }
121: }
|