// The Main for the edge linking program Main { public static void main(String args[]) throws Exception {{ if (args.length < 9) { System.out.println("Usage: edgelink [image file name] [height] [width] [startx] [starty] [endx] [endy] [width] [output file name]"); System.exit(-1); } String fileName = args[0]; String imHeight = args[1]; String imWidth = args[2]; String startX = args[3]; String startY = args[4]; String targetX = args[5]; String targetY = args[6]; String width = args[7]; String outputFileName = args[8]; System.out.println("Processing file " + fileName); System.out.println("image size = " + imHeight + "x" + imWidth); System.out.println("src = ("+startX+","+startY+")" + "target = (" + targetX + ","+targetY+")"); System.out.println("width = " + width); //Graph g = Graph.parse(System.in); //PrintVisitor pv = new PrintVisitor(System.out); //g.universal_trv0(pv); //pv.finish(); //g.universal_trv0(new DisplayVisitor(System.out)); //System.out.flush(); //Graph.debug = true; Graph.printPath = true; // LineEquation.debgu = true; // set the source and target nodes PixelCoord src = PixelCoord.parse("("+startX+","+startY+")"); PixelCoord target = PixelCoord.parse("("+targetX+"," + targetY+")"); // create a new generator GraphGenerator newGen = new GraphGenerator(src, target); // read in the image file Image image = new Image(fileName, Integer.parseInt(imHeight), Integer.parseInt(imWidth)); System.out.println("image max = " + image.get_maxPixelVal() ); //image.print(); // set the costs for all of the nodes newGen.calculateCost(image); PrintVisitor pv = new PrintVisitor(System.out); newGen.get_generatedGraph().universal_trv0(pv); pv.finish(); // process the graph newGen.get_generatedGraph().ProcessGraph(); // obtain the output edge image Image outputImage = image.sameSizeBlank(); newGen.get_generatedGraph().getOutputImage(outputImage); //outputImage.print(); outputImage.save(outputFileName); }} } Graph { // the debug variable to turn on and off the messages {{ public static boolean debug = false; }} // the variable for printing the shortest path {{ public static boolean printPath = false; }} // Method to process the Graph public void ProcessGraph() {{ if (debug) System.out.println("PrcessGraph"); // First Connect the Graph ConnectGraph(); // Run the searching algorithm SearchGraph(); // Output the shortest path for debug if (printPath) PrintShortestPath(); }} ////////////////////////////////////////////////////////////// // print the shortest path that was found public void PrintShortestPath() {{ SourceNode path = findShortestSource(); path.printPath(); }} public SourceNode findShortestSource() bypassing {NodeList, PathData} to SourceNode { {{ SourceNode returnVal = null; }} before SourceNode {{ if (returnVal == null) returnVal = host; else if (returnVal.getPathCost() > host.getPathCost()) returnVal = host; }} return SourceNode {{ returnVal; }} } ////////////////////////////////////////////////////////////// // Search the graph for the shortest path public void SearchGraph() bypassing {NodeList, PathData} to SourceNode { before SourceNode {{ if (Graph.debug) System.out.println("SearchStarted"); host.SearchGraph(); if (Graph.debug) System.out.println("SearchEnded"); }} } ////////////////////////////////////////////////////////////// // Connect the actual graph for the graph searching // algorithm. public void ConnectGraph() {{ // get the graph node list GraphNode_List nodeList = get_graphnode_list(); // for each node find it's possible exits findPossibleExits(nodeList); }} public void findPossibleExits(GraphNode_List nodelist) bypassing {PathData, ->*,tail,*, NodeList} to GraphNode { before SourceNode {{ if (Graph.debug) System.out.println("findPossibleExits"); //gather all exit nodes for NodeList exitNodes = nodelist.gatherExits(host.get_edgeloc()); if (exitNodes == null) host.setCostToInfinite(); // set the exit nodes host.set_nodelist(exitNodes); }} before IntermediateNode {{ NodeList exitNodes = null; // gather all exit nodes for if (host.get_edgeloc() !=null) { exitNodes = nodelist.gatherExits(host.get_edgeloc()); } if (exitNodes == null) host.setCostToInfinite(); // set the exit nodes host.set_nodelist(exitNodes); }} } ////////////////////////////////////////////////////////////// // generate the edge image public void getOutputImage(Image im) {{ SourceNode path = findShortestSource(); path.getOutputImage(im); }} } // method for source node SourceNode { public void SearchGraph() bypassing {PathData, ->*,tail,* } to TargetNode { {{ Stack pathStack = new Stack(); }} {{ SourceNode srcNode = null; }} before SourceNode {{ srcNode = host; if (Graph.debug){ System.out.println("setting new src node"); host.printNode(); System.out.println(); } }} before IntermediateNode {{ if (Graph.debug) { System.out.println("Pushing node"); host.printNode(); System.out.println(); } pathStack.push(host); }} after IntermediateNode {{ GraphNode foo = (GraphNode) pathStack.pop(); if (Graph.debug) { System.out.println("Poping node"); foo.printNode(); System.out.println(); } GraphNode predecessor = null; if (pathStack.empty()) { predecessor = srcNode; } else { predecessor = (GraphNode) pathStack.peek(); } int predPathCost = predecessor.getPathCost(); // if My cost is infinite, then just forget // it, I'm not going to attempt to use me as the // optimal path, but need to set my predecessor // to infinite as well so that this path // won't be used if (host.costIsInfinite() || host.pathCostIsInfinite()) { if (predPathCost == -1) predecessor.setPathCostToInfinite(); return; } int myCost = host.getCost(); int myPathCost = host.getPathCost(); int myNewPathCost = myCost + myPathCost; if (Graph.debug) System.out.println("prePathCost = " + predPathCost + " myNewPathCost = " + myNewPathCost); if (predPathCost == -1 || myNewPathCost < predPathCost) { if (Graph.debug) { System.out.println("Setting new path with cost " + myNewPathCost); host.printNode(); System.out.println(); } predecessor.setNewPath(myNewPathCost, host); } }} after TargetNode {{ GraphNode predecessor = null; if (pathStack.empty()) { predecessor = srcNode; } else { predecessor = (GraphNode) pathStack.peek(); } int predPathCost = predecessor.getPathCost(); int myNewPathCost = host.getCost(); if (predPathCost == -1 || myNewPathCost < predPathCost) { if (Graph.debug) { System.out.println("Setting new path with cost " + myNewPathCost); host.printNode(); System.out.println(); } predecessor.setNewPath(myNewPathCost, host); } }} } public void printPath() bypassing NodeList to TargetNode { {{ PrintVisitor pv = new PrintVisitor(System.out); }} before SourceNode {{ System.out.println("Shortest Path with cost " + host.getPathCost()); host.printNode(pv); System.out.println(); }} before IntermediateNode {{ host.printNode(pv); System.out.println(); }} before TargetNode {{ host.printNode(pv); System.out.println(); }} } public void getOutputImage(Image im) bypassing NodeList to TargetNode { {{ PrintVisitor pv = new PrintVisitor(System.out); }} before SourceNode {{ //System.out.println("Shortest Path with cost " + host.getPathCost()); //host.printNode(pv); //System.out.println(); }} before IntermediateNode {{ im.setPixel(host.get_edgeloc().get_right(), 1); //host.printNode(pv); //System.out.println(); }} before TargetNode {{ //host.printNode(pv); //System.out.println(); }} } } // methods for GraphNode GraphNode { public void printNode() {{ printNode(new PrintVisitor(System.out)); }} // printNode public void printNode(PrintVisitor pv) {{ get_edgeloc().universal_trv0(pv); pv.finish(); System.out.print(getCost()); }} // getPathCost public int getPathCost() bypassing {PathData, NodeList} to NodeData { {{ int returnVal = -1; }} before NodeData {{ if (host.get_pathdata() != null) returnVal = host.get_pathdata().get_pathCost(); }} return int {{ returnVal }} } // getCost public int getCost() bypassing {PathData, NodeList} to NodeData { {{ int returnVal = 0; }} before NodeData {{ returnVal = host.get_cost(); }} return int {{ returnVal }} } // setNewPath public void setNewPath(int newCost, GraphNode newPath) bypassing {PathData, NodeList} to NodeData { before NodeData {{ PathData thisPath = null; if (host.get_pathdata() == null) { host.set_pathdata(new PathData(newCost, newPath)); } else { host.get_pathdata().set_pathCost(newCost); host.get_pathdata().set_path(newPath); } }} } // setNewPathCost public void setPathCostToInfinite() bypassing {PathData, NodeList} to NodeData { before NodeData {{ PathData thisPath = null; if (host.get_pathdata() == null) { host.set_pathdata(new PathData(GraphGenerator.InfiniteCost, null)); } else { host.get_pathdata().set_pathCost(GraphGenerator.InfiniteCost); } }} } } // method for intermediate node list GraphNode_List { {{ public NodeList gatherExits(EdgeLoc edgeloc) { NodeList returnVal = gatherExitsWrapper(edgeloc); if (returnVal.get_graphNodeList() == null) return null; return returnVal; } }} public NodeList gatherExitsWrapper(EdgeLoc edgeloc) bypassing {NodeList, PathData} to GraphNode { {{ NodeList returnNodeList = new NodeList(); }} before GraphNode {{ EdgeLoc thisEdgeLoc = host.get_edgeloc(); if (thisEdgeLoc.isExitOf(edgeloc)) { if (Graph.debug) { PrintVisitor pv = new PrintVisitor(System.out); System.out.println("Exit for:"); edgeloc.universal_trv0(pv); pv.finish(); System.out.println(); System.out.println("is:"); thisEdgeLoc.universal_trv0(pv); pv.finish(); System.out.println(); } returnNodeList.addGraphNode(host); } }} return NodeList {{ returnNodeList }} } } // code for NodeList NodeList { public void addGraphNode(GraphNode node) {{ if (graphNodeList == null) graphNodeList = new GraphNode_ListP(); graphNodeList.addElement(node); }} } // code for edgeloc EdgeLoc { public boolean isExitOf(EdgeLoc src) {{ // is the exit of src edge if, // turning left, // turning right, // or is continuing in the same direction. if (isTurningLeft(src) || isTurningRight(src) || isSameDirection(src)) return true; else return false; }} public boolean isTurningLeft(EdgeLoc src) {{ PixelCoord srcLeft = src.get_left(); PixelCoord srcRight = src.get_right(); PixelCoord myLeft = get_left(); PixelCoord myRight = get_right(); // if my left is equal to the src's left then // we're turning left. We have 4 cases, // -1,1 1,1 1,-1 -1,-1 if (myLeft.isEqual(srcLeft)) { int srcx = srcRight.get_x(); int srcy = srcRight.get_y(); int myx = myRight.get_x(); int myy = myRight.get_y(); if(((srcLeft.get_x() == srcx) && (((srcx-1) == myx && (srcy+1) == myy) ||((srcx+1) == myx && (srcy-1) == myy))) || ((srcLeft.get_y() == srcy) && (((srcx+1) == myx && (srcy+1) == myy) ||((srcx-1) == myx && (srcy-1) == myy)))) { if (Graph.debug) System.out.println("turning left"); return true; } } return false; }} public boolean isTurningRight(EdgeLoc src) {{ PixelCoord srcLeft = src.get_left(); PixelCoord srcRight = src.get_right(); PixelCoord myLeft = get_left(); PixelCoord myRight = get_right(); // if my right is equal to the src's right then // we're turning right. We have 4 cases, // -1,1 1,1 1,-1 -1,-1 if (myRight.isEqual(srcRight)) { int srcx = srcLeft.get_x(); int srcy = srcLeft.get_y(); int myx = myLeft.get_x(); int myy = myLeft.get_y(); if(((srcRight.get_y() == srcy) && (((srcx-1) == myx && (srcy+1) == myy) ||((srcx+1) == myx && (srcy-1) == myy))) || ((srcRight.get_x() == srcx) && (((srcx+1) == myx && (srcy+1) == myy) ||((srcx-1) == myx && (srcy-1) == myy)))) { if (Graph.debug) System.out.println("Turing Right"); return true; } } return false; }} public boolean isSameDirection(EdgeLoc src) {{ PixelCoord srcLeft = src.get_left(); PixelCoord srcRight = src.get_right(); PixelCoord myLeft = get_left(); PixelCoord myRight = get_right(); // we're contiuing down the same direction if // going vertical, // going horizonal, if (srcLeft.get_y() == srcRight.get_y() && myLeft.get_y() == myRight.get_y() && srcLeft.get_x() == myLeft.get_x() && srcRight.get_x() == myRight.get_x() ) { int direction = srcRight.get_x()- srcLeft.get_x(); int leftDiff = srcLeft.get_y() - myLeft.get_y(); int rightDiff = srcRight.get_y() - myRight.get_y(); if ( leftDiff == rightDiff && (leftDiff*direction == 1) ) { if (Graph.debug) System.out.println("Same direction"); return true; } } else if (srcLeft.get_x() == srcRight.get_x() && myLeft.get_x() == myRight.get_x() && srcLeft.get_y() == myLeft.get_y() && srcRight.get_y() == myRight.get_y() ) { int direction = srcLeft.get_y() - srcRight.get_y(); int leftDiff = srcLeft.get_x() - myLeft.get_x(); int rightDiff = srcRight.get_x() - myRight.get_x(); if ( leftDiff == rightDiff && (leftDiff*direction == 1) ) { if (Graph.debug) System.out.println("Same direction"); return true; } } return false; }} } PixelCoord { public boolean isEqual(PixelCoord right) {{ if (get_x() == right.get_x() && get_y() == right.get_y()) return true; return false; }} }