001 /*--------------------------------------------------------------------------+
002 $Id: GraphicsUtils.java 26268 2010-02-18 10:44:30Z juergens $
003 | |
004 | Copyright 2005-2010 Technische Universitaet Muenchen |
005 | |
006 | Licensed under the Apache License, Version 2.0 (the "License"); |
007 | you may not use this file except in compliance with the License. |
008 | You may obtain a copy of the License at |
009 | |
010 | http://www.apache.org/licenses/LICENSE-2.0 |
011 | |
012 | Unless required by applicable law or agreed to in writing, software |
013 | distributed under the License is distributed on an "AS IS" BASIS, |
014 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
015 | See the License for the specific language governing permissions and |
016 | limitations under the License. |
017 +--------------------------------------------------------------------------*/
018 package edu.tum.cs.commons.image;
019
020 import java.awt.Point;
021 import java.awt.Rectangle;
022 import java.awt.geom.GeneralPath;
023
024 /**
025 * Utility classes for graphics.
026 *
027 * @author hummelb
028 * @author $Author: juergens $
029 * @version $Rev: 26268 $
030 * @levd.rating GREEN Hash: 1143143992222183FB5A5906384AA829
031 */
032 public class GraphicsUtils {
033
034 /**
035 * Returns a path for the arrow at the end of an edge from p1 to p2.
036 *
037 * @param arrowBarbSize
038 * gives the size of the barb in pixels (i.e. the size of the
039 * arrow tip)
040 * @param arrowPhi
041 * gives the angle between the barbs and the center line, i.e.
042 * this is half of the angle of the arrow tip.
043 */
044 public static GeneralPath getArrowHead(Point p1, Point p2,
045 int arrowBarbSize, double arrowPhi) {
046 double theta = Math.atan2(p2.y - p1.y, p2.x - p1.x);
047
048 GeneralPath path = new GeneralPath();
049
050 // Add an arrow head at p2
051 double x = p2.x + arrowBarbSize * Math.cos(theta + Math.PI - arrowPhi);
052 double y = p2.y + arrowBarbSize * Math.sin(theta + Math.PI - arrowPhi);
053 path.moveTo((float) x, (float) y);
054 path.lineTo(p2.x, p2.y);
055 x = p2.x + arrowBarbSize * Math.cos(theta + Math.PI + arrowPhi);
056 y = p2.y + arrowBarbSize * Math.sin(theta + Math.PI + arrowPhi);
057 path.lineTo((float) x, (float) y);
058
059 return path;
060 }
061
062 /**
063 * The ChopboxAnchor's location is found by calculating the intersection of
064 * a line drawn from the center point of a box to a reference point and that
065 * box. Code borrowed from org.eclipse.draw2d.ChopboxAnchor.
066 */
067 public static Point getChopboxAnchor(Rectangle box, Point referencePoint) {
068
069 double baseX = box.getCenterX();
070 double baseY = box.getCenterY();
071 double refX = referencePoint.x;
072 double refY = referencePoint.y;
073
074 // This avoids divide-by-zero
075 if (box.isEmpty() || (refX == baseX && refY == baseY)) {
076 return new Point((int) refX, (int) refY);
077 }
078
079 double dx = refX - baseX;
080 double dy = refY - baseY;
081
082 // r.width, r.height, dx, and dy are guaranteed to be non-zero.
083 double scale = 0.5 / Math.max(Math.abs(dx) / box.width, Math.abs(dy)
084 / box.height);
085 baseX += dx * scale;
086 baseY += dy * scale;
087 return new Point((int) Math.round(baseX), (int) Math.round(baseY));
088 }
089 }