Пример #1
0
        static void WEAKEST_LINK()
        {
            int N, skipPerem, countOfRound = 1;
            CircleList <int> manInCircle = new CircleList <int>();

            Console.WriteLine("Введите N: ");
            int.TryParse(Console.ReadLine(), out N);
            Console.WriteLine("Введите, какой по счету человек будет вычеркнут каждый раунд: ");
            int.TryParse(Console.ReadLine(), out skipPerem);

            for (int i = 0; i < N; i++)
            {
                manInCircle.Add(i + 1);
            }

            while (manInCircle.Count > 1 && manInCircle.Count >= skipPerem)
            {
                manInCircle.RemoveThrough(skipPerem);
                Console.WriteLine("Раунд {0} : осталось {1}", countOfRound, manInCircle.Count);
                countOfRound++;
            }

            Console.WriteLine("\nЛюди в кругу: \n");

            foreach (var item in manInCircle)
            {
                Console.WriteLine("Человек {0}", item);
            }
        }
Пример #2
0
    CircleList GetNewCircle()
    {
        CircleList CircleList = Instantiate(PrefabList, Root);

        CircleList.Init();
        return(CircleList);
    }
Пример #3
0
    private IEnumerator PlaceStartCircles()
    {
        var startDigits = new[] { 2, 1, 2, 2, 2, 2, 4, 4 };

        for (var i = 0; i < StartCount;)
        {
            var circle = CreateCircle(startDigits[i]);
            yield return(list.AddAt(circle, i, false));

            var pos = CircleList.GetCirclePosition(i, StartCount);
            circle.Move(pos);

            while (list.IsMoving)
            {
                yield return(null);
            }

            death.Increase();
            i++;
        }

        yield return(list.RenderList());

        playerTurnEvent.Invoke();
    }
Пример #4
0
        public void CalSheltersVisiBorder()
        {
            Dictionary <IShelterObj, List <VisiBordPoint> > temp = new Dictionary <IShelterObj, List <VisiBordPoint> >();

            int index = 0;

            foreach (IShelterObj obj in objMap)
            {
                if (obj != null)
                {
                    if (!temp.ContainsKey(obj))
                    {
                        temp.Add(obj, new List <VisiBordPoint>());
                    }
                    temp[obj].Add(objBordIndexMap[index]);
                }
                index++;
            }

            curObjVisiBorders = new ObjVisiBorder[temp.Count];

            curShelters = new IShelterObj[temp.Count];

            int i = 0;

            foreach (KeyValuePair <IShelterObj, List <VisiBordPoint> > pair in temp)
            {
                pair.Value.Sort(
                    delegate(VisiBordPoint p1, VisiBordPoint p2)
                {
                    if (p1.index < p2.index)
                    {
                        return(-1);
                    }
                    else if (p1.index == p2.index)
                    {
                        return(0);
                    }
                    else
                    {
                        return(1);
                    }
                });

                CircleList <VisiBordPoint> points = new CircleList <VisiBordPoint>();

                foreach (VisiBordPoint p in pair.Value)
                {
                    if (points.Last == null || points.Last.value.index != p.index)
                    {
                        points.AddLast(p);
                    }
                }

                curObjVisiBorders[i] = new ObjVisiBorder((IHasBorderObj)pair.Key, points);
                curShelters[i]       = pair.Key;

                i++;
            }
        }
Пример #5
0
 private async Task RefreshCircleList()
 {
     this.circleList = await CircleList.SyncAsync(this.circleList, this.map1.JsRuntime, circleOptionsByRef, async (ev, sKey, entity) => {
         // Circle has been clicked --> delete it.
         this.circleOptionsByRef.Remove(sKey);
         await this.RefreshCircleList();
     });
 }
Пример #6
0
        private void OnPlayerInfo(MsgBase b)
        {
            var  selfMsg = (Msg_AgarPlayInfo)b;
            uint id      = selfMsg.UserId;

            if (selfMsg.Operat == Msg_AgarPlayInfo.Add)
            {
                var player = new DefaultUserCircle(
                    new Vector2(selfMsg.X, selfMsg.Y),
                    selfMsg.Radius,
                    selfMsg.Color,
                    selfMsg.Name);

                CircleList[id] = player;
                this.AddChind(player, OtherPlayerZOrder);
            }
            else if (selfMsg.Operat == Msg_AgarPlayInfo.Remove)
            {
                if (!CircleList.ContainsKey(id))
                {
                    return;
                }
                var player = CircleList[id];
                this.RemoveChild(player);
                CircleList.Remove(id);
            }
            else if (selfMsg.Operat == Msg_AgarPlayInfo.Changed)
            {
                if (!CircleList.ContainsKey(id))
                {
                    return;
                }
                uint tag    = selfMsg.Tag;
                var  player = CircleList[id];
                if (GameMessageHelper.Is_Changed(tag, GameMessageHelper.POSITION_TAG))
                {
                    player.Position = new Vector2(selfMsg.X, selfMsg.Y);
                }
                if (GameMessageHelper.Is_Changed(tag, GameMessageHelper.RADIUS_TAG))
                {
                    player.Radius = selfMsg.Radius;
                }
                if (GameMessageHelper.Is_Changed(tag, GameMessageHelper.COLOR_TAG))
                {
                    player.ColorProperty = selfMsg.Color.ToColor();
                }
                if (GameMessageHelper.Is_Changed(tag, GameMessageHelper.NAME_TAG))
                {
                    player.Name = selfMsg.Name;
                }
            }
        }
Пример #7
0
 private void InitialSurroundPoint()
 {
     SurroundPoint = new CircleList <Point>();
     SurroundPoint.AddLast(new Point(-1, -1));
     SurroundPoint.AddLast(new Point(0, -1));
     SurroundPoint.AddLast(new Point(1, -1));
     SurroundPoint.AddLast(new Point(1, 0));
     SurroundPoint.AddLast(new Point(1, 1));
     SurroundPoint.AddLast(new Point(0, 1));
     SurroundPoint.AddLast(new Point(-1, 1));
     SurroundPoint.AddLast(new Point(-1, 0));
     SurroundPoint.LinkLastAndFirst();
 }
Пример #8
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;
            }
        }
Пример #9
0
        private void OnMarkListPack(MsgBase b)
        {
            var selfMsg = (Msg_AgarMarkListPack)b;

            MarkList.Clear();

            foreach (var obj in selfMsg.MarkList)
            {
                if (CircleList.ContainsKey(obj.Key))
                {
                    MarkList.Add(new KeyValuePair <string, int>(CircleList[obj.Key].Name, obj.Value));
                }
                else if (obj.Key == Uid && Player != null)
                {
                    MarkList.Add(new KeyValuePair <string, int>(Player.Name, obj.Value));
                }
            }
            // 暂时只接受数据不显示
        }
Пример #10
0
        public CEntityComplexShape(
            CTableLayer layer,
            Guid ToolPk)
            : base()
        {
            PK = ToolPk;

            foreach (CEntityLine line in layer.LineList)
            {
                LineList.Add(line);
            }

            foreach (CEntityCircle circle in layer.CircleList)
            {
                CircleList.Add(circle);
            }

            foreach (CEntityArc arc in layer.ArcList)
            {
                ArcList.Add(arc);
            }
        }
Пример #11
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);
            }
        }
Пример #12
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));
        }
Пример #13
0
        static void Main(string[] args)
        {
            Stopwatch watch = new Stopwatch();

            watch.Start();

            List <int> numbers = File.ReadAllText("input.txt".ToApplicationPath()).Select(x => int.Parse(x.ToString())).ToList();

            CircleList <int> partOneNumbers = new CircleList <int>(numbers);
            string           partOne        = DoAlgorithm(partOneNumbers, 100, 1);

            for (int i = numbers.Max() + 1; i <= 1000000; i++)
            {
                numbers.Add(i);
            }

            CircleList <int> milNumbers = new CircleList <int>(numbers);
            string           partTwo    = DoAlgorithm(milNumbers, 10000000, 2);

            watch.Stop();

            Console.WriteLine($"Part one result: {partOne}\nPart two result: {partTwo}\nExecution time: {watch.ElapsedMilliseconds} ms");
        }
Пример #14
0
 public ConvexHall ( CircleList<VisiBordPoint> border, float minOptimizeDest )
 {
     BuildConvexHall( border, minOptimizeDest );
 }
Пример #15
0
        public void CalSheltersVisiBorder()
        {
            Dictionary<IShelterObj, List<BordPoint>> temp = new Dictionary<IShelterObj, List<BordPoint>>();

            int index = 0;
            foreach (IShelterObj obj in objMap)
            {
                if (obj != null)
                {
                    if (!temp.ContainsKey( obj ))
                    {
                        temp.Add( obj, new List<BordPoint>() );
                    }
                    temp[obj].Add( objBordIndexMap[index] );
                }
                index++;
            }

            curObjVisiBorders = new ObjVisiBorder[temp.Count];

            curShelters = new IShelterObj[temp.Count];

            int i = 0;
            foreach (KeyValuePair<IShelterObj, List<BordPoint>> pair in temp)
            {
                pair.Value.Sort(
                    delegate( BordPoint p1, BordPoint p2 )
                    {
                        if (p1.index < p2.index)
                            return -1;
                        else if (p1.index == p2.index)
                            return 0;
                        else
                            return 1;
                    } );

                CircleList<BordPoint> points = new CircleList<BordPoint>();

                foreach (BordPoint p in pair.Value)
                {
                    if (points.Last == null || points.Last.value.index != p.index)
                        points.AddLast( p );
                }

                curObjVisiBorders[i] = new ObjVisiBorder( (IHasBorderObj)pair.Key, points );
                curShelters[i] = pair.Key;

                i++;
            }
        }
Пример #16
0
 private static ObjVisiBorder CalNonShelterVisiBorder( IHasBorderObj obj, Rader rader )
 {
     CircleListNode<BorderPoint> curNode = obj.BorderData.First;
     CircleList<VisiBordPoint> points = new CircleList<VisiBordPoint>();
     for (int i = 0; i < obj.BorderData.Length; i++)
     {
         if (rader.PointInRader( Vector2.Transform( ConvertHelper.PointToVector2( curNode.value.p ), obj.WorldTrans ) ))
         {
             points.AddLast( new VisiBordPoint( i, curNode.value.p ) );
         }
         curNode = curNode.next;
     }
     if (points.Length != 0)
         return new ObjVisiBorder( obj, points );
     else
         return null;
 }
Пример #17
0
        public void BuildConvexHall ( CircleList<VisiBordPoint> border, float minOptimizeDest )
        {
            #region 获得原始凸包
            if (border.Length < 2)
                return;

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

            CircleListNode<VisiBordPoint> 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++)
            {
                VisiBordPoint p1 = stack.Pop();

                VisiBordPoint p0 = stack.Peek();

                VisiBordPoint 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<VisiBordPoint> templist = new List<VisiBordPoint>( 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 );
                    VisiBordPoint 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 VisiBordPoint( templist[(i + 1) % templist.Count].index, ConvertHelper.Vector2ToPoint( interPoint ) );

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

                    i--;
                }
            }

            #endregion

            convexPoints = templist;
        }
Пример #18
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);
        }
Пример #19
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);
        }
Пример #20
0
 public ConvexHall(CircleList <BordPoint> border, float minOptimizeDest)
 {
     BuildConvexHall(border, minOptimizeDest);
 }
Пример #21
0
 private void InitialSurroundPoint ()
 {
     SurroundPoint = new CircleList<Point>();
     SurroundPoint.AddLast( new Point( -1, -1 ) );
     SurroundPoint.AddLast( new Point( 0, -1 ) );
     SurroundPoint.AddLast( new Point( 1, -1 ) );
     SurroundPoint.AddLast( new Point( 1, 0 ) );
     SurroundPoint.AddLast( new Point( 1, 1 ) );
     SurroundPoint.AddLast( new Point( 0, 1 ) );
     SurroundPoint.AddLast( new Point( -1, 1 ) );
     SurroundPoint.AddLast( new Point( -1, 0 ) );
     SurroundPoint.LinkLastAndFirst();
 }
Пример #22
0
 public ObjVisiBorder(IHasBorderObj obj, CircleList <VisiBordPoint> visiBorder)
 {
     this.obj        = obj;
     this.visiBorder = visiBorder;
     this.visiBorder.LinkLastAndFirst();
 }
Пример #23
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);
        }
Пример #24
0
    public void CalculateBends()
    {
        if (!IsCircular)
        {
            return;
        }
        Bends = new CircleList <Bend>();
        Bend           _bend      = new Bend();
        int            BendId     = 0;
        MovingAvgFloat AngleQueue = new MovingAvgFloat(5);

        _bez = BezierLine.Instance;
        int      XSecCount = XSecs.Count();
        Vector3  PrevMid;
        Vector3  ThisMid;
        Vector3  NextMid;
        BendType _bt            = BendType.Unknown;
        BendType _prevbt        = BendType.Unknown;
        int      Incr           = 1;
        float    AngleThreshold = 1.34f;

        foreach (XSec X in XSecs)
        {
            PrevMid = XSecs.Prev(X).MidPt;
            ThisMid = X.MidPt;
            NextMid = XSecs.Next(X).MidPt;
            float Angle    = VectGeom.SignedAngle(ThisMid + ThisMid - PrevMid, ThisMid, NextMid, Vector3.up);
            float _segDist = Vector3.Distance(ThisMid, NextMid);
            AngleQueue.Push(Angle);
            if (Mathf.Abs(AngleQueue.Avg) < AngleThreshold)
            {
                _bt = BendType.Straight;
            }
            else
            {
                _bt = AngleQueue.Avg > 0 ? BendType.Right : BendType.Left;
            }

            if (_prevbt == _bt)
            {
                _bend.Angle += Angle;
            }
            else
            {
                if (_prevbt == BendType.Left || _prevbt == BendType.Right)
                {  //Finish off the previous bend
                    if (Mathf.Abs(_bend.Angle) < 15)
                    {
                        //ignore small bends
                        Bends.Remove(_bend);
                        BendId--;
                    }
                    else
                    {
                        //take 2 off cos of moving avg
                        _bend.EndXSec    = XSecs[X.Idx - 2];
                        _bend.EndSegIdx  = _bend.EndXSec.Idx;
                        _bend.ApexXSec   = XSecs[_bend.StartSegIdx + Mathf.RoundToInt(XSecs.Diff(_bend.StartXSec, _bend.EndXSec) / 2)];
                        _bend.ApexSegIdx = _bend.ApexXSec.Idx;
                        if (_bend.Type == BendType.Right)
                        {
                            _bend.ApexPos = _bend.ApexXSec.KerbR + (_bend.ApexXSec.KerbL - _bend.ApexXSec.KerbR).normalized; _bend.MinTurninPos = _bend.StartXSec.KerbR + (_bend.StartXSec.KerbL - _bend.StartXSec.KerbR).normalized * (_bend.Concatenated ? 4 : 2);
                        }
                        if (_bend.Type == BendType.Left)
                        {
                            _bend.ApexPos = _bend.ApexXSec.KerbL + (_bend.ApexXSec.KerbR - _bend.ApexXSec.KerbL).normalized; _bend.MinTurninPos = _bend.StartXSec.KerbL + (_bend.StartXSec.KerbR - _bend.StartXSec.KerbL).normalized * (_bend.Concatenated ? 4 : 2);
                        }
                        //Fmax = mv^2/r
                        float c = (_bend.EndSegIdx - _bend.StartSegIdx) * 360 / _bend.Angle;
                        float r = Mathf.Abs(c) / Mathf.PI / 2f;
                        //Debug.Log("Bend" + _bend.BendId + " radius = " + r);
                        _bend.SqrtRad = Mathf.Sqrt(r);
                    }
                }
                else
                {   //We might be starting a new bend or carrying n the previous one
                    if (_bt == BendType.Left || _bt == BendType.Right)
                    {
                        bool StartNewBend = true;

                        if (BendId > 0 && X.Idx - Bends[BendId - 1].EndSegIdx < 15 && Bends[BendId - 1].Type == _bt) ///bugbugbug circle bug
                        {                                                                                            //if the bend we've just finished is close to and the same sign as one before
                          //We just carry on with this bend and dont create a new one
                            StartNewBend       = false;
                            _bend.Concatenated = true;
                            GameObject.Destroy(GameObject.Find("Turnin" + _bend.BendId));
                            GameObject.Destroy(GameObject.Find("Apex" + _bend.BendId));
                            GameObject.Destroy(GameObject.Find("BendStart" + _bend.BendId));
                        }

                        if (StartNewBend)
                        {
                            //Create a new Bend
                            _bend             = new Bend();
                            _bend.Type        = _bt;
                            _bend.Sign        = _bt == BendType.Right ? (Int16)1 : (Int16)(-1);
                            _bend.StartXSec   = XSecs[X.Idx - 2];//-2 cos of moving avg
                            _bend.StartSegIdx = _bend.StartXSec.Idx;
                            _bend.Angle       = Angle;
                            _bend.BendId      = BendId;
                            Bends.Add(_bend);
                            BendId++;
                        }
                    }
                }
                //******************************************************************************************
            }
            _prevbt = _bt;
        }
        //This is the last bend. NOt a brilliant bit but it doesn't crash
        if (_bt == BendType.Straight)
        {
            goto Finalise;
        }
        _bend.EndSegIdx = XSecs.Count - 1;
        _bend.EndXSec   = XSecs[_bend.EndSegIdx];
        if (_bend.EndSegIdx <= _bend.StartSegIdx && Bends.Count() > 0)
        {
            Bends.Remove(_bend); Bends.Last().EndSegIdx = XSecs.Count;
        }
        else
        {
            _bend.ApexSegIdx = Mathf.RoundToInt((_bend.EndSegIdx + _bend.StartSegIdx) / 2);
            _bend.ApexXSec   = XSecs[_bend.ApexSegIdx];
            if (_bend.Type == BendType.Right)
            {
                _bend.ApexPos = _bend.ApexXSec.KerbR + (_bend.ApexXSec.KerbL - _bend.ApexXSec.KerbR).normalized;
            }
            if (_bend.Type == BendType.Left)
            {
                _bend.ApexPos = _bend.ApexXSec.KerbL + (_bend.ApexXSec.KerbR - _bend.ApexXSec.KerbL).normalized;
            }
        }
Finalise:
        CalculateTurninAndExitPoints();
        PopulateXSecCurrBends();
    }
Пример #25
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;
        }
Пример #26
0
        static string DoAlgorithm(CircleList <int> startingNumbers, int moves, int part)
        {
            Dictionary <LinkedListNode <int>, List <LinkedListNode <int> > > destinationCache = new Dictionary <LinkedListNode <int>, List <LinkedListNode <int> > >();

            LinkedListNode <int>         currentNode = startingNumbers.First;
            List <LinkedListNode <int> > maxNodes    = new List <LinkedListNode <int> >();
            List <int> max5 = startingNumbers.ToList().Where(x => x > currentNode.Value).OrderByDescending(x => x).Take(5).ToList();

            foreach (int i in max5)
            {
                maxNodes.Add(startingNumbers.Find(i));
            }
            destinationCache.Add(currentNode, new List <LinkedListNode <int> >());
            List <int> smaller5tmp = startingNumbers.ToList().Where(x => x < currentNode.Value).OrderByDescending(x => x).Take(5).ToList();

            foreach (int i in smaller5tmp)
            {
                destinationCache[currentNode].Add(startingNumbers.Find(i));
            }

            LinkedListNode <int> nextNode = currentNode.NextOrFirst();

            while (nextNode.Value != currentNode.Value)
            {
                if (nextNode.Value < 15)
                {
                    destinationCache.Add(nextNode, new List <LinkedListNode <int> >());
                    List <int> smaller5 = startingNumbers.ToList().Where(x => x < nextNode.Value).OrderByDescending(x => x).Take(5).ToList();
                    foreach (int i in smaller5)
                    {
                        destinationCache[nextNode].Add(startingNumbers.Find(i));
                    }
                }
                else
                {
                    destinationCache.Add(nextNode, nextNode.PreviousOfNumber(5).ToList());
                }

                nextNode = nextNode.NextOrFirst();
            }

            for (int i = 1; i <= moves; i++)
            {
                // if (i % 100000 == 0)
                // {
                //   Console.WriteLine("Move " + i);
                // }
                // WriteOutput($"-- Move {i} --");
                // WriteOutput($"Cups: {string.Join(" ", startingNumbers.ToList().Select((x, id) => id == i - 1 ? "(" + x + ")" : x.ToString()).ToList())}");

                List <LinkedListNode <int> > numbers = startingNumbers.RemoveNextThree(currentNode).ToList();
                // WriteOutput($"Pick up: {numbers[0].Value}, {numbers[1].Value}, {numbers[2].Value}");

                LinkedListNode <int> destination = GetDestination(destinationCache, maxNodes, currentNode, numbers[0].Value, numbers[1].Value, numbers[2].Value);
                // WriteOutput($"Destination: {destination.Value}");

                startingNumbers.InsertAfterNode(destination, numbers[0], numbers[1], numbers[2]);
                currentNode = currentNode.NextOrFirst();
                // WriteOutput();
            }

            // WriteOutput("-- Final --");
            // WriteOutput($"Cups: {string.Join(" ", startingNumbers.ToList())}");
            // WriteOutput();
            string answer = string.Empty;
            LinkedListNode <int> firstValue = startingNumbers.Find(1);

            if (firstValue != null)
            {
                if (part == 1)
                {
                    LinkedListNode <int> nextValue = firstValue.NextOrFirst();
                    int cachedValue = nextValue.Value;
                    answer   += cachedValue;
                    nextValue = nextValue.NextOrFirst();

                    while (nextValue.Value != cachedValue)
                    {
                        if (nextValue.Value != 1)
                        {
                            answer += nextValue.Value;
                        }
                        nextValue = nextValue.NextOrFirst();
                    }
                }
                else
                {
                    List <LinkedListNode <int> > nextValues = firstValue.NextOfNumber(3).ToList();
                    answer = ((long)nextValues[0].Value * (long)nextValues[1].Value).ToString();
                }
            }

            return(answer);
        }
Пример #27
0
 public ObjVisiBorder ( IHasBorderObj obj, CircleList<VisiBordPoint> visiBorder )
 {
     this.obj = obj;
     this.visiBorder = visiBorder;
     this.visiBorder.LinkLastAndFirst();
 }
Пример #28
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;
        }