Разделение карты высот на квадранты
Я рендеринг местности с использованием системы четырех деревьев. Мне нужно разделить карту высот на четыре секции, используя метод splitHeightmap(float[] originalMap, int quadrant)
с квадрантом, являющимся числом от 0-3. Карта должна быть разбита на четверти, поэтому, если 0 передается как квадрант, нижняя левая четверть массива возвращается как новый массив с плавающей точкой. У меня есть небольшой базовый код, но я не уверен, как на самом деле сэмплировать карту в зависимости от желаемого квадранта:
protected float[] splitHeightMap(float[] heightMap, TerrainQuadrant quadrant) {
float[] newHeightMap = new float[size >> 1];
int newSize = size >> 1;
for (int i = 0; i < newSize; i++)
for (int j = 0; j < newSize; j++)
newHeightMap[i * newSize + j] = sampleHeightAt(heightMap, i, j);
return newHeightMap;
}
protected float sampleHeightAt(float[] heightMap, int x, int z) {
return heightMap[z + x * size];
}
Редактировать: я написал то, что, по моему мнению, должно работать, но получаю ArrayIndexOutOfBoundsException для индекса 65792 (с исходной картой высот 512x512):
protected float[] splitHeightMap(float[] heightMap, TerrainQuadrant quadrant) {
float[] newHeightMap = new float[(size >> 1) * (size >> 1)];
int newSize = size >> 1;
int xOffset = 0, zOffset = 0;
int xCount = 0, yCount = 0;
switch (quadrant) {
case BottomRight:
xOffset = newSize;
break;
case TopLeft:
zOffset = newSize;
break;
case TopRight:
xOffset = newSize;
zOffset = newSize;
break;
default:
break;
}
for (int x = xOffset; x < xOffset + newSize; x++)
for (int z = zOffset; z < zOffset + newSize; z++) {
newHeightMap[xCount + yCount * newSize] = heightMap[z + x * size]; // should this be 'z + x * size' or 'x + z * size'?
xCount++;
yCount++;
}
return newHeightMap;
}
1 ответ
Если я вас правильно понимаю, то вам придется использовать двумерный массив. С таким типом массива легко получить любую область массива.
Ваш heightMap
теперь буду float[][]
введите, поэтому вы должны исправить свой код, где вы заполните этот массив.
Я реализовал один экзамен для вас и использовал массив 4х4:
| 2 2 3 3 |
| 2 2 3 3 |
| 0 0 1 1 |
| 0 0 1 1 |
Как я понимаю, вы хотите выбрать такие области, как все "0", все "1", все "2" и все "3".
public static void main ( String[] args )
{
//setting up initial array 'heightMap' (you can name it like you want)
float[][] f = { { 2, 2, 3, 3 }, { 2, 2, 3, 3 }, { 0, 0, 1, 1 }, { 0, 0, 1, 1 } };
float[][] f2 = splitHeightMap ( f, TerrainQuadrant.BotttomRight );
for ( float[] floats : f2 )
{
System.out.println ( Arrays.toString ( floats ) );
}
}
protected static float[][] splitHeightMap ( float[][] heightMap, TerrainQuadrant quadrant )
{
//this gives you half of the 'heightMap' length
int newSize = heightMap.length >> 1;
float[][] newHeightMap = new float[ newSize ][ newSize ];
//its your offsets, indicating from what place to start iteration
int xOffset = 0;
int yOffset = newSize;
//its max values to reach while iterating
int xRestriction = newSize;
int yRestriction = heightMap.length;
//setting up params according to 'quadrant'
switch ( quadrant )
{
case BottomRight:
xOffset = newSize;
yOffset = newSize;
xRestriction = heightMap.length;
break;
case TopLeft:
yOffset = 0;
yRestriction = newSize;
break;
case TopRight:
yOffset = 0;
xOffset = newSize;
xRestriction = heightMap.length;
yRestriction = newSize;
break;
default:
break;
}
//counters not to reach new array bounds
int xCount = 0, yCount = 0;
for ( int y = yOffset; y < yRestriction; y++ )
{
//taking row at 'y' position
float[] row = heightMap[ y ];
for ( int x = xOffset; x < xRestriction; x++ )
{
//taking value from 'y' row at 'x' position.
float value = row[ x ];
//set fetched value to new map.
newHeightMap[ yCount ][ xCount ] = value;
//increase x position, but do not touch row
xCount++;
}
//new row - new 'x' position
xCount = 0;
yCount++;
}
return newHeightMap;
}
Эта реализация показывает вам:
| 1 1 |
| 1 1 |
Чтобы изменить его - измените основной метод.