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