예제 #1
0
        /// <summary>
        /// Draws the line transition latex.
        /// </summary>
        /// <param name="file">The file.</param>
        /// <param name="origin">The origin.</param>
        /// <param name="destination">The destination.</param>
        /// <param name="transitionName">Name of the transition.</param>
        /// <param name="fontSize">Size of the font.</param>
        public static void drawLineTransitionLatex(StreamWriter file, DrawingState origin, DrawingState destination, string transitionName, string fontSize)
        {
            Vector length;
            Vector arrowOrigin = new Vector();
            Vector arrowDestination = new Vector();
            Vector arrowPoint = new Vector();
            Vector textPoint = new Vector();
            double textOffset = 0, transitionGap = 0, stateAngle = 0;
            double arrowAngleOffset = 0, arrowInclination = 0;

            length     = destination.position - origin.position;
            stateAngle = Math.Atan2(-length.Y, length.X);

            if (stateAngle < 0)
            {
                stateAngle += 2 * Math.PI;
            }

            if (origin.isAOrigin(destination))
            {
                transitionGap    = Constants.TRANSITION_OFFSET;
                arrowAngleOffset = Math.Atan2(transitionGap, length.Length -
                                              Constants.STATE_RADIUS - Constants.DISTANCE);

                if (arrowAngleOffset < 0)
                {
                    arrowAngleOffset += 2 * Math.PI;
                }
            }

            arrowOrigin.X = origin.position.X + Constants.STATE_RADIUS + Constants.DISTANCE;
            arrowOrigin.Y = origin.position.Y - transitionGap;

            arrowDestination.X = origin.position.X + length.Length - Constants.STATE_RADIUS - Constants.DISTANCE;
            arrowDestination.Y = arrowOrigin.Y;


            arrowPoint.X = origin.position.X + Math.Cos(stateAngle + arrowAngleOffset) * (length.Length - Constants.STATE_RADIUS - Constants.DISTANCE);
            arrowPoint.Y = origin.position.Y - Math.Sin(stateAngle + arrowAngleOffset) * (length.Length - Constants.STATE_RADIUS - Constants.DISTANCE);

            arrowInclination = stateAngle + Math.PI;

            drawLatexLine(file, arrowOrigin, arrowDestination, stateAngle, origin.position);
            drawLatexArrow(file, arrowPoint, -arrowInclination, arrowPoint);

            textOffset = Math.Atan2(Constants.TEXT_OFFSET + transitionGap, length.Length / 2);

            if (textOffset < 0)
            {
                textOffset += 2 * Math.PI;
            }

            textPoint.X = origin.position.X + Math.Cos(-textOffset + stateAngle) * (length.Length / 2);
            textPoint.Y = origin.position.Y - Math.Sin(-textOffset + stateAngle) * (length.Length / 2);

            writeTextLatex(file, textPoint, transitionName, fontSize, -stateAngle);
        }
예제 #2
0
        //insere um estado na lista de estado de anterior
        public void addOrigin(DrawingState state)
        {
            int value;

            if (originStates.TryGetValue(state, out value))
            {
                originStates[state] = value + 1;
            }
            else
            {
                originStates.Add(state, 1);
            }
        }
예제 #3
0
        /// <summary>
        /// Draws the state of the latex.
        /// </summary>
        /// <param name="file">The file.</param>
        /// <param name="state">The state.</param>
        /// <param name="radius">The radius.</param>
        /// <param name="fontSize">Size of the font.</param>
        public static void drawLatexState(StreamWriter file, DrawingState state, int radius, string fontSize)
        {
            string y = Drawing.round(state.position.Y);
            string x = Drawing.round(state.position.X);

            file.WriteLine("\\draw [black, line width= 0.8pt] (" + x + "," + y + ") circle (" + radius + ");");

            if (state.IsMarked)
            {
                file.WriteLine("\\draw [black, line width= 0.8pt] (" + x + "," + y + ") circle (" + (radius - 4) + ");");
            }
            writeTextLatex(file, state.position, state.Alias, fontSize, 0);
        }
예제 #4
0
        //insere um estado na lita de estado de destino
        public void addDestination(DrawingState state, string eventName)
        {
            Tuple <string, int> value;

            if (destinationStates.TryGetValue(state, out value))
            {
                value = new Tuple <string, int>(value.Item1 + ", " + eventName, value.Item2 + 1);
                destinationStates[state] = value;
            }
            else
            {
                destinationStates.Add(state, new Tuple <string, int>(eventName, 1));
            }
        }
예제 #5
0
        /// <summary>
        /// Draws the state of the SVG.
        /// </summary>
        /// <param name="file">The file.</param>
        /// <param name="state">The state.</param>
        /// <param name="radius">The radius.</param>
        public static void drawSVGState(StreamWriter file, DrawingState state, int radius)
        {
            string y = Drawing.round(state.position.Y);
            string x = Drawing.round(state.position.X);

            file.WriteLine("\t<circle cx=\"" + x + "\" cy=\"" + y + "\" r=\"" + radius + "\" stroke=\"black\" stroke-width=\"1\" fill=\"none\" />");

            if (state.IsMarked)
            {
                file.WriteLine("\t<circle cx=\"" + x + "\" cy=\"" + y + "\" r=\"" + (radius - 4) + "\" stroke=\"black\" stroke-width=\"1\" fill=\"none\" />");
            }

            int    fontSize = 17;
            Vector gap      = new Vector(0, fontSize / 3);

            writeTextSVG(file, state.position, state.Alias, 0, gap, "none", fontSize);
        }
예제 #6
0
 // verifica se o estado dado eh igual a algum na lista de destino
 public bool IsADestination(DrawingState state)
 {
     return(destinationStates.ContainsKey(state));
 }
예제 #7
0
 // verifica se o estado dado eh igual a algum anterior
 public bool isAOrigin(DrawingState state)
 {
     return(originStates.ContainsKey(state));
 }
예제 #8
0
파일: Drawing.cs 프로젝트: lacsed/UltraDES
        //Simula a dinamica de força do sistema
        /// <summary>
        /// Prepares the specified g.
        /// </summary>
        /// <param name="G">The g.</param>
        /// <returns>Dictionary&lt;System.String, DrawingState&gt;.</returns>
        private static Dictionary <string, DrawingState> prepare(DeterministicFiniteAutomaton G)
        {
            //CRIANDO MÉTODO QUE SERA UTILIZADO PARA O DESENVOLVIMENTO DA BIBLIOTECA

            var drawingStatesList = new Dictionary <string, DrawingState>();           // lista de estados com cordenadas

            //Cria uma lista de estados com parametros de posição para serem desenhados
            foreach (var item in G.States)
            {
                var state = new DrawingState(item.ToString(), item.Marking)
                {
                    initialState = item.Equals(G.InitialState)
                };
                drawingStatesList.Add(item.ToString(), state);
            }

            // aloca os estados dentro de um circulo de raio e centro que serão determinados

            var radius = Constants.SPRING_LENGTH * drawingStatesList.Count;
            var center = new Vector(radius + Constants.AREA_LIMIT_OFFSET, radius + Constants.AREA_LIMIT_OFFSET);

            initialConfiguration(drawingStatesList, radius, center);

            // Atraves da lista de transiçoes associa para cada estado quais sao os estados de origem e qual era o anterior;

            foreach (var item in G.Transitions)
            {
                if (drawingStatesList.TryGetValue(item.Origin.ToString(), out var state))
                {
                    var transitionName = item.Trigger + ((item.IsControllableTransition) ? "" : "'");
                    state.addDestination(drawingStatesList[item.Destination.ToString()], transitionName);
                }
                if (drawingStatesList.TryGetValue(item.Destination.ToString(), out state))
                {
                    state.addOrigin(drawingStatesList[item.Origin.ToString()]);
                }
            }


            var force        = new Vector();
            var biggestForce = new Vector();

            for (int j = 0; j < Constants.MAX_ITERATIONS; ++j)
            {
                force.X = 0;
                force.Y = 0;

                foreach (var item in drawingStatesList)
                {
                    var attractionForce = item.Value.attractionForce(Constants.SPRING_CONSTANT, Constants.SPRING_LENGTH);
                    var repulsionForce  = item.Value.repulsionForce(Constants.CONSTANT_OF_REPULSION, drawingStatesList);
                    force = attractionForce + repulsionForce;

                    if (force.Length > biggestForce.Length)
                    {
                        biggestForce = force;
                    }

                    // desloca estado para uma posição melhor
                    if (item.Value.initialState)
                    {
                        continue;
                    }
                    var position = item.Value.position + Constants.DELTA * force;
                    position.X          = Max(position.X, Constants.AREA_LIMIT_OFFSET);
                    position.X          = Min(position.X, Constants.AREA_LIMIT_OFFSET + 2 * radius);
                    position.Y          = Max(position.Y, Constants.AREA_LIMIT_OFFSET);
                    position.Y          = Min(position.Y, Constants.AREA_LIMIT_OFFSET + 2 * radius);
                    item.Value.position = position;
                }
                if (biggestForce.Length <= Constants.STOP_CRITERION.Length)
                {
                    break;
                }
            }
            return(drawingStatesList);
        }
예제 #9
0
        /// <summary>
        /// Draws the curve transition latex.
        /// </summary>
        /// <param name="file">The file.</param>
        /// <param name="origin">The origin.</param>
        /// <param name="destination">The destination.</param>
        /// <param name="transitionName">Name of the transition.</param>
        /// <param name="fontSize">Size of the font.</param>
        public static void drawCurveTransitionLatex(StreamWriter file, DrawingState origin, DrawingState destination, string transitionName, string fontSize)
        {
            Vector startArc                 = new Vector();
            Vector arcDestination           = new Vector();
            Vector firstArcPoint            = new Vector();
            Vector secondArcPoint           = new Vector();
            Vector statesDistance           = new Vector();
            Vector transitionNamePoint      = new Vector();
            Vector distanceArrowDestination = new Vector();           //distancia entre estado origem e destino seta
            Vector arrowPoint               = new Vector();
            double startArcAngle            = Math.PI / 8;
            double stateAngle;
            double arrowAnglePointFix;
            double arrowInclination, arrowAngleFix;
            string stateAngleDegree;

            statesDistance = destination.position - origin.position;
            stateAngle     = Math.Atan2(statesDistance.Y, statesDistance.X);

            if (stateAngle < 0)
            {
                stateAngle += 2 * Math.PI;
            }

            stateAngleDegree = Drawing.round(stateAngle * 180 / Math.PI);

            //calculo do ponto de incio transiçao
            startArc.X = origin.position.X + Math.Cos(startArcAngle) * Constants.STATE_RADIUS;
            startArc.Y = origin.position.Y + Math.Sin(startArcAngle) * Constants.STATE_RADIUS;

            //calculo do ponto de destino transição
            arcDestination.X = origin.position.X + statesDistance.Length - Math.Cos(startArcAngle) * Constants.STATE_RADIUS;
            arcDestination.Y = startArc.Y;

            //calculo primeiro ponto do arco
            firstArcPoint.X = origin.position.X + statesDistance.Length / 3;
            firstArcPoint.Y = origin.position.Y + statesDistance.Length / 5;

            //calculo segundo ponto do arco
            secondArcPoint.X = origin.position.X + 2 * statesDistance.Length / 3;
            secondArcPoint.Y = origin.position.Y + statesDistance.Length / 5;

            //calculo posião seta
            distanceArrowDestination = arcDestination - origin.position;
            arrowAnglePointFix       = Math.Atan2(distanceArrowDestination.Y, distanceArrowDestination.X);
            arrowPoint.X             = origin.position.X + Math.Cos(arrowAnglePointFix + stateAngle) * distanceArrowDestination.Length;
            arrowPoint.Y             = origin.position.Y + Math.Sin(arrowAnglePointFix + stateAngle) * distanceArrowDestination.Length;
            arrowAngleFix            = Math.Atan2(firstArcPoint.Y - startArc.Y, firstArcPoint.X - startArc.X) * 0.75;
            arrowInclination         = stateAngle + Math.PI - arrowAngleFix;

            //arredondamento
            string x1 = Drawing.round(origin.position.X);
            string y1 = Drawing.round(origin.position.Y);
            string x2 = Drawing.round(startArc.X);
            string y2 = Drawing.round(startArc.Y);
            string x3 = Drawing.round(firstArcPoint.X);
            string y3 = Drawing.round(firstArcPoint.Y);
            string x4 = Drawing.round(secondArcPoint.X);
            string y4 = Drawing.round(secondArcPoint.Y);
            string x5 = Drawing.round(arcDestination.X);
            string y5 = Drawing.round(arcDestination.Y);

            file.WriteLine("\\draw[line width=0.8pt, rotate around={" + stateAngleDegree + ":(" + x1 + "," + y1 +
                           ")}, line width=.5pt, smooth] (" + x2 + "," + y2 + ") .. controls (" + x3 + "," + y3 + ") and (" +
                           x4 + "," + y4 + ") .. (" + x5 + "," + y5 + ");");

            //COLCOCAR SETA NA TRANSICAO
            drawLatexArrow(file, arrowPoint, arrowInclination, arrowPoint);

            // COLOCAR A CODIGO PARA INSERIR NOME NAS TRANSIÇOES
            double textAngleFix = Math.Atan2(statesDistance.Length / 4, statesDistance.Length / 2);

            transitionNamePoint.X = origin.position.X + Math.Cos(stateAngle + textAngleFix) * statesDistance.Length / 2;
            transitionNamePoint.Y = origin.position.Y + Math.Sin(stateAngle + textAngleFix) * statesDistance.Length / 2;
            transitionNamePoint   = Drawing.RoundVector(transitionNamePoint);

            writeTextLatex(file, transitionNamePoint, transitionName, fontSize, stateAngle);
        }
예제 #10
0
        /// <summary>
        /// Draws the curve transition2.
        /// </summary>
        /// <param name="file">The file.</param>
        /// <param name="origin">The origin.</param>
        /// <param name="destination">The destination.</param>
        /// <param name="transitionName">Name of the transition.</param>
        /// <param name="fontFill">The font fill.</param>
        /// <param name="fontSize">Size of the font.</param>
        public static void drawCurveTransition2(StreamWriter file, DrawingState origin, DrawingState destination, string transitionName, string fontFill, int fontSize)
        {
            Vector stateDistance = destination.position - origin.position;
            double curveHeight;
            double transitionInclination = Math.Atan2(-stateDistance.Y, stateDistance.X);
            double startArrowAngle       = 0;
            double endArrowAngle         = 0;
            double offset = 0;
            double arrowAngleFix;
            double textAngleFix = 0;
            double textPointFix = 0;
            double arrowAngle;
            double ArcLength;
            Vector startArcPoint       = new Vector();
            Vector destinationArcPoint = new Vector();
            string startArcBeginRef;

            if (transitionInclination < 0)
            {
                transitionInclination += 2 * Math.PI;
            }

            double transitionIncDegree = -Math.Round(180 * transitionInclination / Math.PI);

            startArcBeginRef = Drawing.round(origin.position.X + Constants.STATE_RADIUS + Constants.DISTANCE, 0);
            ArcLength        = stateDistance.Length - 2 * (Constants.STATE_RADIUS + Constants.DISTANCE);
            curveHeight      = -Math.Round(ArcLength / 3);

            offset          = -Constants.TRANSITION_OFFSET;
            startArrowAngle = Math.Atan2(-offset, (Constants.STATE_RADIUS + Constants.DISTANCE));
            endArrowAngle   = Math.Atan2(-offset, (Constants.STATE_RADIUS + Constants.DISTANCE + ArcLength));

            arrowAngleFix = Math.PI - Math.Atan2(-curveHeight, ArcLength / 2);
            arrowAngle    = transitionInclination + arrowAngleFix;

            startArcPoint.X = origin.position.X + Math.Cos(transitionInclination + startArrowAngle) * (Constants.STATE_RADIUS + Constants.DISTANCE);
            startArcPoint.Y = origin.position.Y - Math.Sin(transitionInclination + startArrowAngle) * (Constants.STATE_RADIUS + Constants.DISTANCE);

            destinationArcPoint.X = origin.position.X + Math.Cos(transitionInclination + endArrowAngle) * (Constants.STATE_RADIUS + Constants.DISTANCE + ArcLength);
            destinationArcPoint.Y = origin.position.Y - Math.Sin(transitionInclination + endArrowAngle) * (Constants.STATE_RADIUS + Constants.DISTANCE + ArcLength);

            string p1 = Drawing.round(origin.position.Y + offset);
            string x1 = Drawing.round(origin.position.X);
            string y1 = Drawing.round(origin.position.Y);

            file.WriteLine("\t<path d=\"M " + startArcBeginRef + " " + p1 + " q " + Math.Round(ArcLength / 2)
                           + " " + curveHeight + " " + Math.Round(ArcLength) + " " + 0 +
                           "\" stroke=\"black\" stroke-width=\"1\" fill=\"none\"  transform =\"rotate(" +
                           transitionIncDegree + " " + x1 + "," + y1 + ")\" />");

            drawSVGArrow(file, destinationArcPoint, arrowAngle, destinationArcPoint);

            textPointFix = Constants.TEXT_OFFSET;
            if (transitionInclination > Math.PI / 2 && transitionInclination < 3 * Math.PI / 2)
            {
                textPointFix = Constants.TEXT_OFFSET + 6;
            }

            Vector textPoint = new Vector();
            double distanceArrowOriginText = Math.Sqrt((-curveHeight / 2 + textPointFix) * (-curveHeight / 2 + textPointFix) + (ArcLength / 2) * (ArcLength / 2));

            textAngleFix = Math.Atan2(-curveHeight / 2 + textPointFix, ArcLength / 2);

            textPoint.X = startArcPoint.X + Math.Cos(transitionInclination + textAngleFix) * distanceArrowOriginText;
            textPoint.Y = startArcPoint.Y - Math.Sin(transitionInclination + textAngleFix) * distanceArrowOriginText;
            textPoint   = Drawing.RoundVector(textPoint);

            Vector gap = new Vector();

            writeTextSVG(file, textPoint, transitionName, transitionInclination, gap, fontFill, fontSize);
        }
예제 #11
0
        /// <summary>
        /// Draws the line transition.
        /// </summary>
        /// <param name="file">The file.</param>
        /// <param name="origin">The origin.</param>
        /// <param name="destination">The destination.</param>
        /// <param name="transitionName">Name of the transition.</param>
        /// <param name="fontFill">The font fill.</param>
        /// <param name="fontSize">Size of the font.</param>
        public static void drawLineTransition(StreamWriter file, DrawingState origin, DrawingState destination,
                                              string transitionName, string fontFill, int fontSize)
        {
            Vector length, originPoint, destinationPoint, arrowPoint;
            Vector textPoint = new Vector();
            Vector fixTextPosition = new Vector();
            double x, y, textOffset = 0, transitionGap = 0;
            double stateAngle = 0, arrowAngleOffset = 0, arrowInclination = 0;

            length     = destination.position - origin.position;
            stateAngle = Math.Atan2(-length.Y, length.X);

            if (stateAngle < 0)
            {
                stateAngle += 2 * Math.PI;
            }

            if (origin.isAOrigin(destination))
            {
                transitionGap    = Constants.TRANSITION_OFFSET;
                arrowAngleOffset = Math.Atan2(transitionGap, length.Length -
                                              Constants.STATE_RADIUS - Constants.DISTANCE);

                if (arrowAngleOffset < 0)
                {
                    arrowAngleOffset += 2 * Math.PI;
                }
            }

            x           = origin.position.X + Constants.STATE_RADIUS + Constants.DISTANCE;
            y           = origin.position.Y - transitionGap;
            originPoint = new Vector(x, y);

            x = origin.position.X + length.Length - Constants.STATE_RADIUS - Constants.DISTANCE;
            y = originPoint.Y;
            destinationPoint = new Vector(x, y);

            x          = origin.position.X + Math.Cos(stateAngle + arrowAngleOffset) * (length.Length - Constants.STATE_RADIUS - Constants.DISTANCE);
            y          = origin.position.Y - Math.Sin(stateAngle + arrowAngleOffset) * (length.Length - Constants.STATE_RADIUS - Constants.DISTANCE);
            arrowPoint = new Vector(x, y);

            arrowInclination = stateAngle + Math.PI;

            drawSVGLine(file, originPoint, destinationPoint, -stateAngle, origin.position);
            drawSVGArrow(file, arrowPoint, arrowInclination, arrowPoint);

            textOffset = Math.Atan2(Constants.TEXT_OFFSET + transitionGap, length.Length / 2);

            if (textOffset < 0)
            {
                textOffset += 2 * Math.PI;
            }

            //correcão do posicionamnto do texto quando angulo vara entre 90 e 270 graus
            if (stateAngle >= Math.PI / 2 && stateAngle <= 3 * Math.PI / 2)
            {
                fixTextPosition.X = -Math.Sin(stateAngle) * Constants.TEXT_OFFSET;
                fixTextPosition.Y = -Math.Cos(stateAngle) * Constants.TEXT_OFFSET;
            }

            x = origin.position.X + Math.Cos(textOffset + stateAngle) * (length.Length / 2) + fixTextPosition.X;
            y = origin.position.Y - Math.Sin(textOffset + stateAngle) * (length.Length / 2) + fixTextPosition.Y;

            Vector gap = new Vector();

            writeTextSVG(file, textPoint, transitionName, stateAngle, gap, fontFill, fontSize);
        }