/// <summary> /// 返回Range对象范围中的最右下角点的那个单元格对象 /// </summary> /// <param name="SourceRange">对于对Range.Areas.Item(1)中的单元格区域进行操作</param> /// <param name="Corner">要返回哪一个角落的单元格</param> /// <returns></returns> public static Range Ex_CornerCell(this Range SourceRange, CornerIndex Corner) { Range myCornerCell = null; // SourceRange = SourceRange.Areas[1]; Range LeftTopCell = SourceRange.Cells[1, 1] as Range;; // switch (Corner) { case CornerIndex.BottomRight: myCornerCell = SourceRange.Worksheet.Cells[LeftTopCell.Row + SourceRange.Rows.Count - 1, LeftTopCell.Column + SourceRange.Columns.Count - 1] as Range; break; case CornerIndex.UpRight: myCornerCell = SourceRange.Worksheet.Cells[LeftTopCell.Row, LeftTopCell.Column + SourceRange.Columns.Count - 1] as Range;; break; case CornerIndex.BottomLeft: myCornerCell = SourceRange.Worksheet.Cells[LeftTopCell.Row + SourceRange.Rows.Count - 1, LeftTopCell.Column] as Range;; break; case CornerIndex.UpLeft: myCornerCell = LeftTopCell; break; } return(myCornerCell); }
// this is called by a zombie to compute the (heuristic) distance between current position // and the position of the next corner // This distance ignore the x-component if zombie is moving in the y direction // or the y-component if zombie is moving in the x direction public float distanceLeft(CornerIndex ci, Vector3 position, bool direction) { Vector2 temp = getCorner(ci); if ((ci.j % 2 == 0 && direction) || (ci.j % 2 == 1 && !direction)) { return((float)Mathf.Abs(temp.y - position.y)); } else { return((float)Mathf.Abs(temp.x - position.x)); } }
// switch to a random track adjacent to the current one // return the shif in position public Vector2 changeTrack(CornerIndex ci, Zombie z) { if (ci.i == 2 || (Random.value > 0.5 && ci.i > 0)) { if (!z.zombieNearBy(trackDelta[ci.j])) { ci.i--; return(trackDelta[ci.j]); } } else if (!z.zombieNearBy(trackDelta[(ci.j + 2) % 4])) { ci.i++; return(trackDelta[(ci.j + 2) % 4]); } return(Vector2.zero); }
// this is called by Phone Addict Zombies when they are travelling at the opposite direction public Vector2 turnReverse(CornerIndex ci) { ci.j = (4 + ci.j - 1) % 4; return(getCorner(ci)); }
/*** * Functions called by zombies: */ // this is called by a zombie when it arrives at a corner // returns the next corner to go to public Vector2 turn(CornerIndex ci) { ci.j = (ci.j + 1) % 4; return(getCorner(ci)); }
// helper function to access an entry in the corner array public Vector2 getCorner(CornerIndex ci) { return(corners [ci.i] [ci.j]); }
/// <summary> /// Connects the specified candidate edges to the specified Voronoi region by inserting /// edges that span a border or corner of the <see cref="ClippingBounds"/>.</summary> /// <param name="candidates"> /// A <see cref="LinkedList{PointI}"/> containing the candidate edges that must be connected /// to the specified <paramref name="region"/>.</param> /// <param name="region"> /// A <see cref="LinkedList{PointI}"/> containing the sorted and connected edges of the /// Voronoi region. The first and last vertex must touch the <see cref="ClippingBounds"/>. /// </param> /// <remarks> /// <b>ConnectCandidates</b> adds one or two edges at the beginning of the specified /// <paramref name="candidates"/> list. If two edges are added, both will contain one /// pseudo-vertex represented by a <see cref="CornerIndex"/> value.</remarks> private void ConnectCandidates(LinkedList <PointI> candidates, LinkedList <PointI> region) { int firstIndex = region.First.Value.X; int lastIndex = region.Last.Value.Y; PointD firstVertex = GetVertex(firstIndex); PointD lastVertex = GetVertex(lastIndex); Debug.Assert(IsAtClippingBounds(firstVertex)); Debug.Assert(IsAtClippingBounds(lastVertex)); // outer vertex indices of connecting edge(s) int connect1 = -1, connect2 = -1; foreach (PointI candidate in candidates) { connect1 = candidate.X; PointD connectVertex = GetVertex(connect1); if (MeetAtClippingBounds(connectVertex, firstVertex)) { connect2 = firstIndex; break; } if (MeetAtClippingBounds(connectVertex, lastVertex)) { connect2 = lastIndex; break; } connect1 = candidate.Y; connectVertex = GetVertex(connect1); if (MeetAtClippingBounds(connectVertex, firstVertex)) { connect2 = firstIndex; break; } if (MeetAtClippingBounds(connectVertex, lastVertex)) { connect2 = lastIndex; break; } } if (connect2 >= 0) { // add connecting edge on same clipping border candidates.AddFirst(new PointI(connect1, connect2)); return; } connect1 = -1; connect2 = -1; CornerIndex corner = CornerIndex.None; foreach (PointI candidate in candidates) { connect1 = candidate.X; PointD connectVertex = GetVertex(connect1); corner = GetCornerIndex(connectVertex, firstVertex); if (corner != CornerIndex.None) { connect2 = firstIndex; break; } corner = GetCornerIndex(connectVertex, lastVertex); if (corner != CornerIndex.None) { connect2 = lastIndex; break; } connect1 = candidate.Y; connectVertex = GetVertex(connect1); corner = GetCornerIndex(connectVertex, firstVertex); if (corner != CornerIndex.None) { connect2 = firstIndex; break; } corner = GetCornerIndex(connectVertex, lastVertex); if (corner != CornerIndex.None) { connect2 = lastIndex; break; } } // add connecting edges across clipping corner Debug.Assert(connect2 >= 0); candidates.AddFirst(new PointI((int)corner, connect2)); candidates.AddFirst(new PointI(connect1, (int)corner)); }