diff --git a/visualizationElements/Edge.java b/visualizationElements/Edge.java new file mode 100644 index 0000000..5557d42 --- /dev/null +++ b/visualizationElements/Edge.java @@ -0,0 +1,337 @@ +package visualizationElements; + +import java.awt.Color; +import java.awt.Graphics; + + +/** + * Represents an edge of a graph. + * @author MSchaefer + * + */ +public class Edge { + + private Vertex source; + private Vertex destination; + private Color color; + private String marking; + int[] xPoints; + int[] yPoints; + float baseX; + float baseY ; + + /** + * Creates a new Edge. + * @param source The vertex the edge starts at. + * @param destination The vertex the edge ends at. + * @param marking Marking of the edge. + * @param color Coloring the edge is drawn. + */ + public Edge(Vertex source, Vertex destination, String marking, Color color) { + + this.setSource(source); + this.setDestination(destination); + this.setColor(color); + this.setMarking(marking); + } + + + /** + * Creates a new Edge. + * @param source The vertex the edge starts at. + * @param destination The vertex the edge ends at. + * @param color Coloring the edge is drawn. + */ + public Edge(Vertex source, Vertex destination, Color color) { + + this.setSource(source); + this.setDestination(destination); + this.setColor(color); + this.setMarking(""); + } + + + /** + * Creates a new Edge. + * @param source The vertex the edge starts at. + * @param destination The vertex the edge ends at. + * @param marking Marking of the edge. + */ + public Edge(Vertex source, Vertex destination, String marking) { + + this.setSource(source); + this.setDestination(destination); + this.setColor(Color.BLACK); + this.setMarking(marking); + } + + + /** + * Creates a new Edge. + * @param source The vertex the edge starts at. + * @param destination The vertex the edge ends at. + */ + public Edge(Vertex source, Vertex destination) { + + this.setSource(source); + this.setDestination(destination); + this.setColor(Color.BLACK); + this.setMarking(""); + } + + + /** + * @param source the source to set + */ + public void setSource(Vertex source) { + this.source = source; + } + + + /** + * @return the source + */ + public Vertex getSource() { + return source; + } + + + /** + * @param destination the destination to set + */ + public void setDestination(Vertex destination) { + this.destination = destination; + } + + + /** + * @return the destination + */ + public Vertex getDestination() { + return destination; + } + + + /** + * @param color the color to set + */ + public void setColor(Color color) { + this.color = color; + } + + + /** + * @return the color + */ + public Color getColor() { + return color; + } + + + /** + * @param marking the marking to set + */ + public void setMarking(String marking) { + this.marking = marking; + } + + + /** + * @return the marking + */ + public String getMarking() { + return marking; + } + + + /** + * Draws an undirected double edge directly from one vertex to another. + * @param g Graphics object to draw to DrawArea. + */ + public void drawUndirectedDirectDoubleEdge(Graphics g) { + g.drawLine( getSource().getXpos() + (getSource().getVertexDiameter()/3), + getSource().getYpos() + (getSource().getVertexDiameter()/3), + getDestination().getXpos() + (getSource().getVertexDiameter()/3), + getDestination().getYpos() + (getSource().getVertexDiameter()/3)); + g.drawString(getMarking(), (getSource().getXpos() + getDestination().getXpos())/2, (getSource().getYpos() + getDestination().getYpos())/2); + + g.drawLine(getSource().getXpos() + ((2*getSource().getVertexDiameter())/3), + getSource().getYpos() + ((2*getSource().getVertexDiameter())/3), + getDestination().getXpos() + ((2*getSource().getVertexDiameter())/3), + getDestination().getYpos() + ((2*getSource().getVertexDiameter())/3)); + g.drawString(getMarking(), (getSource().getXpos() + getDestination().getXpos())/2 , (getSource().getYpos() + getDestination().getYpos())/2 + 35); + } + + + /** + * Draws an undirected loop. + * @param g Graphics object to draw to DrawArea. + */ + public void drawUndirectedLoop(Graphics g) { + g.drawOval(getSource().getXpos()+ getSource().getVertexDiameter()/2, getSource().getYpos()+getSource().getVertexDiameter()/2, getSource().getVertexDiameter(), getSource().getVertexDiameter()); + } + + + /** + * Draws an undirected edge directly from one vertex to another. + * @param g Graphics object to draw to DrawArea. + */ + public void drawUndirectedDirectEdge(Graphics g) { + g.drawLine(getSource().getXpos() + getSource().getVertexDiameter()/2, + getSource().getYpos() + getSource().getVertexDiameter()/2, + getDestination().getXpos() + getDestination().getVertexDiameter()/2, + getDestination().getYpos() + getDestination().getVertexDiameter()/2); + + g.drawString(getMarking(), (getSource().getXpos() + getDestination().getXpos())/2, (getSource().getYpos() + getDestination().getYpos())/2); + } + + + /** + * Draws an undirected angled loop. + * @param g Graphics object to draw to DrawArea. + */ + public void drawUndirectedAngeledLoop(Graphics g) { + g.drawRect(getSource().getXpos()+ getSource().getVertexDiameter()/2, getSource().getYpos() + getSource().getVertexDiameter()/2, getSource().getVertexDiameter(), getSource().getVertexDiameter()); + } + + + /** + * Draws an undirected angled edge from source vertex to destination vertex. + * @param g Graphics object to draw to DrawArea. + */ + public void drawUndirectedAngledEdge(Graphics g) { + g.drawLine(getSource().getXpos() + getSource().getVertexDiameter()/2, + getSource().getYpos() + getSource().getVertexDiameter()/2, + getSource().getXpos() + getSource().getVertexDiameter()/2, + getDestination().getYpos() + getDestination().getVertexDiameter()/2); + + g.drawLine(getSource().getXpos() + getSource().getVertexDiameter()/2, + getDestination().getYpos() + getDestination().getVertexDiameter()/2, + getDestination().getXpos() + getDestination().getVertexDiameter()/2, + getDestination().getYpos() + getDestination().getVertexDiameter()/2); + } + + + /** + * Draws a directed edge directly from source vertex to destination vertex. + * @param g Graphics object to draw to DrawArea. + */ + public void drawDirectedAngeledEdge(Graphics g) { + createArrowDataForDirectEdges(EdgeStyle.Angled); + + g.drawLine(getSource().getXpos() + getSource().getVertexDiameter()/2, + getSource().getYpos() + getSource().getVertexDiameter()/2, + getSource().getXpos() + getSource().getVertexDiameter()/2, + getDestination().getYpos() + getDestination().getVertexDiameter()/2); + + g.drawLine(getSource().getXpos() + getSource().getVertexDiameter()/2, + getDestination().getYpos() + getDestination().getVertexDiameter()/2, + getDestination().getXpos() + getDestination().getVertexDiameter()/2, + getDestination().getYpos() + getDestination().getVertexDiameter()/2); + g.fillPolygon(xPoints, yPoints, 3); + } + + + /** + * Draws a directed loop. + * @param g Graphics object to draw to DrawArea. + */ + public void drawDirectedLoop(Graphics g) { + createArrowDataForLoops(); + g.drawRect(getSource().getXpos() + getSource().getVertexDiameter()/2, getSource().getYpos() + getSource().getVertexDiameter()/2, 2*getSource().getVertexDiameter(), getSource().getVertexDiameter()); + g.fillPolygon(xPoints, yPoints, 3); + } + + + /** + * Draws a directed edge directly from source vertex to destination vertex. + * @param g Graphics object to draw to DrawArea. + */ + public void drawDirectedDirectEdge(Graphics g) { + createArrowDataForDirectEdges(EdgeStyle.Direct); + + g.drawLine( getSource().getXpos() + getSource().getVertexDiameter()/2, getSource().getYpos() + getSource().getVertexDiameter()/2, (int)baseX, (int)baseY ); + g.fillPolygon(xPoints, yPoints, 3); + } + + + /** + * Creates an arrow for directed edges. + */ + private void createArrowDataForDirectEdges(EdgeStyle edgeStyle) { + int sourceX = getSource().getXpos() + getSource().getVertexDiameter()/2; + + int sourceY; + if(edgeStyle == EdgeStyle.Direct){ + sourceY = getSource().getYpos() + getSource().getVertexDiameter()/2; + } + else{ + sourceY = getDestination().getYpos() + getDestination().getVertexDiameter()/2; + } + int destinationX = getDestination().getXpos() + getDestination().getVertexDiameter()/2; + int destinationY = getDestination().getYpos() + getDestination().getVertexDiameter()/2; + + createArrow(sourceX, sourceY, destinationX, destinationY); + } + + + /** + * Creates an arrow for directed loops. + */ + private void createArrowDataForLoops() { + int sourceX = getSource().getXpos() + getSource().getVertexDiameter()/2 + getSource().getVertexDiameter(); + int sourceY = getSource().getYpos() + getSource().getVertexDiameter()/2; + + int destinationX = getDestination().getXpos() + getDestination().getVertexDiameter()/2; + int destinationY = getDestination().getYpos() + getDestination().getVertexDiameter()/2; + + createArrow(sourceX, sourceY, destinationX, destinationY); + } + + + /** + * Creates data to draw an arrow for directed edges. + * @param sourceX x position of the source vertex. + * @param sourceY y position of the source vertex. + * @param destinationX x position of the destination vertex. + * @param destinationY y position of the destination vertex. + */ + private void createArrow(int sourceX, int sourceY, int destinationX,int destinationY) { + xPoints = new int[ 3 ] ; + yPoints = new int[ 3 ] ; + + float arrowWidth = 10.0f ; + float theta = 0.423f ; + float[] vecLine = new float[ 2 ] ; + float[] vecLeft = new float[ 2 ] ; + float fLength; + float th; + float ta; + + xPoints[ 0 ] = destinationX ; + yPoints[ 0 ] = destinationY ; + + // build the line vector + vecLine[ 0 ] = (float)xPoints[ 0 ] - sourceX ; + vecLine[ 1 ] = (float)yPoints[ 0 ] - sourceY ; + + // build the arrow base vector - normal to the line + vecLeft[ 0 ] = -vecLine[ 1 ] ; + vecLeft[ 1 ] = vecLine[ 0 ] ; + + // setup length parameters + fLength = (float)Math.sqrt( vecLine[0] * vecLine[0] + vecLine[1] * vecLine[1] ) ; + th = arrowWidth / ( 2.0f * fLength ) ; + ta = arrowWidth / ( 2.0f * ( (float)Math.tan( theta ) / 2.0f ) * fLength ) ; + + // find the base of the arrow + baseX = ( (float)xPoints[ 0 ] - ta * vecLine[0]); + baseY = ( (float)yPoints[ 0 ] - ta * vecLine[1]); + + // build the points on the sides of the arrow + xPoints[ 1 ] = (int)( baseX + th * vecLeft[0] ); + yPoints[ 1 ] = (int)( baseY + th * vecLeft[1] ); + xPoints[ 2 ] = (int)( baseX - th * vecLeft[0] ); + yPoints[ 2 ] = (int)( baseY - th * vecLeft[1] ); + } +} diff --git a/visualizationElements/EdgeStyle.java b/visualizationElements/EdgeStyle.java new file mode 100644 index 0000000..adf6530 --- /dev/null +++ b/visualizationElements/EdgeStyle.java @@ -0,0 +1,11 @@ +package visualizationElements; + +/** + * Enum to decide the style of an graph's edges. + * @author MSchaefer + * + */ +public enum EdgeStyle { + Direct, + Angled +} diff --git a/visualizationElements/Graph.java b/visualizationElements/Graph.java new file mode 100644 index 0000000..ea4ad78 --- /dev/null +++ b/visualizationElements/Graph.java @@ -0,0 +1,222 @@ +/** + * + */ +package visualizationElements; + +import java.awt.Graphics; +import java.util.Vector; + +/** + * Represents a graph to visualize search algorithms. + * @author MSchaefer + * + */ +public class Graph extends VisualizationElement{ + + private Vector vertexes; + private Vector edges; + private boolean isDirected; + private EdgeStyle edgeStyle; + + + /** + * Creates a new Graph. + * @param vertexes Vertexes containing to the graph. + * @param edges Edge containing to the graph. + * @param isDirected Value whether the graph is directed or undirected. + * @param edgeStyle Value in which style the edges will be drawn. + */ + public Graph(Vector vertexes, Vector edges, boolean isDirected, EdgeStyle edgeStyle){ + this.setVertexes(vertexes); + this.setEdges(edges); + this.setDirected(isDirected); + this.setEdgeStyle(edgeStyle); + } + + + @Override + public void draw(Graphics g){ + if(g != null){ + + // draw edges + for(Edge edge : edges){ + g.setColor(edge.getColor()); + + if(this.isDirected){ + if(this.edgeStyle == EdgeStyle.Direct){ + drawDirectedDirectEdge(g, edge); + } + else{ + drawDirectedAngeledEdge(g, edge); + } + } + // undirected Graph + else{ + if(this.edgeStyle == EdgeStyle.Direct){ + drawUndirectedDirectEdge(g, edge); + } + // angeled edges + else{ + drawUndirectedAngeledEdge(g, edge); + } + } + } + // draw all vertexes and print names marking + for(Vertex vertex : vertexes){ + vertex.draw(g); + } + } + } + + + /** + * @param isDirected the isDirected to set + */ + public void setDirected(boolean isDirected) { + this.isDirected = isDirected; + } + + /** + * @return the isDirected + */ + public boolean isDirected() { + return isDirected; + } + + /** + * @param edgeStyle the edgeStyle to set + */ + public void setEdgeStyle(EdgeStyle edgeStyle) { + this.edgeStyle = edgeStyle; + } + + + /** + * @return the edge style + */ + public EdgeStyle getEdgeStyle() { + return edgeStyle; + } + + + /** + * + * @param vertexes The vertexes of the graph. + */ + public void setVertexes(Vector vertexes) { + this.vertexes = vertexes; + } + + + /** + * + * @return the graph's vertexes. + */ + public Vector getVertexes() { + return vertexes; + } + + + /** + * + * @param edges The edges of the graph. + */ + public void setEdges(Vector edges) { + this.edges = edges; + } + + + /** + * + * @return the graph's edges. + */ + public Vector getEdges() { + return edges; + } + + + /** + * Draws an directed angled edge. + * @param g Graphics object to draw to drawArea. + * @param edge The edge to draw. + */ + private void drawDirectedAngeledEdge(Graphics g, Edge edge) { + // if the edge is a loop draw a rectangle + if(edge.getSource() == edge.getDestination()){ + //edge.drawDirectedAngeledLoop(g); + edge.drawDirectedLoop(g); + } + else{ + edge.drawDirectedAngeledEdge(g); + } + } + + + /** + * Draws an directed direct edge. + * @param g Graphics object to draw to drawArea. + * @param edge The edge to draw. + */ + private void drawDirectedDirectEdge(Graphics g, Edge edge){ + //drawArrow(g, edge); + if(edge.getSource() == ((Edge) edge).getDestination()){ + edge.drawDirectedLoop(g); + } + else{ + edge.drawDirectedDirectEdge(g); + } + } + + + /** + * Draws an undirected direct Edge. + * @param g Graphics object to draw to drawArea. + * @param edge The edge to draw. + */ + private void drawUndirectedDirectEdge(Graphics g, Edge edge) { + // if there is an double edge draw two lines + if(hasEdge(edge.getSource(), edge.getDestination()) && hasEdge(edge.getDestination(), edge.getSource()) && edge.getSource() != edge.getDestination()){ + edge.drawUndirectedDirectDoubleEdge(g); + } + else{ + // if the edge is a loop draw a oval, otherwise draw a line from source to destination + if(edge.getSource() == edge.getDestination()){ + edge.drawUndirectedLoop(g); + } + else{ + edge.drawUndirectedDirectEdge(g); + } + } + } + + + /** + * Draws an undirected angled Edge. + * @param g Graphics object to draw to drawArea. + * @param edge The edge to draw. + */ + private void drawUndirectedAngeledEdge(Graphics g, Edge edge) { + // if the edge is a loop draw a rectangle + if(edge.getSource() == ((Edge) edge).getDestination()){ + edge.drawUndirectedAngeledLoop(g); + } + else{ + edge.drawUndirectedAngledEdge(g); + } + } + + + /** + * Decides whether the graph has an edge between two vertexes. + * @param source The source vertex. + * @param destination The destination vertex. + * @return True if there is an edge between the two vertexes, false otherwise. + */ + private boolean hasEdge(Vertex source, Vertex destination) { + for(Edge edge : edges){ + if (edge.getSource() == source && edge.getDestination() == destination) + return true; + } + return false; + } +} diff --git a/visualizationElements/Hashtable.java b/visualizationElements/Hashtable.java new file mode 100644 index 0000000..8624d63 --- /dev/null +++ b/visualizationElements/Hashtable.java @@ -0,0 +1,26 @@ +package visualizationElements; + +/** + * Represents a hash table to visualize hash algorithms. + * @author MSchaefer + * + */ +public class Hashtable extends Table { + + private static final String OBJECT_CAPTION = "Object"; + private static final String HASHVALUE_CAPTION = "Hashvalue"; + + /** + * Creates a new Hashtable. + * @param values The values to display in the hash table. + */ + public Hashtable(Object[][] values){ + super(values, 2, values[0].length); + + String[] captions = new String[2]; + captions[0] = HASHVALUE_CAPTION; + captions[1] = OBJECT_CAPTION; + + super.setColumnCaptions(captions); + } +} diff --git a/visualizationElements/List.java b/visualizationElements/List.java new file mode 100644 index 0000000..67a6329 --- /dev/null +++ b/visualizationElements/List.java @@ -0,0 +1,69 @@ +package visualizationElements; + +import java.awt.Graphics; +import java.util.Vector; + +/** + * Represents the abstract data type List. + * @author MSchaefer + * + */ +public class List extends Table { + + + /** + * Creates a new List. + * @param values The values of the list. + */ + public List(Vector values) { + super(null, values.size(), 1); + + Object[][] tableArray = createTableArray(values); + + super.setValues(tableArray); + } + + + /** + * Creates a new List. + * @param values The values of the list. + */ + public List(Object[] values) { + super(null, values.length, 1); + + Object[][] tableArray = new Object[1][values.length]; + + int i = 0; + for(Object o : values){ + tableArray[0][i] = o; + i++; + } + + super.setValues(tableArray); + } + + + /* (non-Javadoc) + * @see visualizationElements.VisualizationElement#draw() + */ + @Override + public void draw(Graphics g) { + + super.draw(g); + } + + + /** + * Creates the array to visualize as list out from the vector. + * @param values Vector to convert. + * @return Array with values to visualizes as list. + */ + private Object[][] createTableArray(Vector values) { + String[][] tableArray = new String[1][values.size()]; + + for (int i = 0; i