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 }