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); } }
CircleList GetNewCircle() { CircleList CircleList = Instantiate(PrefabList, Root); CircleList.Init(); return(CircleList); }
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(); }
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++; } }
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(); }); }
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; } } }
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(); }
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; } }
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)); } } // 暂时只接受数据不显示 }
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); } }
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); } }
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)); }
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"); }
public ConvexHall ( CircleList<VisiBordPoint> border, float minOptimizeDest ) { BuildConvexHall( border, minOptimizeDest ); }
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++; } }
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; }
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; }
/// <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); }
/// <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); }
public ConvexHall(CircleList <BordPoint> border, float minOptimizeDest) { BuildConvexHall(border, minOptimizeDest); }
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(); }
public ObjVisiBorder(IHasBorderObj obj, CircleList <VisiBordPoint> visiBorder) { this.obj = obj; this.visiBorder = visiBorder; this.visiBorder.LinkLastAndFirst(); }
//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); }
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(); }
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; }
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); }
public ObjVisiBorder ( IHasBorderObj obj, CircleList<VisiBordPoint> visiBorder ) { this.obj = obj; this.visiBorder = visiBorder; this.visiBorder.LinkLastAndFirst(); }
//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; }