/// <summary> /// 设置海拔,距离海岸线越远,海拔越高 /// </summary> /// <returns>返回最高点</returns> private float _LandRiseElevation( ) { // 待设置的拐角 Queue <RasterIndex> cornerQueue = new Queue <RasterIndex>(_coastCornerList); // 某一圈的数量 int count = cornerQueue.Count; // 离海洋的距离,从1开始 float dis = 1; // 广度优先搜索,每次加入一个内圈的 while (cornerQueue.Count > 0) { // 上一圈已经全部搞定 if (count == 0) { count = cornerQueue.Count; dis += 0.1f; } RasterIndex corner = cornerQueue.Dequeue(); count--; uint x = corner.x; uint y = corner.y; _cornerElevations[x, y] = dis; // 周围4个点是否是land?是否已加入下一圈?已加入设为255 if (_cornerTypes[x + 1, y] == CornerType.kLand && _cornerElevations[x + 1, y] == 0) { _cornerElevations[x + 1, y] = byte.MaxValue; cornerQueue.Enqueue(new RasterIndex(x + 1, y)); } if (_cornerTypes[x, y + 1] == CornerType.kLand && _cornerElevations[x, y + 1] == 0) { _cornerElevations[x, y + 1] = byte.MaxValue; cornerQueue.Enqueue(new RasterIndex(x, y + 1)); } if (_cornerTypes[x - 1, y] == CornerType.kLand && _cornerElevations[x - 1, y] == 0) { _cornerElevations[x - 1, y] = byte.MaxValue; cornerQueue.Enqueue(new RasterIndex(x - 1, y)); } if (_cornerTypes[x, y - 1] == CornerType.kLand && _cornerElevations[x, y - 1] == 0) { _cornerElevations[x, y - 1] = byte.MaxValue; cornerQueue.Enqueue(new RasterIndex(x, y - 1)); } } return(dis); }
/// <summary> /// 用栅格逼近圆 /// </summary> /// <param name="center">圆心</param> /// <param name="radius">圆半径</param> /// <returns>栅格的标号,只需第一象限的1/4</returns> public RasterIndex[] GetCircleIndices(RasterIndex center, float radius) { float minSize = Mathf.Min(_border.size.x, _border.size.y); radius = Mathf.Min(minSize * 0.9f, radius); uint radiusNumber = (uint)(radius / _squareSize); List <RasterIndex> result = new List <RasterIndex>(); // 第一个栅格的位置 RasterIndex index = new RasterIndex(); index.x = center.x; index.y = center.y - radiusNumber; result.Add(index); while (index.x <= center.x + radiusNumber && index.y <= center.y) { // 向右下方 RasterIndex right = new RasterIndex(index.x + 1, index.y); RasterIndex down = new RasterIndex(index.x, index.y + 1); RasterIndex rightDown = new RasterIndex(index.x + 1, index.y + 1); index = right; float dis = Vector2.Distance(GetSquareCenter(index), GetSquareCenter(center)); float minDiff = Mathf.Abs(dis - radius); dis = Vector2.Distance(GetSquareCenter(down), GetSquareCenter(center)); float diff = Mathf.Abs(dis - radius); if (diff < minDiff) { minDiff = diff; index = down; } dis = Vector2.Distance(GetSquareCenter(rightDown), GetSquareCenter(center)); diff = Mathf.Abs(dis - radius); if (diff < minDiff) { minDiff = diff; index = rightDown; } result.Add(index); } return(result.ToArray()); }
// Start is called just before any of the Update methods is called the first time public void Start( ) { // 初始化栅格 Rect border = new Rect(Vector2.zero, mapSize); _squareSize = border.size.x / m; n = (uint)(border.size.y / _squareSize); _raster = new Raster(border, m, 0.5f); float minSize = Mathf.Min(mapSize.x, mapSize.y) * 0.48f; radius = Mathf.Min(minSize, radius); normalizedRadius = radius / minSize; // 默认整个栅格的中心 _centerIndex = new RasterIndex(m / 2, n / 2); _centerPoint = _raster.GetSquareCenter(_centerIndex); _setElevationMethods = new Dictionary <byte, SetElevationDelegate>(); _setElevationMethods.Add((byte)ElevationType.kFlat, _FlatElevation); _setElevationMethods.Add((byte)ElevationType.kRise, _LandRiseElevation); _setIsIslandMethods = new Dictionary <byte, SetIsIslandDelegate>(); _setIsIslandMethods.Add((byte)IslandType.kCircle, _IsInsideCircleIsland); _setIsIslandMethods.Add((byte)IslandType.kPerlin, _IsInsidePerlinIsland); float maxHeight = 0; if (islandType == IslandType.kCircle) { _noise1D = new PerlinNoise1D(ampl: 100, count: 8, freq: 10); _SetCoastPoint(); maxHeight = _setElevationMethods[(byte)elevationType](); _SetHeight(terrain.terrainData, maxHeight); } else if (islandType == IslandType.kPerlin) { _noise2D = new PerlinNoise2D((uint)mapSize.x, (uint)mapSize.y); _SetCoastPoint(); maxHeight = _setElevationMethods[(byte)elevationType](); _SetHeight(terrain.terrainData, maxHeight); } //Test(); }
public Vector2 GetSquareCenter(RasterIndex index) { return(SquareCenters[index.x, index.y]); }
public Vector2[] GetSquareCorner(RasterIndex index) { return(GetSquareCorner(index.x, index.y)); }