Что можно улучшить в методе randomPointsInPolygon()?
Есть метод которому передаёшь float step(влияет на количество точек (1 * step / 10000), чем больше тем больше точек), List drawcord(набор точек которые определяют площадь полигона)
public static List<Vector3> randomPointsInPolygon(float step, List<Vector3> drawcord)
{
float mapoffsetx = marijnz.EditorCoroutines.PlacementObjects.mainSatting.mapoffsetx;
float mapoffsety = marijnz.EditorCoroutines.PlacementObjects.mainSatting.mapoffsetz;
if (drawcord[0].x != drawcord[drawcord.Count - 1].x && drawcord[0].z != drawcord[drawcord.Count - 1].z) //если линия, ограничивающая полигон не замкнута
drawcord.Add(drawcord[0]); //добавляем замыкающую вершину
float[] metricIn = new float[drawcord.Count * 2]; //дополнительный массив вершин, пересчитанный для проверки нахождения точки внутри полигона
drawcord[0] = new Vector3(drawcord[0].x - mapoffsetx, 0, drawcord[0].z - mapoffsety); //расчет 0-ой вершины в единицах Unity (метры)
metricIn[0] = drawcord[0].x; metricIn[1] = drawcord[0].z; //запись 0-ой вершины в дополнительный массив. x-координаты под четными индексами, Z-координаты под нечетными индексами
float minpointx = drawcord[0].x; //минимальная x-координата
float maxpointx = drawcord[0].x; //максимальная х-координата
float minpointz = drawcord[0].z; //минимальная y-координата
float maxpointz = drawcord[0].z; //максимальная у-координата
/*Цикл обработки вершин. начинается 1-ой вершины*/
for (int i = 1; i < drawcord.Count; i++)
{
drawcord[i] = new Vector3(drawcord[i].x - mapoffsetx, 0, drawcord[i].z - mapoffsety); //расчет i-ой вершины в единицах Unity (метры)
metricIn[i * 2] = drawcord[i].x; //запись i-ой вершины в дополнительный массив. x-координаты под четными индексами
metricIn[i * 2 + 1] = drawcord[i].z; //запись i-ой вершины в дополнительный массив. z-координаты под нечетными индексами
/*поиск максимальных и минимальных координат по x и максимальных и минимальных координат по z*/
if (drawcord[i].x < minpointx)
minpointx = drawcord[i].x;
if (drawcord[i].x > maxpointx)
maxpointx = drawcord[i].x;
if (drawcord[i].z < minpointz)
minpointz = drawcord[i].z;
if (drawcord[i].z > maxpointz)
maxpointz = drawcord[i].z;
}
float f = Area(drawcord); //Вызов функции для расчета площади полигона
float density = f * (1 * step / 10000); //расчет требуемого числа деревьев в зависимости от пплощади и шага
// System.Random random = new System.Random();
int breakcount = 0; //счетчик количества деревьев
List<Vector3> tempList = new List<Vector3>();
/*Цикл прекращается, когда высажено достаточное количество деревьев*/
do
{
Vector3 pos = new Vector3(UnityEngine.Random.Range(Convert.ToInt32(minpointx), Convert.ToInt32(maxpointx) + 1), 0, UnityEngine.Random.Range(Convert.ToInt32(minpointz), Convert.ToInt32(maxpointz) + 1));
if (figures_Included(pos.x, pos.z, metricIn, drawcord.Count) == true)
{
tempList.Add(pos);
breakcount++; //добавление дерева к счетчику
}
} while (breakcount <= density);
return tempList;
}
static float Area(List<Vector3> drawcord)
{
float x1, x2, x3, y1, y2, y3;
float p, a, b, c, s = 0;
x1 = drawcord[0].x;
y1 = drawcord[0].z;
for (int i = 1; i < drawcord.Count - 1; i++)
{
x2 = drawcord[i].x;
y2 = drawcord[i].z;
x3 = drawcord[i + 1].x;
y3 = drawcord[i + 1].z;
a = (float)Math.Sqrt(((x3 - x2) * (x3 - x2)) + ((y3 - y2) * (y3 - y2)));
b = (float)Math.Sqrt(((x3 - x1) * (x3 - x1)) + ((y3 - y1) * (y3 - y1)));
c = (float)Math.Sqrt(((x2 - x1) * (x2 - x1)) + ((y2 - y1) * (y2 - y1)));
p = (a + b + c) / 2;
s += (float)Math.Sqrt(p * (p - a) * (p - b) * (p - c));
}
return s;
}
static bool figures_Included(float xPoint, float yPoint, float[] metricIn, int n)
{
float X = xPoint;
float Y = yPoint;
int npol = n;
int i, j;
bool res = false;
float[] XYpol = metricIn;
for (i = 0, j = npol - 1; i < npol; j = i++)
{
if ((((XYpol[i * 2 + 1] <= Y) && (Y < XYpol[j * 2 + 1])) ||
((XYpol[j * 2 + 1] <= Y) && (Y < XYpol[i * 2 + 1]))) &&
(X < (XYpol[j * 2] - XYpol[i * 2]) * (Y - XYpol[i * 2 + 1]) /
(XYpol[j * 2 + 1] - XYpol[i * 2 + 1]) + XYpol[i * 2]))
{
res = !res;
}
}
return res;
}
Что можно улучшить в коде?
Смещение. Можно задать любое, которое будет выставлять ваши точки на terrain
float mapoffsetx = marijnz.EditorCoroutines.PlacementObjects.mainSatting.mapoffsetx;
float mapoffsety = marijnz.EditorCoroutines.PlacementObjects.mainSatting.mapoffsetz;