private GeologyTerrain[,] ConvertToGeology(Map1 map, float refinement) { GeologyTerrain[,] geologyTerrains = new GeologyTerrain[(int)map.Width, (int)map.Height]; for (int i = 0; i < map.Width; ++i) { for (int j = 0; j < map.Height; ++j) { geologyTerrains[i, j] = new GeologyTerrain(); } } foreach (var center in map.Graph.centers) { float perlinNoise = Mathf.PerlinNoise(refinement + (int)center.point.x, refinement + (int)center.point.y); eGeology geology = GetGeology(perlinNoise); geologyTerrains.FillPolygon(center.corners.Select(p => p.point * _textureScale).ToArray(), geology); } return(geologyTerrains); }
public static void FillPolygon(this GeologyTerrain[,] geologyTerrains, Vector2[] points, eGeology geology) { // http://alienryderflex.com/polygon_fill/ var IMAGE_BOT = (int)points.Max(p => p.y); var IMAGE_TOP = (int)points.Min(p => p.y); var IMAGE_LEFT = (int)points.Min(p => p.x); var IMAGE_RIGHT = (int)points.Max(p => p.x); var MAX_POLY_CORNERS = points.Count(); var polyCorners = MAX_POLY_CORNERS; var polyY = points.Select(p => p.y).ToArray(); var polyX = points.Select(p => p.x).ToArray(); int[] nodeX = new int[MAX_POLY_CORNERS]; int nodes, pixelX, i, j, swap; // Loop through the rows of the image. for (int pixelY = IMAGE_TOP; pixelY <= IMAGE_BOT; pixelY++) { // Build a list of nodes. nodes = 0; j = polyCorners - 1; for (i = 0; i < polyCorners; i++) { if (polyY[i] < (float)pixelY && polyY[j] >= (float)pixelY || polyY[j] < (float)pixelY && polyY[i] >= (float)pixelY) { nodeX[nodes++] = (int)(polyX[i] + (pixelY - polyY[i]) / (polyY[j] - polyY[i]) * (polyX[j] - polyX[i])); } j = i; } // Sort the nodes, via a simple “Bubble” sort. i = 0; while (i < nodes - 1) { if (nodeX[i] > nodeX[i + 1]) { swap = nodeX[i]; nodeX[i] = nodeX[i + 1]; nodeX[i + 1] = swap; if (i != 0) { i--; } } else { i++; } } // Fill the pixels between node pairs. for (i = 0; i < nodes; i += 2) { if (nodeX[i] >= IMAGE_RIGHT) { break; } if (nodeX[i + 1] > IMAGE_LEFT) { if (nodeX[i] < IMAGE_LEFT) { nodeX[i] = IMAGE_LEFT; } if (nodeX[i + 1] > IMAGE_RIGHT) { nodeX[i + 1] = IMAGE_RIGHT; } for (j = nodeX[i]; j < nodeX[i + 1]; j++) { if (geologyTerrains.GetLength(0) <= j || geologyTerrains.GetLength(1) <= pixelY) { continue; } geologyTerrains[j, pixelY].geology = geology; } } } } }