For tracking connection points on nodes when drawing backwards directed connections, i.e. when the connection target node is vertically higher than the source node.
Пример #1
0
            /// <summary>
            /// Gets the state object for a given graph node. Creates the object if it does not yet exist.
            /// </summary>
            public ConnectionPointInfo GetNodeStateInfo(GraphNode node)
            {
                ConnectionPointInfo info;

                if (!_nodeStateDict.TryGetValue(node, out info))
                {
                    info = new ConnectionPointInfo();
                    _nodeStateDict.Add(node, info);
                }
                return(info);
            }
    public void Draw(Rect r, ConnectionPointInfo info, int i = -1)
    {
        //figure out width and height
        Vector2 size = new Vector2(r.width * info.Width, r.height * info.Height);

        //figure out offset
        Vector2 offset = new Vector2(r.width, r.height);

        offset.Scale(new Vector2(info.UVx, info.UVy));
        offset -= size * .5f;
        Rect rP = new Rect(offset, size);

        rP.position += r.position;

        string s = i != -1 ? $"{i}":"";

        GUI.Box(rP, s, info.Style);
    }
 /// <summary>
 /// Gets the state object for a given graph node. Creates the object if it does not yet exist.
 /// </summary>
 public ConnectionPointInfo GetNodeStateInfo(GraphNode node)
 {
     ConnectionPointInfo info;
     if(!_nodeStateDict.TryGetValue(node, out info))
     {
         info = new ConnectionPointInfo();
         _nodeStateDict.Add(node, info);
     }
     return info;
 }
        private void PaintBackConnection(Pen pen,
                                         Point srcPos, 
                                         Point tgtPos,
                                         ConnectionPointInfo srcInfo,
                                         ConnectionPointInfo tgtInfo,
                                         PaintState state)
        {
            const float SlopeInit = 0.25f;
            const float SlopeIncr = 0.23f;

            // This is the maximum slope value we get before exceeding the slope threshold of 1.
            float slopeMax = SlopeInit + (SlopeIncr * (float)Math.Floor((1f-SlopeInit) / SlopeIncr));

            // Back connection is described by the line ABCDEF. A = srcPos and F = tgtPos.
            int srcConIdx, tgtConIdx;
            int srcSide, tgtSide;

            // If the source and target nodes are close on the X-axis then connect to the same side on both
            // nodes. Otherwise connect nodes on their facing sides.
            if(Math.Abs(tgtPos.X - srcPos.X) <= NodeDiameterModel) {
                srcConIdx = srcInfo._lowerLeft++;
                tgtConIdx = tgtInfo._upperLeft++;
                srcSide = -1;
                tgtSide = -1;
            }
            else if(tgtPos.X > srcPos.X) {
                srcConIdx = srcInfo._lowerRight++;
                tgtConIdx = tgtInfo._upperLeft++;
                srcSide = 1;
                tgtSide = -1;
            } else {
                srcConIdx = srcInfo._lowerLeft++;
                tgtConIdx = tgtInfo._upperRight++;
                srcSide = -1;
                tgtSide = 1;
            }

        //--- Point B.
            // The line AB is a connection leg emerging from the base of a node. To visually seperate multiple legs
            // the first leg has a gentle gradient (almost horizontal) and each successive leg has a steeper gradient.
            // Once a vertical gradient has been reached each sucessive leg is made longer.
            // Calculate leg slope: 0=horizontal, 1=vertical. Hence this is value is not a gradient.
            // Slope pre-trimming back to maximum of 1.0.
            float slopePre = SlopeInit + (SlopeIncr * srcConIdx);

            // Leg length.
            float lenAB = state._backConnectionLegLength;
            float slope = slopePre;
            if(slope > slopeMax)  
            {   // Increase length in fractions of _backConnectionLegLength.
                lenAB += (slopePre-slopeMax) * state._backConnectionLegLength;
                slope = 1f;
            }

            // Calculate position of B as relative to A. 
            // Note. Length is taken to be L1 length (Manhatten distance). This means that the successive B positions 
            // describe a straight line (rather than the circle you get with L2/Euclidean distance) which in turn 
            // ensures that the BC segments of successive connections are evenly spaced out.
            int xDelta = (int)(lenAB * (1f - slope)) * srcSide;
            int yDelta = (int)(lenAB * slope);
            Point b = new Point(srcPos.X + xDelta, srcPos.Y + yDelta);

        //--- Point C.
            // Line BC is a horizontal line from the end of the leg AB.
            int lenBC = (int)(2f * slopePre * state._backConnectionLegLength);
            xDelta = lenBC * srcSide;
            Point c = new Point(b.X + xDelta, b.Y);

        //--- Point E. Equivalent to point B but emerging from the target node.
            slopePre = SlopeInit + (SlopeIncr * tgtConIdx);

            // Leg length.
            float lenEF = state._backConnectionLegLength;
            slope = slopePre;
            if(slope > slopeMax)  
            {   // Increase length in fractions of _backConnectionLegLength.
                lenEF += (slopePre-slopeMax) * state._backConnectionLegLength;
                slope = 1f;
            }

            xDelta = (int)(lenEF * (1f - slope)) * tgtSide;
            yDelta = -(int)(lenEF * slope);
            Point e = new Point(tgtPos.X + xDelta, tgtPos.Y + yDelta);

        //--- Point D. Equivalent to point C but on the target end of the connection.
            int lenDE = (int)(2f * slopePre * state._backConnectionLegLength);
            xDelta = lenDE * tgtSide;
            Point d = new Point(e.X + xDelta, e.Y);

            state._g.DrawLines(pen, new Point[]{srcPos,b,c,d,e,tgtPos});
        }
Пример #5
0
        private void PaintBackConnection(Pen pen,
                                         Point srcPos,
                                         Point tgtPos,
                                         ConnectionPointInfo srcInfo,
                                         ConnectionPointInfo tgtInfo,
                                         PaintState state)
        {
            const float SlopeInit = 0.25f;
            const float SlopeIncr = 0.23f;

            // This is the maximum slope value we get before exceeding the slope threshold of 1.
            float slopeMax = SlopeInit + (SlopeIncr * (float)Math.Floor((1f - SlopeInit) / SlopeIncr));

            // Back connection is described by the line ABCDEF. A = srcPos and F = tgtPos.
            int srcConIdx, tgtConIdx;
            int srcSide, tgtSide;

            // If the source and target nodes are close on the X-axis then connect to the same side on both
            // nodes. Otherwise connect nodes on their facing sides.
            if (Math.Abs(tgtPos.X - srcPos.X) <= NodeDiameterModel)
            {
                srcConIdx = srcInfo._lowerLeft++;
                tgtConIdx = tgtInfo._upperLeft++;
                srcSide   = -1;
                tgtSide   = -1;
            }
            else if (tgtPos.X > srcPos.X)
            {
                srcConIdx = srcInfo._lowerRight++;
                tgtConIdx = tgtInfo._upperLeft++;
                srcSide   = 1;
                tgtSide   = -1;
            }
            else
            {
                srcConIdx = srcInfo._lowerLeft++;
                tgtConIdx = tgtInfo._upperRight++;
                srcSide   = -1;
                tgtSide   = 1;
            }

            //--- Point B.
            // The line AB is a connection leg emerging from the base of a node. To visually separate multiple legs
            // the first leg has a gentle gradient (almost horizontal) and each successive leg has a steeper gradient.
            // Once a vertical gradient has been reached each successive leg is made longer.
            // Calculate leg slope: 0=horizontal, 1=vertical. Hence this is value is not a gradient.
            // Slope pre-trimming back to maximum of 1.0.
            float slopePre = SlopeInit + (SlopeIncr * srcConIdx);

            // Leg length.
            float lenAB = state._backConnectionLegLength;
            float slope = slopePre;

            if (slope > slopeMax)
            {   // Increase length in fractions of _backConnectionLegLength.
                lenAB += (slopePre - slopeMax) * state._backConnectionLegLength;
                slope  = 1f;
            }

            // Calculate position of B as relative to A.
            // Note. Length is taken to be L1 length (Manhattan distance). This means that the successive B positions
            // describe a straight line (rather than the circle you get with L2/Euclidean distance) which in turn
            // ensures that the BC segments of successive connections are evenly spaced out.
            int   xDelta = (int)(lenAB * (1f - slope)) * srcSide;
            int   yDelta = (int)(lenAB * slope);
            Point b      = new Point(srcPos.X + xDelta, srcPos.Y + yDelta);

            //--- Point C.
            // Line BC is a horizontal line from the end of the leg AB.
            int lenBC = (int)(2f * slopePre * state._backConnectionLegLength);

            xDelta = lenBC * srcSide;
            Point c = new Point(b.X + xDelta, b.Y);

            //--- Point E. Equivalent to point B but emerging from the target node.
            slopePre = SlopeInit + (SlopeIncr * tgtConIdx);

            // Leg length.
            float lenEF = state._backConnectionLegLength;

            slope = slopePre;
            if (slope > slopeMax)
            {   // Increase length in fractions of _backConnectionLegLength.
                lenEF += (slopePre - slopeMax) * state._backConnectionLegLength;
                slope  = 1f;
            }

            xDelta = (int)(lenEF * (1f - slope)) * tgtSide;
            yDelta = -(int)(lenEF * slope);
            Point e = new Point(tgtPos.X + xDelta, tgtPos.Y + yDelta);

            //--- Point D. Equivalent to point C but on the target end of the connection.
            int lenDE = (int)(2f * slopePre * state._backConnectionLegLength);

            xDelta = lenDE * tgtSide;
            Point d = new Point(e.X + xDelta, e.Y);

            state._g.DrawLines(pen, new Point[] { srcPos, b, c, d, e, tgtPos });
        }