/* * JFLAP - Formal Languages and Automata Package * * * Susan H. Rodger * Computer Science Department * Duke University * August 27, 2009 * Copyright (c) 2002-2009 * All rights reserved. * JFLAP is open source software. Please see the LICENSE for terms. * */ package automata.graph.layout; import java.awt.Dimension; import java.awt.geom.Point2D; import automata.graph.Graph; /** * A VertexChain that also has the ability to layout its vertices in a circle or part of a circle. * * @see VertexChain * @author Chris Morgan */ public class CircleChain extends VertexChain { /** * Distance from the center of the graph of the CircleChain. The polar coordinate r for all * vertices in the CircleChain. */ protected double radius; /** * The value for how much space in the graph a vertex is assumed to take. */ protected Dimension vertexDim; /** * The minimum space between vertices. */ protected double vertexBuffer; /** * Constructor. * * @param g * the graph from which edge information is processed. * @param vDim * value for vertexDim. * @param vBuffer * value for vertexBuffer. */ public CircleChain(Graph g, Dimension vDim, double vBuffer) { super(g); radius = 0; vertexDim = vDim; vertexBuffer = vBuffer; } /** * Returns the CircleChain's radius. * * @return the CircleChain's radius. */ public double getRadius() { return radius; } /** * Places the vertices of the CircleChain onto the graph associated with this * LayoutAlgorithm in a circle. All points assigned are in polar coordinates, * so they will eventually need to be converted in cartesian coordinates if displayed * on the screen. */ public void layoutInCircle() { layout(0, Math.PI, 2*Math.PI); } /** * Places the vertices of the CircleChain onto the graph associated with this * LayoutAlgorithm in a circle or part of a circle. All points assigned are in polar * coordinates, so they will eventually need to be converted in cartesian coordinates if displayed * on the screen. * * @param r * the starting radius from the graph's center from which the radius is calculated. * This is not necessarily the final radius, as the final radius, in order to * give each vertex ample room in the graph, gets larger based on the number of vertices in the chain. * @param midTheta * the degree, in radians, that represents the midpoint of the CircleChain * with respect to the center of the graph. * @param span * The degree, in radians, that represents the maximum degree of the circle part over which the * CircleChain can be laid out. This degree is in reference to a circle who's center is the * graph's center. */ public void layout(double r, double midTheta, double span) { //Is distance from a corner of the alloted space of a vertex to the center. double diagonalLength = Math.sqrt(Math.pow(vertexDim.getHeight(), 2) + Math.pow(vertexDim.getWidth(), 2)) + vertexBuffer; if (size() == 0) return; if (size() == 1) { if (r==0) graph.moveVertex(vertices.get(0), new Point2D.Double(0, 0)); else graph.moveVertex(vertices.get(0), new Point2D.Double(r+diagonalLength, midTheta)); return; } double startTheta, thetaDivision; int divisions; startTheta = midTheta - span / 2; if (2* Math.PI - span < .0001) //aka if it's a circle divisions = size(); else divisions = size() - 1; thetaDivision = span / divisions; //radius = circumference / 2pi = (diagonalLength * (2pi / thetaDivision)) / 2pi = diagonalLength / thetaDivision radius = diagonalLength / thetaDivision; //If starting radius + diagonallength > R, we want to use that as the radius from the center of //the graph instead. if (radius < r + diagonalLength) radius = r + diagonalLength; for (int i=0; i