Esempio n. 1
0
        private bool SaveNodes(string fileName, DialogueContainer dialogueContainerObject)
        {
            if (!Edges.Any())
            {
                return(false);
            }
            var connectedSockets = Edges.Where(x => x.input.node != null).ToArray();

            for (var i = 0; i < connectedSockets.Count(); i++)
            {
                var outputNode = (connectedSockets[i].output.node as DialogueNode);
                var inputNode  = (connectedSockets[i].input.node as DialogueNode);
                dialogueContainerObject.NodeLinks.Add(new NodeLinkData
                {
                    BaseNodeGUID   = outputNode.GUID,
                    PortName       = connectedSockets[i].output.portName,
                    TargetNodeGUID = inputNode.GUID
                });
            }

            foreach (var node in Nodes.Where(node => !node.EntyPoint))
            {
                dialogueContainerObject.DialogueNodeData.Add(new DialogueNodeData
                {
                    NodeGUID     = node.GUID,
                    DialogueText = node.DialogueText,
                    Position     = node.GetPosition().position
                });
            }

            return(true);
        }
Esempio n. 2
0
 /// <summary>
 /// Removes all edges between vertices.
 /// Vertices still remains in graph but any of them are connected.
 /// </summary>
 public void ClearEdges()
 {
     while (Edges.Any())
     {
         RemoveEdge(Edges.First());
     }
 }
Esempio n. 3
0
        public void AddEdge(Edge <T> edge, double weight = 0)
        {
            bool existsInGraph = !(Edges.Any((i => i.Node1.Id == edge.Node1.Id && i.Node2.Id == edge.Node2.Id)) || (Edges.Any(i => i.Node1.Id == edge.Node2.Id && i.Node2.Id == edge.Node1.Id)));

            if (existsInGraph)
            {
                Edges.Add(edge);
            }

            if (!_graphSet.ContainsKey(edge.Node1.Id))
            {
                _graphSet.Add(edge.Node1.Id, new HashSet <Node <T> >());
            }

            if (!_graphSet.ContainsKey(edge.Node2.Id))
            {
                _graphSet.Add(edge.Node2.Id, new HashSet <Node <T> >());
            }

            if (_graphSet.ContainsKey(edge.Node1.Id))
            {
                _graphSet[edge.Node1.Id].Add(edge.Node2);
            }

            if (_graphSet.ContainsKey(edge.Node2.Id))
            {
                _graphSet[edge.Node2.Id].Add(edge.Node1);
            }
            SetEdgeWeight(edge, weight);
        }
Esempio n. 4
0
        public void AddEdge(T from, T to)
        {
            if (from == null)
            {
                throw new ArgumentNullException(nameof(from));
            }

            if (to == null)
            {
                throw new ArgumentNullException(nameof(to));
            }

            if (!Vertices.Contains(from, EqualityComparer))
            {
                throw new ArgumentException($"Cannot add edge from nonexistant vertex {from}");
            }

            if (!Vertices.Contains(to, EqualityComparer))
            {
                throw new ArgumentException($"Cannot add edge to nonexistant vertex {to}");
            }

            if (Edges.Any(edge => EqualityComparer.Equals(edge.From, from) && EqualityComparer.Equals(edge.To, to)))
            {
                throw new ArgumentException($"Edge from vertex {from} to vertex {to} already exists");
            }

            _edges.Add(new Edge <T>(from, to));
        }
Esempio n. 5
0
 protected void ValidatePrintEdges()
 {
     if (!Edges.Any())
     {
         throw new Exception("There's no edges.");
     }
 }
Esempio n. 6
0
        public void SortVertices()
        {
            if (!Edges.Any())
            {
                return;
            }

            Vertices.Clear();

            List <Line> sortedLines = new List <Line>();
            List <Line> edgesCopy   = new List <Line>();

            foreach (Line e in Edges)
            {
                Line tmp = new Line(e.StartPoint, e.EndPoint);
                edgesCopy.Add(tmp);
            }

            bool closed   = false;
            Line currLine = edgesCopy.First();
            Line toRemove = null;

            while (!closed)
            {
                foreach (Line line in edgesCopy)
                {
                    //if (l.GetPoints().Contains(currLine.EndPoint))
                    if (containsPoint(line.GetPoints(), currLine.EndPoint, 5))
                    {
                        Vector3 vtmp = line.GetPoints().Where(o => !almostEqual(o, currLine.EndPoint, 5)).First();
                        Line    tmp  = new Line(currLine.EndPoint, vtmp);
                        toRemove = line;
                        sortedLines.Add(tmp);
                        currLine = tmp;
                        break;
                    }
                    else
                    {
                        toRemove = null;
                    }
                }

                if (toRemove == null)
                {
                    break;
                }
                else
                {
                    edgesCopy.Remove(toRemove);
                }

                if (edgesCopy.Count == 0)
                {
                    closed = true;
                }
            }

            Edges = sortedLines;
        }
Esempio n. 7
0
 public bool ContainsEdge(Edge edge, bool compareByPos = false)
 {
     if (compareByPos)
     {
         return(ContainsVertex(edge.P1.Position) && ContainsVertex(edge.P2.Position));
     }
     return(Edges.Any(x => x.Equals(edge, compareByPos)));
 }
    private bool SaveNodes(FrpGraphContainer frpGraphContainer)
    {
        if (!Edges.Any())
        {
            return(false);
        }

        var edges = Edges.ToArray();

        for (var i = 0; i < edges.Length; ++i)
        {
            var outputNode = edges[i].output.node as FrpNode;
            var inputNode  = edges[i].input.node as FrpNode;

            var basePortName = edges[i].output.portName;

            var basePortNames = new List <string>();
            for (int j = 0; j < outputNode.outputContainer.childCount; ++j)
            {
                basePortNames.Add(outputNode.outputContainer[j].Q <Port>().portName);
            }

            var basePortIndex = basePortNames.FindIndex(x => x == basePortName);

            var targetPortName = edges[i].input.portName;

            var targetPortNames = new List <string>();
            for (int j = 0; j < inputNode.inputContainer.childCount; ++j)
            {
                targetPortNames.Add(inputNode.inputContainer[j].Q <Port>().portName);
            }

            var targetPortIndex = targetPortNames.FindIndex(x => x == targetPortName);

            var connectionName = edges[i].Q <TextField>().value;

            frpGraphContainer.NodeLinks.Add(new NodeLinkData
            {
                ConnectionName = connectionName,
                BaseNodeGuid   = outputNode.frpNodeData.Guid,
                BasePortName   = basePortName,
                BasePortNum    = basePortIndex,
                TargetNodeGuid = inputNode.frpNodeData.Guid,
                TargetPortName = targetPortName,
                TargetPortNum  = targetPortIndex
            });
        }

        foreach (var node in Nodes)
        {
            node.frpNodeData.Position = node.GetPosition().position;
            frpGraphContainer.FrpNodeData.Add(node.frpNodeData.Clone());
        }

        return(true);
    }
Esempio n. 9
0
        /// <inheritdoc />
        public bool ContainsVertex(TVertex vertex)
        {
            if (vertex == null)
            {
                throw new ArgumentNullException(nameof(vertex));
            }

            return(Edges.Any(
                       edge => edge.Source.Equals(vertex) || edge.Target.Equals(vertex)));
        }
Esempio n. 10
0
        /// <inheritdoc />
        public bool ContainsVertex(TVertex vertex)
        {
            if (vertex == null)
            {
                throw new ArgumentNullException(nameof(vertex));
            }

            return(Edges.Any(
                       edge => EqualityComparer <TVertex> .Default.Equals(edge.Source, vertex) || EqualityComparer <TVertex> .Default.Equals(edge.Target, vertex)));
        }
Esempio n. 11
0
File: Vertex.cs Progetto: tz0711/vdc
 public void AddEdge(Vertex to)
 {
     if (!Edges.Any(
             t => t.Name.Equals(
                 to.Name,
                 StringComparison.InvariantCultureIgnoreCase)))
     {
         Edges.AddLast(to);
     }
 }
Esempio n. 12
0
        bool CanAdd()
        {
            if (!Edges.Any())
            {
                return(true);
            }
            var edge = Edges[Edges.Count - 1];

            return(!string.IsNullOrEmpty(edge.From) && !string.IsNullOrEmpty(edge.To));
        }
Esempio n. 13
0
        private bool FCheckEasy(out IEnumerable <Vector> ptsToBeClipped)
        {
            ptsToBeClipped = null;
            if (!Edges.Any(e => e.VtxStart.FAtInfinity || e.VtxEnd.FAtInfinity))
            {
                ptsToBeClipped = Vertices.Select(v => v.Pt);
                return(true);
            }

            return(false);
        }
Esempio n. 14
0
        public List <Triangle> CreateTriangles(Vector3 normal)
        {
            if (!Edges.Any())
            {
                return(new List <Triangle>());
            }

            List <Triangle> triangles = new List <Triangle>();

            //Clear the vertices
            Vertices.Clear();
            UV.Clear();

            //Create the new vertices with the uv
            foreach (Line l in Edges)
            {
                Vertices.Add(l.StartPoint);
                UV.Add(new Vector2());
            }

            Vertices.Add(Edges.Last().EndPoint);
            UV.Add(new Vector2());

            //Create the triangles
            for (int i = 1; i < Vertices.Count - 1; i++)
            {
                if (Vertices[0] == Vertices[i] ||
                    Vertices[0] == Vertices[i + 1])
                {
                    continue;
                }

                List <Vector3> vertices = new List <Vector3>
                {
                    Vertices[0],
                    Vertices[i],
                    Vertices[i + 1]
                };
                List <Vector3> normals = new List <Vector3>
                {
                    normal, normal, normal
                };
                List <Vector2> uvs = new List <Vector2>
                {
                    UV[0],
                    UV[i],
                    UV[i + 1]
                };

                triangles.Add(new Triangle(vertices, normals, uvs));
            }

            return(triangles);
        }
Esempio n. 15
0
 private void InitializeIds()
 {
     if (Edges.Any())
     {
         nextEdgeId = edges.Keys.Max() + 1;
     }
     if (Vertices.Any())
     {
         nextVertexId = vertices.Keys.Max() + 1;
     }
     idsAreInitialized = true;
 }
Esempio n. 16
0
        public int CountTrees()
        {
            int         treeCount = 0;
            List <Edge> tree      = new List <Edge>();

            var fGroup = Edges.GroupBy(e => e.From);    // 1, 3, 4, 6
            var tGroup = Edges.GroupBy(e => e.To);      // 2, 4, 5, 7, 8, 9

            for (int i = 0; i < Nodes; i++)
            {
                int fCount = fGroup.Count(f => f.Key == i);
                int tCount = tGroup.Count(f => f.Key == i);

                if (fCount == 0 && tCount == 0)
                {
                    treeCount++; tree.Add(new Edge(i, i));  continue;
                }
                if (fCount > 0 && tCount > 0)
                {
                    continue;                                                   //Do not add to tree since it found in both direction.
                }
                if (fCount > 0)
                {
                    foreach (var e in fGroup.Where(g => g.Key == i))
                    {
                        List <int> tos = e.Select(f => f.To).ToList();

                        if (!Edges.Any(f => tos.Contains(f.From)))
                        {
                            treeCount++; tree.AddRange(e.Select(f => f));
                        }
                    }
                }
                if (tCount > 0)
                {
                    foreach (var e in tGroup.Where(g => g.Key == i))
                    {
                        List <int> froms = e.Select(f => f.From).ToList();

                        if (!Edges.Any(f => froms.Contains(f.To)))
                        {
                            treeCount++; tree.AddRange(e.Select(f => f));
                        }
                    }
                }
            }

            treeCount = tree.Distinct().Select(d => d.From).Distinct().Count();

            return(treeCount);
        }
Esempio n. 17
0
 public void AddEdge(Edge edge)
 {
     if (!Edges.Any(current => current.FirstVertex.Equals(edge.FirstVertex) ||
                    current.SecondVertex.Equals(edge.FirstVertex)))
     {
         VertexCount++;
     }
     if (!Edges.Any(current => current.FirstVertex.Equals(edge.SecondVertex) ||
                    current.SecondVertex.Equals(edge.SecondVertex)))
     {
         VertexCount++;
     }
     Edges.Add(edge);
 }
Esempio n. 18
0
        // todo: not cut by rhythm
        private SliderTick[] GetBezierDiscreteBallData(double interval)
        {
            if (Math.Round(interval - _singleElapsedTime) >= 0)
            {
                return(Array.Empty <SliderTick>());
            }

            var totalLength = RawBezierLengthData.Sum();
            var ticks       = new List <SliderTick>();

            for (int i = 1; i *interval < _singleElapsedTime; i++)
            {
                var offset = i * interval; // 当前tick的相对时间
                if (Edges.Any(k => Math.Abs(k.Offset - _offset - offset) < 0.01))
                {
                    continue;
                }

                var ratio       = offset / _singleElapsedTime;           // 相对整个滑条的时间比例,=距离比例
                var relativeLen = totalLength * ratio;                   // 至滑条头的距离

                var(index, lenInPart) = CalculateWhichPart(relativeLen); // can be optimized
                var len       = RawBezierLengthData[index];
                var tickPoint = Bezier.CalcPoint((float)(lenInPart / len), RawGroupedBezierData[index]);
                ticks.Add(new SliderTick(_offset + offset, tickPoint));
            }

            if (Repeat > 1)
            {
                var firstSingleCopy = ticks.ToArray();
                for (int i = 2; i <= Repeat; i++)
                {
                    var reverse = i % 2 == 0;
                    if (reverse)
                    {
                        ticks.AddRange(firstSingleCopy.Reverse().Select(k =>
                                                                        new SliderTick((_singleElapsedTime - (k.Offset - _offset)) + (i - 1) * _singleElapsedTime + _offset,
                                                                                       k.Point)));
                    }
                    else
                    {
                        ticks.AddRange(firstSingleCopy.Select(k =>
                                                              new SliderTick(k.Offset + (i - 1) * _singleElapsedTime, k.Point)));
                    }
                }
            }

            return(ticks.ToArray());
        }
Esempio n. 19
0
        public void AddToMesh(IEnumerable <GroundPointBuilder> newPoints, IEnumerable <GroundEdgeBuilder> newEdges)
        {
            IEnumerable <GroundPoint> points = newPoints.Select(item => new GroundPoint(this, item.Index, item.Position)).ToArray();

            AddPoints(points);
            IEnumerable <GroundEdge> edges = newEdges.Select(item => new GroundEdge(this, Points[item.PointAIndex], Points[item.PointBIndex])).ToArray();

            AddEdges(edges);
            BorderEdges = Edges.Where(item => item.IsBorder).ToArray();

            if (Edges.Any(edge => edge.Quads.Count() == 0 || edge.Quads.Count() > 2))
            {
                throw new Exception("Malformed data.");
            }

            UpdateVoxelVisuals();
        }
Esempio n. 20
0
 ////////////////////////////////////////////////////////////////////////////////////////////////////
 /// <summary>
 ///     Identical to BoxVertices if there are any infinite polygons/vertices involved.  In the case
 ///     of a purely finite polygon, we return it unaltered.
 /// </summary>
 /// <remarks>
 ///     This overload of RealVertices ensures that all vertices are finite in a foolproof way.  The
 ///     overload of RealVertices that takes a double as a raylength relies on the caller guessing as
 ///     to a sufficient ray length to ensure that our rays extend outside of whatever area they're
 ///     interested in.  That's usually not possible to do in a foolproof way.  Also, it has problems
 ///     with doubly infinite lines when the return value is interpreted as a polygon.  This routine
 ///     doesn't necessarily clip to the box in question, but does guarantee that the finite polygon
 ///     returned will properly cover it's assigned area in the box passed in.  On interior cells, it
 ///     avoids the overhead of a clipping operation which is liable to happen outside of this call
 ///     anyway.  This is the safest way of covering a box without necessarily clipping to it.
 ///     Darrellp, 2/28/2011.
 /// </remarks>
 /// <param name="ptUL">	The upper left point of the box. </param>
 /// <param name="ptLR">	The lower right point of the box. </param>
 /// <returns>	An enumerable of real points representing the polygon. </returns>
 ////////////////////////////////////////////////////////////////////////////////////////////////////
 public IEnumerable <Vector> RealVertices(Vector ptUL, Vector ptLR)
 {
     if (!Edges.Any(e => e.VtxStart.FAtInfinity || e.VtxEnd.FAtInfinity))
     {
         foreach (var pt in Vertices.Select(v => v.Pt))
         {
             yield return(pt);
         }
     }
     else
     {
         foreach (var pt in BoxVertices(ptUL, ptLR))
         {
             yield return(pt);
         }
     }
 }
Esempio n. 21
0
 /// <summary>
 ///     Defines the face curvature. Depends on DefineEdgeAngle
 /// </summary>
 public void DefineFaceCurvature()
 {
     if (Edges.Any(e => e == null || e.Curvature == CurvatureType.Undefined))
     {
         Curvature = CurvatureType.Undefined;
     }
     else if (Edges.All(e => e.Curvature != CurvatureType.Concave))
     {
         Curvature = CurvatureType.Convex;
     }
     else if (Edges.All(e => e.Curvature != CurvatureType.Convex))
     {
         Curvature = CurvatureType.Concave;
     }
     else
     {
         Curvature = CurvatureType.SaddleOrFlat;
     }
 }
Esempio n. 22
0
        /// <summary>
        /// Creates the connection to the annex node.
        /// </summary>
        public override void CreateConnections(List <PathfindingNodeMaster> Objects)
        {
            var annexZoneLocProp = export.GetProperty <ObjectProperty>("AnnexZoneLocation");

            if (annexZoneLocProp != null)
            {
                //ExportEntry annexzonelocexp = pcc.Exports[annexZoneLocProp.Value - 1];

                PathfindingNodeMaster othernode = null;
                int othernodeidx = annexZoneLocProp.Value;
                if (othernodeidx != 0)
                {
                    foreach (PathfindingNodeMaster node in Objects)
                    {
                        if (node.export.UIndex == othernodeidx)
                        {
                            othernode = node;
                            break;
                        }
                    }
                }

                if (othernode != null)
                {
                    PathfindingEditorEdge edge = new PathfindingEditorEdge
                    {
                        Pen       = annexZoneLocPen,
                        EndPoints =
                        {
                            [0] = this,
                            [1] = othernode
                        }
                    };
                    if (!Edges.Any(x => x.DoesEdgeConnectSameNodes(edge)) && !othernode.Edges.Any(x => x.DoesEdgeConnectSameNodes(edge)))
                    {
                        Edges.Add(edge);
                        othernode.Edges.Add(edge);
                        g.edgeLayer.AddChild(edge);
                    }
                }
            }
        }
Esempio n. 23
0
        internal void Refresh(bool switchBackFront)
        {
            UpdateNormalVector();

            if (mIsTransparent || Edges.Any <Edge>(e => e.OtherFace == null))
            {
                mIsFrontFacing = true;
            }
            else
            {
                //the face may no longer be front-facing (or no longer back-facing)
                double dotProduct = NormalVector.DotProduct(new Coord(0, 0, 1));
                int    dotSign    = Math.Sign(dotProduct);
                mIsFrontFacing = switchBackFront ? (dotSign == -1) : (dotSign == 1);
            }
            //update the bounding box
            mBoundingBox = Global.GetRectangleWithGivenCorners(Vertices[0].ViewCoord.ToPointD(), Vertices[1].ViewCoord.ToPointD());
            for (int i = 1; i < Vertices.Count; i++)
            {
                mBoundingBox = Rectangle.Union(mBoundingBox, Global.GetRectangleWithGivenCorners(Vertices[i - 1].ViewCoord.ToPointD(), Vertices[i].ViewCoord.ToPointD()));
            }
        }
Esempio n. 24
0
        ////////////////////////////////////////////////////////////////////////////////////////////////////
        /// <summary>	Ensure that all edges connect to each other. </summary>
        /// <remarks>	Darrellp, 2/18/2011. </remarks>
        /// <returns>	True if all edges connect in order, else false. </returns>
        ////////////////////////////////////////////////////////////////////////////////////////////////////
        internal bool FValidateEdgesInOrder()
        {
            // If it's a single infinite polygon
            if (!Edges.Any())
            {
                // There are no edges so skip this check
                return(true);
            }

            // Declarations
            var fFirstTimeThroughLoop = true;
            var edgePrev  = new WeEdge();
            var edgeFirst = new WeEdge();

            // For each edge in the polygon
            foreach (var edgeCur in Edges)
            {
                if (fFirstTimeThroughLoop)
                {
                    // Initialize
                    fFirstTimeThroughLoop = false;
                    edgePrev = edgeFirst = edgeCur;
                }
                else
                {
                    // If this edge doesn't connect to the previous one
                    if (!edgeCur.FConnectsToEdge(edgePrev))
                    {
                        // there is a problem
                        return(Failure());
                    }

                    edgePrev = edgeCur;
                }
            }

            // Make sure the last edge cycles back to the first one
            return(edgePrev.FConnectsToEdge(edgeFirst) || Failure());
        }
Esempio n. 25
0
 /// <summary>
 ///     Defines vertex curvature
 /// </summary>
 private void DefineCurvature()
 {
     if (Edges.Any(e => e.Curvature == CurvatureType.Undefined))
     {
         _curvature = CurvatureType.Undefined;
     }
     else if (Edges.All(e => e.Curvature == CurvatureType.SaddleOrFlat))
     {
         _curvature = CurvatureType.SaddleOrFlat;
     }
     else if (Edges.Any(e => e.Curvature != CurvatureType.Convex))
     {
         _curvature = CurvatureType.Concave;
     }
     else if (Edges.Any(e => e.Curvature != CurvatureType.Concave))
     {
         _curvature = CurvatureType.Convex;
     }
     else
     {
         _curvature = CurvatureType.SaddleOrFlat;
     }
 }
Esempio n. 26
0
        private void DefineAdvancedPlanarFace()
        {
            MinX = PlanarFace.GetMinX();
            MaxX = PlanarFace.GetMaxX();
            MinY = PlanarFace.GetMinY();
            MaxY = PlanarFace.GetMaxY();
            MinZ = PlanarFace.GetMinZ();
            MaxZ = PlanarFace.GetMaxZ();

            Edges = GetEdges();
            if (!Edges.Any())
            {
                IsDefined = false;
                return;
            }

            IsHorizontal = PlanarFace.IsHorizontal();
            IsVertical   = PlanarFace.IsVertical();
            if (!IsVertical && !IsHorizontal)
            {
                IsDefined = false;
            }
        }
Esempio n. 27
0
        ////////////////////////////////////////////////////////////////////////////////////////////////////
        /// <summary>
        ///     Clip this voronoi cell with a passed in bounding box.
        /// </summary>
        /// <remarks>
        ///     <para>
        ///         I'm trying to handle all the exceptional cases.  There is one incredibly exceptional
        ///         case which I'm ignoring.  That is the case where there are two vertices at infinity which are
        ///         at such nearly opposite directions without being completely collinear that we can't push
        ///         their points at infinity out far enough to encompass the rest of the box within the range of
        ///         a double.  If this is important to you, then see the comments below, but it's hard to imagine
        ///         it ever arising.
        ///     </para>
        ///     <para>
        ///         Editorial comment - The annoying thing about all of this is that, like in so much of
        ///         computational geometry, the rarer and less significant the exceptional cases are, the more
        ///         difficult they are to handle.  It's both a blessing and a curse - it means that the normal
        ///         cases are generally faster, but it also makes it difficult to get excited about slogging
        ///         through the tedious details of situations that will probably never arise in practice.  Still,
        ///         in order to keep our noses clean, we press on regardless.
        ///     </para>
        ///     Darrellp, 2/26/2011.
        /// </remarks>
        /// <param name="ptUL">	The upper left point of the box. </param>
        /// <param name="ptLR">	The lower right point of the box. </param>
        /// <returns>	An enumerable of real points representing the voronoi cell clipped to the box. </returns>
        ////////////////////////////////////////////////////////////////////////////////////////////////////
        public IEnumerable <Vector> BoxVertices(Vector ptUL, Vector ptLR)
        {
            // If no edges, then it's just the entire box
            if (!Edges.Any())
            {
                foreach (var pt in BoxPoints(ptUL, ptLR))
                {
                    yield return(pt);
                }

                yield break;
            }

            var ptsBox = BoxPoints(ptUL, ptLR);

            var fFound = FCheckEasy(out var ptsToBeClipped);

            if (!fFound)
            {
                fFound = FCheckParallelLines(ptsBox, out ptsToBeClipped);
            }

            if (!fFound)
            {
                fFound = FCheckDoublyInfinite(ptsBox, out ptsToBeClipped);
            }

            if (!fFound)
            {
                ptsToBeClipped = RealVertices(CalcRayLength(ptsBox));
            }

            foreach (var pt in ConvexPolyIntersection.FindIntersection(ptsToBeClipped, ptsBox))
            {
                yield return(pt);
            }
        }
Esempio n. 28
0
        ////////////////////////////////////////////////////////////////////////////////////////////////////
        /// <summary>	Converts vertices to real vertices. </summary>
        /// <remarks>
        ///     This routine does nothing for polygons with no infinite vertices.  If there are no doubly
        ///     infinite lines, it uses raylength to extend the rays.  If there are doubly infinite lines it
        ///     uses the machinery above to produce a region.  No clipping is done but it's guaranteed is
        ///     that the resultant polygon is finite and covers the polygon's portion which intersects the
        ///     passed in box (assuming that rayLength is long enough).  This routine is fairly fast, works
        ///     with doubly infinite lines but could fail for infinite regions in which rayLength is of
        ///     insufficient size.  If you feel like raylength will handle all non-doubly infinite lines but
        ///     you still have to deal with the doubly infinite case, this is a good choice - especially if
        ///     perfomance is an issue.
        ///     Darrellp, 3/1/2011.
        /// </remarks>
        /// <param name="rayLength">	Length of the ray. </param>
        /// <param name="ptUL">			The upper left point of the box. </param>
        /// <param name="ptLR">			The lower right point of the box. </param>
        /// <returns>	An enumerable of real points representing the polygon. </returns>
        ////////////////////////////////////////////////////////////////////////////////////////////////////

        // TODO: share code between this and BoxVertices
        public IEnumerable <Vector> RealVertices(double rayLength, Vector ptUL, Vector ptLR)
        {
            // If no edges, then it's just the entire box
            if (!Edges.Any())
            {
                foreach (var pt in BoxPoints(ptUL, ptLR))
                {
                    yield return(pt);
                }

                yield break;
            }

            var ptsBox = BoxPoints(ptUL, ptLR);

            var fFound = FCheckEasy(out var points);

            if (!fFound)
            {
                fFound = FCheckParallelLines(ptsBox, out points);
            }

            if (!fFound)
            {
                fFound = FCheckDoublyInfinite(ptsBox, out points);
            }

            if (!fFound)
            {
                points = RealVertices(rayLength);
            }

            foreach (var pt in points)
            {
                yield return(pt);
            }
        }
Esempio n. 29
0
        // todo: not cut by rhythm
        // todo: i forget math
        private SliderTick[] GetPerfectDiscreteBallData(double interval)
        {
            if (Math.Round(interval - _singleElapsedTime) >= 0)
            {
                return(Array.Empty <SliderTick>());
            }

            Vector2 <float> p1;
            Vector2 <float> p2;
            Vector2 <float> p3;

            try
            {
                p1 = StartPoint;
                p2 = CurvePoints[0];
                p3 = CurvePoints[1];
            }
            catch (IndexOutOfRangeException)
            {
                this.SliderType = SliderType.Linear;
                return(GetBezierDiscreteBallData(interval));
            }

            var circle = GetCircle(p1, p2, p3);

            var radStart = Math.Atan2(p1.Y - circle.p.Y, p1.X - circle.p.X);
            var radMid   = Math.Atan2(p2.Y - circle.p.Y, p2.X - circle.p.X);
            var radEnd   = Math.Atan2(p3.Y - circle.p.Y, p3.X - circle.p.X);

            if (radMid - radStart > Math.PI)
            {
                radMid -= Math.PI * 2;
            }
            else if (radMid - radStart < -Math.PI)
            {
                radMid += Math.PI * 2;
            }

            if (radEnd - radMid > Math.PI)
            {
                radEnd -= Math.PI * 2;
            }
            else if (radEnd - radMid < -Math.PI)
            {
                radEnd += Math.PI * 2;
            }

            var ticks = new List <SliderTick>();

            for (int i = 1; i *interval < _singleElapsedTime; i++)
            {
                var offset = i * interval; // 当前tick的相对时间
                if (Edges.Any(k => Math.Abs(k.Offset - _offset - offset) < 0.01))
                {
                    continue;
                }
                var ratio       = offset / _singleElapsedTime; // 相对整个滑条的时间比例,=距离比例
                var relativeRad = (radEnd - radStart) * ratio; // 至滑条头的距离
                var offsetRad   = radStart + relativeRad;
                var x           = circle.p.X + circle.r * Math.Cos(offsetRad);
                var y           = circle.p.Y + circle.r * Math.Sin(offsetRad);

                ticks.Add(new SliderTick(_offset + offset, new Vector2 <float>((float)x, (float)y)));
            }

            if (Repeat > 1)
            {
                var firstSingleCopy = ticks.ToArray();
                for (int i = 2; i <= Repeat; i++)
                {
                    var reverse = i % 2 == 0;
                    if (reverse)
                    {
                        ticks.AddRange(firstSingleCopy.Reverse().Select(k =>
                                                                        new SliderTick((_singleElapsedTime - (k.Offset - _offset)) + (i - 1) * _singleElapsedTime + _offset,
                                                                                       k.Point)));
                    }
                    else
                    {
                        ticks.AddRange(firstSingleCopy.Select(k =>
                                                              new SliderTick(k.Offset + (i - 1) * _singleElapsedTime, k.Point)));
                    }
                }
            }

            return(ticks.ToArray());
            //var degStart = radStart / Math.PI * 180;
            //var degMid = radMid / Math.PI * 180;
            //var degEnd = radEnd / Math.PI * 180;
            //return Array.Empty<SliderTick>();
        }
Esempio n. 30
0
        /// <summary>
        /// Creates the reachspec connections from this pathfinding node to others.
        /// </summary>
        public override void CreateConnections(List <PathfindingNodeMaster> graphNodes)
        {
            ReachSpecs = (SharedPathfinding.GetReachspecExports(export));
            foreach (ExportEntry spec in ReachSpecs)
            {
                Pen penToUse = blackPen;
                switch (spec.ObjectName.Name)
                {
                case "SlotToSlotReachSpec":
                    penToUse = slotToSlotPen;
                    break;

                case "CoverSlipReachSpec":
                    penToUse = coverSlipPen;
                    break;

                case "SFXLadderReachSpec":
                    penToUse = sfxLadderPen;
                    break;

                case "SFXLargeBoostReachSpec":
                    penToUse = sfxLargeBoostPen;
                    break;

                case "SFXBoostReachSpec":
                    penToUse = sfxBoostPen;
                    break;

                case "SFXJumpDownReachSpec":
                    penToUse = sfxJumpDownPen;
                    break;
                }
                //Get ending
                PropertyCollection props          = spec.GetProperties();
                ExportEntry        otherEndExport = SharedPathfinding.GetReachSpecEndExport(spec, props);

                /*
                 * if (props.GetProp<StructProperty>("End") is StructProperty endProperty &&
                 *  endProperty.GetProp<ObjectProperty>(SharedPathfinding.GetReachSpecEndName(spec)) is ObjectProperty otherNodeValue)
                 * {
                 *  othernodeidx = otherNodeValue.Value;
                 * }*/

                if (otherEndExport != null)
                {
                    bool isTwoWay = false;
                    PathfindingNodeMaster othernode = graphNodes.FirstOrDefault(x => x.export == otherEndExport);
                    if (othernode != null)
                    {
                        //Check for returning reachspec for pen drawing. This is going to incur a significant performance penalty...
                        var othernodeSpecs = SharedPathfinding.GetReachspecExports(otherEndExport);
                        foreach (var path in othernodeSpecs)
                        {
                            if (SharedPathfinding.GetReachSpecEndExport(path) == export)
                            {
                                isTwoWay = true;
                                break;
                            }
                        }

                        //var
                        //    PropertyCollection otherSpecProperties = possibleIncomingSpec.GetProperties();

                        //    if (otherSpecProperties.GetProp<StructProperty>("End") is StructProperty endStruct)
                        //    {
                        //        if (endStruct.GetProp<ObjectProperty>(SharedPathfinding.GetReachSpecEndName(possibleIncomingSpec)) is ObjectProperty incomingTargetIdx)
                        //        {
                        //            if (incomingTargetIdx.Value == export.UIndex)
                        //            {
                        //                isTwoWay = true;
                        //                break;
                        //            }
                        //        }
                        //    }
                        //}

                        //if (othernode != null)
                        //{
                        var radius = props.GetProp <IntProperty>("CollisionRadius");
                        var height = props.GetProp <IntProperty>("CollisionHeight");

                        bool penCloned = false;
                        if (radius != null && height != null && (radius >= ReachSpecSize.MINIBOSS_RADIUS || height >= ReachSpecSize.MINIBOSS_HEIGHT))
                        {
                            penCloned = true;
                            penToUse  = (Pen)penToUse.Clone();

                            if (radius >= ReachSpecSize.BOSS_RADIUS && height >= ReachSpecSize.BOSS_HEIGHT)
                            {
                                penToUse.Width = 3;
                            }
                            else
                            {
                                penToUse.Width = 2;
                            }
                        }
                        if (!isTwoWay)
                        {
                            if (!penCloned)
                            {
                                penToUse  = (Pen)penToUse.Clone();
                                penCloned = true;
                            }
                            penToUse.DashStyle = DashStyle.Dash;
                        }

                        if (!penCloned)
                        {
                            //This will prevent immutable modifications later if we delete or modify reachspecs without a full
                            //graph redraw
                            penToUse  = (Pen)penToUse.Clone();
                            penCloned = true;
                        }

                        PathfindingEditorEdge edge = new PathfindingEditorEdge
                        {
                            Pen                 = penToUse,
                            EndPoints           = { [0] = this, [1] = othernode },
                            OutboundConnections = { [0] = true, [1] = isTwoWay }
                        };
                        if (!Edges.Any(x => x.DoesEdgeConnectSameNodes(edge)) && !othernode.Edges.Any(x => x.DoesEdgeConnectSameNodes(edge)))
                        {
                            //Only add edge if neither node contains this edge
                            Edges.Add(edge);
                            othernode.Edges.Add(edge);
                            g.edgeLayer.AddChild(edge);
                        }
                    }
                }
            }
        }