/// <summary>
 /// Constructor specifying graph and shape information.
 /// </summary>
 /// <param name="obstacles">The collection of shapes to route around. Contains all source and target shapes
 /// as well as any intervening obstacles.</param>
 /// <param name="padding">The minimum padding from an obstacle's curve to its enclosing polyline.</param>
 /// <param name="cornerFitRadius">The radius of the arc inscribed into path corners</param>
 /// <param name="useSparseVisibilityGraph">If true, use a sparse visibility graph, which saves memory for large graphs
 /// but may select suboptimal paths</param>
 /// <param name="useObstacleRectangles">Use obstacle bounding boxes in visibility graph</param>
 public RectilinearEdgeRouter(IEnumerable<Shape> obstacles, double padding, double cornerFitRadius,
                             bool useSparseVisibilityGraph, bool useObstacleRectangles) {
     Padding = padding;
     CornerFitRadius = cornerFitRadius;
     BendPenaltyAsAPercentageOfDistance = SsstRectilinearPath.DefaultBendPenaltyAsAPercentageOfDistance;
     if (useSparseVisibilityGraph) {
         this.GraphGenerator = new SparseVisibilityGraphGenerator();
     } else {
         this.GraphGenerator = new FullVisibilityGraphGenerator();
     }
     this.UseObstacleRectangles = useObstacleRectangles;
     PortManager = new PortManager(GraphGenerator);
     AddShapes(obstacles);
 }
 internal PortManager(VisibilityGraphGenerator graphGenerator) {
     this.TransUtil = new TransientGraphUtility(graphGenerator);
     this.graphGenerator = graphGenerator;
 }
 internal TransientGraphUtility(VisibilityGraphGenerator graphGen) {
     GraphGenerator = graphGen;
 }