/* * This file is part of the Trickl Open Source Libraries. * * Trickl Open Source Libraries - http://open.trickl.com/ * * Copyright (C) 2011 Tim Gee. * * Trickl Open Source Libraries are free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Trickl Open Source Libraries are distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this project. If not, see <http://www.gnu.org/licenses/>. */ package com.trickl.graph.planar.generate; import com.trickl.graph.planar.PlanarGraph; import com.trickl.graph.planar.PlanarLayout; import com.vividsolutions.jts.geom.Coordinate; import java.util.ArrayList; import java.util.HashMap; import java.util.Map; import org.jgrapht.VertexFactory; public class PlanarSquareGraphGenerator<V, E> implements PlanarGraphGenerator<V, E, V>, PlanarLayout<V> { private Map<V, Coordinate> positions = new HashMap<V, Coordinate>(); private ArrayList<V> vertices = new ArrayList<V>(); private final int size; private final double scale; public PlanarSquareGraphGenerator(int size) { this(size, 1); } public PlanarSquareGraphGenerator(int size, double scale) { this.size = size; this.scale = scale; } @Override public void generateGraph(PlanarGraph<V,E> graph, VertexFactory<V> vertexFactory, java.util.Map<java.lang.String,V> resultMap) { int width = ((int) Math.sqrt(size - 1)) + 1; for (int k = 0; k < size; ++k) { V vertex = vertexFactory.createVertex(); vertices.add(vertex); graph.addVertex(vertex); } for (int k = 0; k < size; ++k) { V vertex = vertices.get(k); int i = k % width; int j = k / width; // Build upwards (positive j = top) int k_left = (i - 1) + j * width; int k_right = (i + 1) + j * width; int k_top = i + (j + 1) * width; int k_bottom = i + (j - 1) * width; V bottom = null; V left = null; V top = null; V right = null; // Add edges cyclically to ensure planarity if (j != 0 && k_bottom < size) { bottom = vertices.get(k_bottom); } if (i != 0 && k_left < size) { left = vertices.get(k_left); } if (j != width - 1 && k_top < size) { top = vertices.get(k_top); } if (i != width - 1 && k_right < size) { right = vertices.get(k_right); } if (right != null) graph.addEdge(vertex, right, bottom, null); if (top != null) graph.addEdge(vertex, top, right == null ? bottom : right, null); if (left != null) graph.addEdge(vertex, left, top, null); if (bottom != null) graph.addEdge(vertex, bottom, left, null); positions.put(vertex, new Coordinate((i - width * 0.5) * scale, (j - width * 0.5) * scale)); } } @Override public Coordinate getCoordinate(V vertex) { return positions.get(vertex); } }