Example #1
0
    public void RemoveAt(int index, int count = 1)
    {
        if (index < 0 || index > InnerList.Count || count < 0 || count > InnerList.Count)
        {
            throw new ArgumentException("Bad arguments!");
        }


        var afterRemoved  = FindAt(index + count);
        var beforeRemoved = index == 0 ? FindLast() : FindAt(index - 1);

        beforeRemoved.Next = afterRemoved;

        if (index + count > Count)
        {
            Head = afterRemoved;
            var range1 = Count - index;
            InnerList.RemoveRange(index, range1);
            InnerList.RemoveRange(0, count - range1);
        }
        else
        {
            if (index == 0)
            {
                Head = count == Count ? null : FindAt(count);
            }
            InnerList.RemoveRange(index, count);
        }
    }
Example #2
0
        internal void ShowInfo()
        {
            CircleListNode <VisiBordPoint> checkCur = this.visiBorder.First;

            for (int i = 0; i < this.visiBorder.Length; i++)
            {
                Console.WriteLine(checkCur.value.index);
                checkCur = checkCur.next;
            }
        }
Example #3
0
        public void ApplyShelterObj(Rader rader, IShelterObj obj)
        {
            Matrix worldMatrix = obj.WorldTrans;

            CircleList <BorderPoint>     border = obj.BorderData;
            CircleListNode <BorderPoint> lastB  = border.First.pre;
            Vector2 pInRader  = rader.TranslateToRaderSpace(Vector2.Transform(ConvertHelper.PointToVector2(lastB.value.p), worldMatrix));
            int     lastIndex = IndexOf(pInRader.X);
            float   lastDepth = pInRader.Y;

            CircleListNode <BorderPoint> cur = border.First;

            for (int i = 0; i < border.Length; i++)
            {
                pInRader = rader.TranslateToRaderSpace(Vector2.Transform(ConvertHelper.PointToVector2(cur.value.p), worldMatrix));
                int   curIndex = IndexOf(pInRader.X);
                float curDepth = pInRader.Y;
                if (pInRader.X >= -1.1f && pInRader.X <= 1.3f)
                {
                    //this[pInRader.X] = Math.Min( this[pInRader.X], pInRader.Y );
                    SetValueAtIndex(curIndex, pInRader.Y, obj, i, cur.value.p);

                    if (curIndex - lastIndex > 1)
                    {
                        int overIndex = lastIndex + 1;
                        while (overIndex != curIndex)
                        {
                            float lerp = MathHelper.Lerp(lastDepth, curDepth, (curIndex - overIndex) / (curIndex - lastIndex));
                            SetValueAtIndex(overIndex, lerp, obj, i, cur.value.p);
                            overIndex++;
                        }
                    }
                    else if (curIndex - lastIndex < -1)
                    {
                        int overIndex = lastIndex - 1;
                        while (overIndex != curIndex)
                        {
                            float lerp = MathHelper.Lerp(lastDepth, curDepth, (curIndex - overIndex) / (curIndex - lastIndex));
                            SetValueAtIndex(overIndex, lerp, obj, i, cur.value.p);
                            overIndex--;
                        }
                    }
                }
                lastIndex = curIndex;
                lastDepth = curDepth;

                cur = cur.next;
            }
        }
Example #4
0
    private void AddFirst(Circle value)
    {
        var newEl = new CircleListNode(value);

        if (Count == 0)
        {
            newEl.Next = newEl;
            Head       = newEl;
        }
        else
        {
            newEl.Next      = Head;
            FindLast().Next = newEl;
            Head            = newEl;
        }

        InnerList.Insert(0, value);
    }
Example #5
0
        private static ObjVisiBorder CalNonShelterVisiBorder(IHasBorderObj obj, Rader rader)
        {
            CircleListNode <BorderPoint> curNode = obj.BorderData.First;
            CircleList <BordPoint>       points  = new CircleList <BordPoint>();

            for (int i = 0; i < obj.BorderData.Length; i++)
            {
                if (rader.PointInRader(Vector2.Transform(ConvertHelper.PointToVector2(curNode.value.p), obj.WorldTrans)))
                {
                    points.AddLast(new BordPoint(i, curNode.value.p));
                }
                curNode = curNode.next;
            }
            if (points.Length != 0)
            {
                return(new ObjVisiBorder(obj, points));
            }
            else
            {
                return(null);
            }
        }
Example #6
0
        private Point[] SurroundQueue(Point point, Point prePoint)
        {
            CircleList <Point> result = SurroundPoint.Clone();

            result.ForEach(delegate(ref Point p)
            {
                p = new Point(p.X + point.X, p.Y + point.Y);
            });

            CircleListNode <Point> find = result.FindFirst(delegate(Point p)
            {
                if (p == prePoint)
                {
                    return(true);
                }
                else
                {
                    return(false);
                }
            });

            return(result.ToArray(find, true));
        }
Example #7
0
        /// <summary>
        /// 检测是否在边界矩形外
        /// </summary>
        /// <param name="BorderRect"></param>
        /// <returns></returns>
        public CollisionResult CheckOutBorder(Rectanglef BorderRect)
        {
            if (!this.mSupportIntersectDect)
            {
                throw new Exception("the sprite doesn't support IntersectDect!");
            }

            UpdateTransformBounding();

            CollisionResult result     = new CollisionResult();
            Rectanglef      screenRect = BorderRect;


            if (!this.mBounding.Intersects(screenRect))
            {
                result.IsCollided = false;
                return(result);
            }

            int widthA  = this.mTexture.Width;
            int heightA = this.mTexture.Height;

            // Calculate a matrix which transforms from A's local space into
            // world space
            Matrix transformAToWorld = mTransform;

            Vector2 stepX = Vector2.TransformNormal(Vector2.UnitX, transformAToWorld);
            Vector2 stepY = Vector2.TransformNormal(Vector2.UnitY, transformAToWorld);

            Vector2 oriPosInWorld = Vector2.Transform(Vector2.Zero, transformAToWorld);


            CircleList <BorderPoint>     list = mBorder.BorderCircle;
            CircleListNode <BorderPoint> cur  = list.First;

            bool justStart = true;
            bool find      = false;

            CircleListNode <BorderPoint> firstNode = cur;
            int length = 0;

            #region 找出第一个相交点和该连续相交线的长度
            for (int i = 0; i < list.Length; i++)
            {
                Point bordPointA = cur.value.p;

                if (PointOutBorder(oriPosInWorld, stepX, stepY, bordPointA, screenRect))
                {
                    if (!justStart)
                    {
                        if (!find)
                        {
                            find      = true;
                            firstNode = cur;
                        }
                        else
                        {
                            length++;
                        }
                    }
                    else
                    {
                        CircleListNode <BorderPoint> temp = cur.pre;

                        int leftLength = list.Length;
                        while (PointOutBorder(oriPosInWorld, stepX, stepY, temp.value.p, screenRect) && leftLength >= 0)
                        {
                            temp = temp.pre;
                            leftLength--;
                        }
                        cur = temp;
                        i--;
                        justStart = false;
                    }
                }
                else
                {
                    justStart = false;

                    if (find)
                    {
                        break;
                    }
                }

                cur = cur.next;
            }
            #endregion

            if (find)
            {
                cur = firstNode;

                for (int i = 0; i < Math.Round((float)length / 2); i++)
                {
                    cur = cur.next;
                }

                Point bordPointA = cur.value.p;
                result.IsCollided = true;
                Vector2 InterPos = Vector2.Transform(new Vector2(bordPointA.X, bordPointA.Y), mTransform);
                result.NormalVector = Vector2.Transform(mBorder.GetNormalVector(cur, mAverageSum), mTransform)
                                      - Vector2.Transform(Vector2.Zero, mTransform);
                result.NormalVector.Normalize();
                result.InterPos = InterPos;
                return(result);
            }


            // No intersection found
            result.IsCollided = false;
            return(result);
        }
Example #8
0
        /// <summary>
        /// Determines if there is overlap of the non-transparent pixels between two
        /// sprites.
        /// 检查两个精灵是否发生碰撞
        /// </summary>
        /// <returns>True if non-transparent pixels overlap; false otherwise</returns>
        public static CollisionResult IntersectPixels(Sprite spriteA, Sprite spriteB)
        {
            if (!spriteA.mSupportIntersectDect || !spriteB.mSupportIntersectDect)
            {
                throw new Exception("At lest one of the two sprite doesn't support IntersectDect!");
            }

            spriteA.UpdateTransformBounding();
            spriteB.UpdateTransformBounding();

            CollisionResult result = new CollisionResult();

            if (!spriteA.mBounding.Intersects(spriteB.mBounding))
            {
                result.IsCollided = false;
                return(result);
            }

            int widthA  = spriteA.mTexture.Width;
            int heightA = spriteA.mTexture.Height;
            int widthB  = spriteB.mTexture.Width;
            int heightB = spriteB.mTexture.Height;

            // Calculate a matrix which transforms from A's local space into
            // world space and then into B's local space
            Matrix transformAToB = spriteA.mTransform * Matrix.Invert(spriteB.mTransform);

            // When a point moves in A's local space, it moves in B's local space with a
            // fixed direction and distance proportional to the movement in A.
            // This algorithm steps through A one pixel at a time along A's X and Y axes
            // Calculate the analogous steps in B:
            Vector2 stepX = Vector2.TransformNormal(Vector2.UnitX, transformAToB);
            Vector2 stepY = Vector2.TransformNormal(Vector2.UnitY, transformAToB);

            // Calculate the top left corner of A in B's local space
            // This variable will be reused to keep track of the start of each row
            Vector2 oriPosInB = Vector2.Transform(Vector2.Zero, transformAToB);

            CircleList <BorderPoint>     list = spriteA.mBorder.BorderCircle;
            CircleListNode <BorderPoint> cur  = list.First;

            bool justStart = true;
            bool find      = false;

            CircleListNode <BorderPoint> firstNode = cur;
            int length = 0;

            #region 找出第一个相交点和该连续相交线的长度
            for (int i = 0; i < list.Length; i++)
            {
                Point bordPointA = cur.value.p;

                if (SpriteBBlockAtPos(spriteB, oriPosInB, stepX, stepY, bordPointA))
                {
                    if (!justStart)
                    {
                        if (!find)
                        {
                            find      = true;
                            firstNode = cur;
                        }
                        else
                        {
                            length++;
                        }
                    }
                    else
                    {
                        CircleListNode <BorderPoint> temp = cur.pre;
                        while (SpriteBBlockAtPos(spriteB, oriPosInB, stepX, stepY, temp.value.p) && temp != cur)
                        {
                            temp = temp.pre;
                        }
                        cur = temp;
                        i--;
                        justStart = false;
                    }
                }
                else
                {
                    justStart = false;

                    if (find)
                    {
                        break;
                    }
                }

                cur = cur.next;
            }
            #endregion

            if (find)
            {
                cur = firstNode;

                for (int i = 0; i < Math.Round((float)length / 2); i++)
                {
                    cur = cur.next;
                }

                Point bordPointA = cur.value.p;
                result.IsCollided = true;
                Vector2 InterPos = Vector2.Transform(new Vector2(bordPointA.X, bordPointA.Y), spriteA.mTransform);
                result.NormalVector = Vector2.Transform(spriteA.mBorder.GetNormalVector(cur, spriteA.mAverageSum), spriteA.mTransform)
                                      - Vector2.Transform(Vector2.Zero, spriteA.mTransform);
                result.NormalVector.Normalize();
                result.InterPos = InterPos;
                return(result);
            }


            // No intersection found
            result.IsCollided = false;
            return(result);
        }
Example #9
0
        //public ObjVisiBorder ( IGameObj obj )
        //{
        //    this.obj = obj;
        //    this.visiBorder = new CircleList<BordPoint>();
        //}

        internal bool Combine(CircleList <VisiBordPoint> borderB)
        {
            CircleListNode <VisiBordPoint> curA = this.visiBorder.First;

            int  iA            = 0;
            bool borderUpdated = false;

            if (curA.value.index > borderB.First.value.index)
            {
                this.visiBorder.AddFirst(borderB.First.value);
                curA          = this.visiBorder.First;
                borderUpdated = true;
            }

            bool objborderChanged = false;

            foreach (VisiBordPoint pB in borderB)
            {
                while (curA.value.index < pB.index && iA < this.visiBorder.Length)
                {
                    curA = curA.next;
                    iA++;
                }
                if (curA.value.index == pB.index)
                {
                    if (curA.value.p != pB.p)
                    {
                        objborderChanged = true;
                        break;
                    }
                }
                else
                {
                    borderUpdated = true;
                    this.visiBorder.InsertAfter(pB, curA.pre);
                    curA = curA.pre;
                }
            }

            if (objborderChanged)
            {
                this.visiBorder = borderB;
            }

            #region Check Code
            //CircleListNode<BordPoint> checkCur = this.visiBorder.First;

            //int lastIndex = -1;

            //for (int i = 0; i < this.visiBorder.Length; i++)
            //{
            //    if (checkCur.value.index <= lastIndex)
            //    {
            //        Console.WriteLine( "this.visiBorder :" );
            //        this.ShowInfo();
            //        Console.WriteLine();
            //        Console.WriteLine( "borderB :" );
            //        foreach (BordPoint p in borderB)
            //        {
            //            Console.WriteLine( p.index );
            //        }

            //        throw new Exception();
            //    }

            //    lastIndex = checkCur.value.index;
            //    checkCur = checkCur.next;
            //}
            #endregion

            return(borderUpdated);
        }
Example #10
0
        public void BuildConvexHall(CircleList <BordPoint> border, float minOptimizeDest)
        {
            #region 获得原始凸包
            if (border.Length < 2)
            {
                return;
            }

            Stack <BordPoint> stack = new Stack <BordPoint>();

            CircleListNode <BordPoint> cur = border.First;
            stack.Push(cur.value);
            cur = cur.next;
            stack.Push(cur.value);
            cur = cur.next;
            for (int i = 2; i < border.Length; i++)
            {
                BordPoint p1 = stack.Pop();

                BordPoint p0 = stack.Peek();

                BordPoint p2 = cur.value;

                if (CountWise(p1, p0, p2))
                {
                    stack.Push(p1);
                    stack.Push(p2);
                    cur = cur.next;
                }
                else
                {
                    if (stack.Count == 1)
                    {
                        stack.Push(p2);
                        cur = cur.next;
                    }
                    else
                    {
                        i--;
                    }
                }
            }

            List <BordPoint> templist = new List <BordPoint>(stack);

            if (templist.Count > 3)
            {
                if (!CountWise(templist[0], templist[1], templist[templist.Count - 1]))
                {
                    templist.RemoveAt(0);
                }
                if (!CountWise(templist[templist.Count - 1], templist[0], templist[templist.Count - 2]))
                {
                    templist.RemoveAt(templist.Count - 1);
                }
            }
            else if (templist.Count == 3)
            {
                if (!CountWise(templist[0], templist[1], templist[templist.Count - 1]))
                {
                    templist.RemoveAt(0);
                    BordPoint temp = templist[0];
                    templist[0] = templist[1];
                    templist[1] = temp;
                }
            }

            #endregion

            #region 对凸包进行化简

            if (templist.Count > 3)
            {
                for (int i = 0; i < templist.Count; i++)
                {
                    Vector2 p1 = ConvertHelper.PointToVector2(templist[i].p);
                    Vector2 p2 = ConvertHelper.PointToVector2(templist[(i + 1) % templist.Count].p);
                    Vector2 p3 = ConvertHelper.PointToVector2(templist[(i + 2) % templist.Count].p);
                    Vector2 p4 = ConvertHelper.PointToVector2(templist[(i + 3) % templist.Count].p);

                    if (Vector2.Distance(p2, p3) > minOptimizeDest)
                    {
                        continue;
                    }

                    Vector2 seg1 = p2 - p1;
                    Vector2 seg2 = p4 - p3;

                    float ang = (float)Math.Acos(Vector2.Dot(seg1, seg2) / (seg1.Length() * seg2.Length()));
                    if (ang > MathHelper.PiOver2)
                    {
                        continue;
                    }

                    Line line1 = new Line(p1, seg1);
                    Line line2 = new Line(p4, seg2);

                    Vector2 interPoint;

                    if (!MathTools.InterPoint(line1, line2, out interPoint))
                    {
                        continue;
                    }

                    templist[(i + 1) % templist.Count] =
                        new BordPoint(templist[(i + 1) % templist.Count].index, ConvertHelper.Vector2ToPoint(interPoint));

                    templist.RemoveAt((i + 2) % templist.Count);

                    i--;
                }
            }

            #endregion

            convexPoints = templist;
        }