/// <summary>
        /// Writes the graph to a file
        /// </summary>
        public void Write()
        {
            CultureInfo currentCulture = Thread.CurrentThread.CurrentCulture;
            Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture;
            var matrix = new PlaneTransformation(1, 0, 0, 0, -1, 0);

            try
            {
                graph.GeometryGraph.Transform(matrix);
                Open();
                WriteGraphAttr(graph.Attr);
                WriteLabel(graph.Label);
                WriteEdges();
                WriteNodes();
                
#if DEBUG && TEST_MSAGL
                WriteDebugCurves();
#endif
                Close();
            }
            finally
            {
                //restore the culture
                graph.GeometryGraph.Transform(matrix);
                Thread.CurrentThread.CurrentCulture = currentCulture;
            }
        }
        static void PostRunTransform(GeometryGraph geometryGraph, PlaneTransformation transformation)
        {
            bool transform = !transformation.IsIdentity;
            if (transform)
            {
                foreach (Node n in geometryGraph.Nodes)
                {
                    n.Transform(transformation);
                }

                //restore labels widths and heights
                foreach (Edge e in geometryGraph.Edges)
                {
                    if (e.Label != null)
                    {
                        e.Label.Width = e.OriginalLabelWidth;
                        e.Label.Height = e.OriginalLabelHeight;
                    }
                }

                TransformCurves(geometryGraph, transformation);
            }

            geometryGraph.UpdateBoundingBox();
        }
示例#3
0
        /// <summary>
        /// returns the transformed polyline
        /// </summary>
        /// <param name="transformation"></param>
        /// <returns></returns>
        public ICurve Transform(PlaneTransformation transformation)
        {
            if (transformation == null)
            {
                return(this);
            }
            var poly = new Polyline {
                Closed = Closed
            };

            foreach (var p in this)
            {
                poly.AddPoint(transformation * p);
            }

            return(poly);
        }
        public static void SetGraphTransform(GeometryGraph geometryGraph, System.Drawing.Rectangle rectangle) {
            //instead of setting transormation for graphics we are going to transform the geometry graph, just to test that GeometryGraph.Transform() works
            RectangleF clientRectangle = rectangle;
            var gr = geometryGraph.BoundingBox;
            if (clientRectangle.Height > 1 && clientRectangle.Width > 1) {
                var scale = Math.Min(clientRectangle.Width * 0.9 / gr.Width, clientRectangle.Height * 0.9 / gr.Height);
                var g0 = (gr.Left + gr.Right) / 2;
                var g1 = (gr.Top + gr.Bottom) / 2;

                var c0 = (clientRectangle.Left + clientRectangle.Right) / 2;
                var c1 = (clientRectangle.Top + clientRectangle.Bottom) / 2;
                var dx = c0 - scale * g0;
                var dy = c1 - scale * g1;
                var planeTransformation=new PlaneTransformation(scale,0,dx, 0, scale, dy); 
                geometryGraph.Transform(planeTransformation);
            }
        }
        internal static void PreRunTransform(GeometryGraph geomGraph, PlaneTransformation matrix) {
            if (matrix.IsIdentity) return;
            var matrixInverse = matrix.Inverse;
            foreach (Node n in geomGraph.Nodes)
                n.Transform(matrixInverse);
            //calculate new label widths and heights
            foreach (Edge e in geomGraph.Edges) {
                if (e.Label != null) {
                    e.OriginalLabelWidth = e.Label.Width;
                    e.OriginalLabelHeight = e.Label.Height;
                    var r = new Rectangle(matrixInverse*new Point(0, 0), matrixInverse*new Point(e.Label.Width, e.Label.Height));
                    e.Label.Width = r.Width;
                    e.Label.Height = r.Height;
                }
            }

            geomGraph.UpdateBoundingBox();
        }
#pragma warning disable 1591
        public void ScaleNodeAroundCenter(IViewerNode viewerNode, double scale) {
#pragma warning restore 1591
            var nodePosition = viewerNode.Node.BoundingBox.Center;
            var scaleMatrix = new PlaneTransformation(scale, 0, 0, 0, scale, 0);
            var translateToOrigin = new PlaneTransformation(1, 0, -nodePosition.X, 0, 1, -nodePosition.Y);
            var translateToNode = new PlaneTransformation(1, 0, nodePosition.X, 0, 1, nodePosition.Y);
            var matrix = translateToNode*scaleMatrix*translateToOrigin;
            viewerNode.Node.GeometryNode.BoundaryCurve=viewerNode.Node.GeometryNode.BoundaryCurve.Transform(matrix);
            viewer.Invalidate(viewerNode);
            foreach (var edge in viewerNode.OutEdges.Concat(viewerNode.InEdges).Concat(viewerNode.SelfEdges))
                RecoverEdge(edge);
        }
        /// <summary>
        /// Check whether graph layers in a vertical order
        /// </summary>
        /// <returns>True if layer is based on node Y coordinate</returns>
        private static bool IsVerticallyLayered(PlaneTransformation transformation)
        {
            //just check LR and RL cases first, other than that, assume to be TD or DT
            PlaneTransformation leftRight = PlaneTransformation.Rotation(Math.PI / 2);
            bool horizontial = true;
            for (int i = 0; i < 2; i++)
            {
                for (int j = 0; j < 3; j++)
                {
                    if (Math.Abs(transformation.Elements[i][j] - leftRight.Elements[i][j]) > Tolerance)
                    {
                        horizontial = false;
                        break;
                    }
                }
                if (!horizontial)
                {
                    break;
                }
            }

            if (horizontial)
            {
                return false;
            }

            PlaneTransformation rightLeft = PlaneTransformation.Rotation(-Math.PI / 2);
            horizontial = true;
            for (int i = 0; i < 2; i++)
            {
                for (int j = 0; j < 3; j++)
                {
                    if (Math.Abs(transformation.Elements[i][j] - rightLeft.Elements[i][j]) > Tolerance)
                    {
                        horizontial = false;
                        break;
                    }
                }
                if (!horizontial)
                {
                    break;
                }
            }

            return !horizontial;
        }
 void WriteTransformation(PlaneTransformation transformation) {
     WriteStartElement(GeometryToken.Transform);
     XmlWriter.WriteComment("the order of elements is [0,0],[0,1],[0,2],[1,0],[1,1],[1,2]");
     for (int i = 0; i < 2; i++)
         for (int j = 0; j < 3; j++)
             WriteTransformationElement(transformation[i, j]);
     WriteEndElement();
 }
 /// <summary>
 /// matrix matrix multiplication
 /// </summary>
 /// <param name="a"></param>
 /// <param name="b"></param>
 /// <returns></returns>
 static public PlaneTransformation Multiply(PlaneTransformation a, PlaneTransformation b) {
     if (a != null && b != null)
         return new PlaneTransformation(
            a[0, 0] * b[0, 0] + a[0, 1] * b[1, 0], a[0, 0] * b[0, 1] + a[0, 1] * b[1, 1], a[0, 0] * b[0, 2] + a[0, 1] * b[1, 2] + a[0, 2],
            a[1, 0] * b[0, 0] + a[1, 1] * b[1, 0], a[1, 0] * b[0, 1] + a[1, 1] * b[1, 1], a[1, 0] * b[0, 2] + a[1, 1] * b[1, 2] + a[1, 2]);
     return null;
 }
 /// <summary>
 /// Point by matrix multiplication
 /// </summary>
 /// <param name="transformation"></param>
 /// <param name="point"></param>
 /// <returns></returns>
 static public Point Multiply(PlaneTransformation transformation, Point point) {
     if (transformation != null)
         return new Point(transformation[0, 0] * point.X + transformation[0, 1] * point.Y + transformation[0, 2], transformation[1, 0] * point.X + transformation[1, 1] * point.Y + transformation[1, 2]);
     return new Point();
 }
 /// <summary>
 /// Divid matrix by a matrix
 /// </summary>
 /// <param name="transformation0"></param>
 /// <param name="transformation1"></param>
 /// <returns></returns>
 static public PlaneTransformation Divide(PlaneTransformation transformation0, PlaneTransformation transformation1) {
     return transformation0 / transformation1;
 }
 /// <summary>
 /// Return the transformed curve
 /// </summary>
 /// <param name="transformation"></param>
 /// <returns>the transformed curve</returns>
 public ICurve Transform(PlaneTransformation transformation)
 {
     return(new LineSegment(transformation * a, transformation * b));
 }
        ICurve ReadEllepticalArc(CurveStream curveStream, ref Point currentPoint) {
            /*
            var rx = "A"+DoubleToString(ellipse.AxisA.Length);
            var ry = DoubleToString(ellipse.AxisB.Length);
            var xAxisRotation = DoubleToString(180*Point.Angle(new Point(1, 0), ellipse.AxisA)/Math.PI);
            var largeArcFlag = Math.Abs(ellipse.ParEnd - ellipse.ParStart) >= Math.PI ? "1" : "0";
            var sweepFlag = ellipse.ParEnd > ellipse.ParStart ? "1" : "0"; //it happens because of the y-axis orientation down in SVG
            var endPoint=PointToString(ellipse.End);
            return string.Join(" ", new[] {rx, ry, xAxisRotation, largeArcFlag, sweepFlag, endPoint});
            var endPoint = GetCurveDataPoint(curveStream);
             */
            var rx = GetNextDoubleFromCurveData(curveStream);
            var ry = GetNextDoubleFromCurveData(curveStream);
            var xAxisRotation = GetNextDoubleFromCurveData(curveStream)/180*Math.PI;
            var largeArcFlag = (int) GetNextDoubleFromCurveData(curveStream);
            var sweepFlag = (int) GetNextDoubleFromCurveData(curveStream);
            var endPoint = GetNextPointFromCurveData(curveStream);
            //figure out the transform to the circle
            //then solve this problem on the circle
            if (ApproximateComparer.Close(rx, 0) || ApproximateComparer.Close(ry, 0))
                Error("ellipseArc radius is too small");
            var yScale = rx/ry;
            var rotationMatrix = PlaneTransformation.Rotation(-xAxisRotation);
            var scaleMatrix = new PlaneTransformation(1, 0, 0, 0, yScale, 0);
            var transform = scaleMatrix*rotationMatrix;
            var start = transform*currentPoint;
            currentPoint = endPoint;
            var end = transform*endPoint;
            Point center;
            double startAngle;
            double endAngle;
            Point axisY;
            GetArcCenterAndAngles(rx, largeArcFlag, sweepFlag, start, end, out center, out startAngle, out endAngle,
                out axisY);
            var inverted = transform.Inverse;
            center = inverted*center;
            var rotation = PlaneTransformation.Rotation(xAxisRotation);
            var axisX = rotation*new Point(rx, 0);
            axisY = rotation*(axisY/yScale);
            var ret = new Ellipse(startAngle, endAngle, axisX, axisY, center);

            Debug.Assert(ApproximateComparer.Close(ret.End, endPoint));
            return ret;
        }
示例#14
0
        internal void SetTransformOnScaleAndCenter(double scale, Point sourceCenter)
        {
            if (OriginalGraph!=null && OriginalGraph.BoundingBox.Diagonal * scale < 5) //less than 5 pixels
                return;

            var dx = PanelWidth/2.0 - scale*sourceCenter.X;
            var dy = PanelHeight/2.0 + scale*sourceCenter.Y;
            transformation = new PlaneTransformation(scale, 0, dx, 0, -scale, dy);
        }
 static bool HandleTransformIsNotIdentity(GeometryGraph geometryGraph, SugiyamaLayoutSettings sugiyamaLayoutSettings,
     out PlaneTransformation originalTransform) {
     var transformIsNotIdentity = !sugiyamaLayoutSettings.Transformation.IsIdentity;
     originalTransform = sugiyamaLayoutSettings.Transformation;
     if (transformIsNotIdentity) {
         var m = sugiyamaLayoutSettings.Transformation.Inverse;
         foreach (Node n in geometryGraph.Nodes) n.Transform(m);
         //calculate new label widths and heights
         foreach (Edge e in geometryGraph.Edges) {
             if (e.Label != null) {
                 e.OriginalLabelWidth = e.Label.Width;
                 e.OriginalLabelHeight = e.Label.Height;
                 var r = new Rectangle(m*new Point(0, 0), m*new Point(e.Label.Width, e.Label.Height));
                 e.Label.Width = r.Width;
                 e.Label.Height = r.Height;
             }
         }
     }
     sugiyamaLayoutSettings.Transformation = PlaneTransformation.UnitTransformation; //restore it later
     return transformIsNotIdentity;
 }
 ///<summary>
 ///</summary>
 ///<param name="transformation"></param>
 public void Transform(PlaneTransformation transformation) {
     if (BoundaryCurve != null)
         BoundaryCurve = BoundaryCurve.Transform(transformation);
 }
 void ReadTransform(PlaneTransformation transform) {
     XmlRead();
     if (TokenIs(GeometryToken.Transform)) {
         XmlRead();
         for (int i = 0; i < 2; i++)
             for (int j = 0; j < 3; j++) {
                 CheckToken(GeometryToken.TransformElement);
                 MoveToContent();
                 transform[i, j] = ReadElementContentAsDouble();
             }
         XmlRead();
     }
     else {
         //set the unit transform
         transform[0, 0] = 1;
         transform[0, 1] = 0;
         transform[0, 2] = 0;
         transform[1, 0] = 0;
         transform[1, 1] = 1;
         transform[1, 2] = 0;
     }
 }
        LayoutAlgorithmSettings ReadSugiyamaLayoutSettings(EdgeRoutingMode edgeRoutingMode) {
            var sugiyama = new SugiyamaLayoutSettings();
            EdgeRoutingSettings routingSettings = sugiyama.EdgeRoutingSettings;
            routingSettings.EdgeRoutingMode = edgeRoutingMode;

            LayoutAlgorithmSettings layoutSettings = sugiyama;

            sugiyama.MinNodeWidth = GetDoubleAttributeOrDefault(GeometryToken.MinNodeWidth, sugiyama.MinNodeWidth);
            sugiyama.MinNodeHeight = GetDoubleAttributeOrDefault(GeometryToken.MinNodeHeight, sugiyama.MinimalHeight);
            sugiyama.AspectRatio = GetDoubleAttributeOrDefault(GeometryToken.AspectRatio, sugiyama.AspectRatio);
            sugiyama.NodeSeparation = GetDoubleAttributeOrDefault(GeometryToken.NodeSeparation, sugiyama.NodeSeparation);
            sugiyama.ClusterMargin = sugiyama.NodeSeparation;

#if REPORTING
            sugiyama.Reporting = GetBoolAttributeOrDefault(GeometryToken.Reporting, false);
#endif

            sugiyama.RandomSeedForOrdering = GetIntAttributeOrDefault(GeometryToken.RandomSeedForOrdering,
                sugiyama.RandomSeedForOrdering);
            sugiyama.NoGainAdjacentSwapStepsBound = GetIntAttributeOrDefault(GeometryToken.NoGainStepsBound,
                sugiyama.NoGainAdjacentSwapStepsBound);
            sugiyama.MaxNumberOfPassesInOrdering = GetIntAttributeOrDefault(GeometryToken.MaxNumberOfPassesInOrdering,
                sugiyama.MaxNumberOfPassesInOrdering);
            sugiyama.RepetitionCoefficientForOrdering = GetIntAttributeOrDefault(GeometryToken.
                RepetitionCoefficientForOrdering, sugiyama.RepetitionCoefficientForOrdering);
            sugiyama.GroupSplit = GetIntAttributeOrDefault(GeometryToken.GroupSplit, sugiyama.GroupSplit);
            sugiyama.LabelCornersPreserveCoefficient = GetDoubleAttribute(GeometryToken.LabelCornersPreserveCoefficient);
            sugiyama.BrandesThreshold = GetIntAttributeOrDefault(GeometryToken.BrandesThreshold,
                sugiyama.BrandesThreshold);
            sugiyama.LayerSeparation = GetDoubleAttributeOrDefault(GeometryToken.LayerSeparation,
                sugiyama.LayerSeparation);
            var transform = new PlaneTransformation();
            ReadTransform(transform);
            return layoutSettings;
        }
 /// <summary>
 /// Rotate a curve around a given point using radians
 /// </summary>
 /// <param name="curve"></param>
 /// <param name="center"></param>
 /// <param name="angle"></param>
 /// <returns></returns>
 public static ICurve RotateCurveAroundCenterByRadian(ICurve curve, Point center, double angle) {
     ValidateArg.IsNotNull(curve, "curve");
     var c = Math.Cos(angle);
     var s = Math.Sin(angle);
     var transform = new PlaneTransformation(1, 0, center.X, 0, 1, center.Y) * new PlaneTransformation(c, -s, 0, s, c, 0) * new PlaneTransformation(1, 0, -center.X, 0, 1, -center.Y);
     return curve.Transform(transform);
 }
示例#20
0
 private static void TransformUnderlyingPolyline(GeometryGraph geometryGraph, GeometryEdge e, PlaneTransformation transformation)
 {
     if (e.UnderlyingPolyline != null)
     {
         for (Microsoft.Msagl.Core.Geometry.Site s = e.UnderlyingPolyline.HeadSite; s != null; s = s.Next)
         {
             s.Point = transformation * s.Point;
         }
     }
 }
示例#21
0
        void InitiateDrawing()
        {
            transformation = null;

            CalcRects(null);

            bBNode = null; //to initiate new calculation

            panel.Invalidate();
        }
 /// <summary>
 /// Return the transformed curve
 /// </summary>
 /// <param name="transformation"></param>
 /// <returns>the transformed curve</returns>
 public ICurve Transform(PlaneTransformation transformation) {
     return new CubicBezierSegment(transformation * b[0], transformation * b[1], transformation * b[2], transformation * b[3]);
 }
示例#23
0
 /// <summary>
 /// Divid matrix by a matrix
 /// </summary>
 /// <param name="transformation0"></param>
 /// <param name="transformation1"></param>
 /// <returns></returns>
 static public PlaneTransformation Divide(PlaneTransformation transformation0, PlaneTransformation transformation1)
 {
     return(transformation0 / transformation1);
 }
示例#24
0
 void InitTransform()
 {
     if (originalGraph == null) {
         transformation = PlaneTransformation.UnitTransformation;
         return;
     }
     var scale = GetFitScale();
     var sourceCenter = originalGraph.BoundingBox.Center;
     SetTransformOnScaleAndCenter(scale, sourceCenter);
 }
        public void InitTransform() {
            double mapCenterX = 0.5*_mapWidth;
            double mapCenterY = 0.5*_mapHeight;
            double worldCenterX = _bbox.Center.X;
            double worldCenterY = _bbox.Center.Y;

            double scaleX = _mapWidth/_bbox.Width;
            double scaleY = _mapHeight/_bbox.Height;
            _worldToMap = new PlaneTransformation(scaleX, 0, mapCenterX - scaleX*worldCenterX,
                0, scaleY, mapCenterY - scaleY*worldCenterY);

            _mapToWorld = _worldToMap.Inverse;
        }
示例#26
0
 void ToolBarButtonClick(object sender, ToolBarButtonClickEventArgs e)
 {
     if (e.Button == zoomin)
         ZoomInPressed();
     else if (e.Button == zoomout)
         ZoomOutPressed();
     else    if (e.Button == backwardButton)
         BackwardButtonPressed();
     else if (e.Button == forwardButton)
         ForwardButtonPressed();
     else if (e.Button == saveButton)
         SaveButtonPressed();
     else if (e.Button == print)
         PrintButtonPressed();
     else if (e.Button == openButton)
         OpenButtonPressed();
     else if (e.Button == undoButton)
         UndoButtonPressed();
     else if (e.Button == redoButton)
         RedoButtonPressed();
     else if (e.Button == windowZoomButton)
         WindowZoomButtonIsPressed();
     else if (e.Button == panButton)
         PanButtonIsPressed();
     else if (e.Button == layoutSettingsButton)
         LayoutSettingsIsClicked();
     else if (e.Button == edgeInsertButton) {
         InsertingEdge = edgeInsertButton.Pushed;
         if (InsertingEdge)
             layoutEditor.PrepareForEdgeDragging();
         else
             layoutEditor.ForgetEdgeDragging();
     }else if (e.Button == homeZoomButton) {
         transformation = null;
         panel.Invalidate();
     }
 }
示例#27
0
 void SetRenderTransformWithoutRaisingEvents(PlaneTransformation value)
 {
     graphCanvas.RenderTransform = new MatrixTransform(value[0, 0], value[0, 1], value[1, 0], value[1, 1],
                                                       value[0, 2],
         value[1, 2]);
 }
示例#28
0
 /// <summary>
 /// Return the transformed curve
 /// </summary>
 /// <param name="transformation"></param>
 /// <returns>the transformed curve</returns>
 public ICurve Transform(PlaneTransformation transformation)
 {
     return(new CubicBezierSegment(transformation * b[0], transformation * b[1], transformation * b[2], transformation * b[3]));
 }
 /// <summary>
 /// Return the transformed curve
 /// </summary>
 /// <param name="transformation"></param>
 /// <returns>the transformed curve</returns>
 public ICurve Transform(PlaneTransformation transformation) {
     return new LineSegment(transformation * a, transformation * b);
 }
        /// <summary>
        /// Transform the curve, arrowheads and label according to the given matrix
        /// </summary>
        /// <param name="matrix">affine transform matrix</param>
        internal void Transform(PlaneTransformation matrix)
        {
            if (Curve == null)
                return;
            Curve = Curve.Transform(matrix);
            if (UnderlyingPolyline != null)
                for (Site s = UnderlyingPolyline.HeadSite, s0 = UnderlyingPolyline.HeadSite;
                     s != null;
                     s = s.Next, s0 = s0.Next)
                    s.Point = matrix * s.Point;

            var sourceArrow = edgeGeometry.SourceArrowhead;
            if (sourceArrow != null)
                sourceArrow.TipPosition = matrix * sourceArrow.TipPosition;
            var targetArrow = edgeGeometry.TargetArrowhead;
            if (targetArrow != null)
                targetArrow.TipPosition = matrix * targetArrow.TipPosition;

            if (Label != null)
                Label.Center = matrix * LabelBBox.Center;
        }
 /// <summary>
 /// Transforms the ellipse
 /// </summary>
 /// <param name="transformation"></param>
 /// <returns>the transformed ellipse</returns>
 public ICurve Transform(PlaneTransformation transformation){
     if(transformation != null){
         Point ap = transformation*aAxis - transformation.Offset;
         Point bp = transformation*bAxis - transformation.Offset;
         return new Ellipse(parStart, parEnd, ap, bp, transformation*center);
     }
     return this;
 }
		/// <summary>
		/// transforms relative to given rectangles
		/// </summary>
		public void TransformRelativeTo(Rectangle oldBounds, Rectangle newBounds)
        {
            if (EdgeGeometry != null) {
                var toOrigin = new PlaneTransformation(1, 0, -oldBounds.Left, 0, 1, -oldBounds.Bottom);
                var scale = new PlaneTransformation(newBounds.Width/oldBounds.Width, 0, 0,
                                                    0,newBounds.Height/oldBounds.Height, 0);
                var toNewBounds = new PlaneTransformation(1, 0, newBounds.Left, 0, 1, newBounds.Bottom);
                Transform(toNewBounds*scale*toOrigin);
            }
            foreach (var l in this.Labels)
            {
                l.Translate(newBounds.LeftBottom - oldBounds.LeftBottom);
            }
        }
示例#33
0
 ///<summary>
 ///</summary>
 ///<param name="transformation"></param>
 public void Transform(PlaneTransformation transformation) {
     BoundaryCurve = BoundaryCurve.Transform(transformation);
 }
 /// <summary>
 /// Return the transformed curve
 /// </summary>
 /// <param name="transformation"></param>
 /// <returns>the transformed curve</returns>
 public ICurve Transform(PlaneTransformation transformation) {
     var bounds = curve.BoundingBox;
     var lt = transformation * bounds.LeftTop;
     var rb = transformation * bounds.RightBottom;
     var transBounds = new Rectangle(lt, rb);
     return new RoundedRect(transBounds, RadiusX, RadiusY);
 }