При написании программы с движением по карте высот, может потребоваться нахождение высоты точки внутри ячейки сетки ландшафта, особенно при низкой подробности карты. Это нужно для постепенного движения между высотами.
Самым простым и неточным способом будет - сложить высоты всех 4-х точек клетки и разделить на их количество. Так можно получить высоту средней точки элемента.
float square=1.0f;
float x=0.0f, z=0.0f;
float y1=1.25f, y2=0.15f, y3=0.0f, y4=0.5f;
Если развить эту формулу:
float r=sqrt (pow (square, 2)+pow (square, 2));
float r1=sqrt (pow ((-square-x), 2)+pow ((-square-z), 2)),
r2=sqrt (pow ((-square-x), 2)+pow ((square-z), 2)),
r3=sqrt (pow ((square-x), 2)+pow ((square-z), 2)),
r4=sqrt (pow ((square-x), 2)+pow ((-square-z), 2));
float h=(y1*(r*2-r1)/r/4.0f+y2*(r*2-r2)/r/4.0f+y3*(r*2-r3)/r/4.0f+y4*(r*2-r4)/r/4.0f);
- то она позволит вычислить любую точку плоскости (на самом деле, фигура из 4-х точек не всегда будет плоской и GL построит её в виде двух треугольников). Недостаток данного алгоритма в том, что наибольшая точность останется в центре ячейки.
Более подходящим станет такой подход:
float min, mx;
float z0, x0, h0, h1, h2;
if (y1>y2)
{
mx=y1;
min=y2;
z0=square-z;
}
else
{
mx=y2;
min=y1;
z0=square+z;
}
h0=mx-min;
float angle=atan (h0/(square*2));
h1=tan (angle)*z0+min;
h1=h0/(square*2)*z0+min;
if (y4>y3)
{
mx=y4;
min=y3;
z0=square-z;
}
else
{
mx=y3;
min=y4;
z0=square+z;
}
h0=mx-min;
h2=h0/(square*2)*z0+min;
if (h1>h2)
{
mx=h1;
min=h2;
x0=square-x;
}
else
{
mx=h2;
min=h1;
x0=square+x;
}
h0=mx-min;
h=h0/(square*2)*x0+min;
Его можно упростить, рассчитав высоты на отрезках по пропорциям - умножив высоты на удаление (чем ближе, тем больше коэффициент) от них точки: сначала по оси Z, затем X. Похоже на первый способ, но в данном случае он работает, давая те же значения, что и предыдущий вариант.
h1=y1*(square*2-(square+z))/(square*2.0f)+y2*(square*2-(square-z))/(square*2.0f);
h2=y4*(square*2-(square+z))/(square*2.0f)+y3*(square*2-(square-z))/(square*2.0f);
h=h1*(square*2-(square+x))/(square*2.0f)+h2*(square*2-(square-x))/(square*2.0f);
Зная высоты конечных точек прямоугольника, можно найти координаты для построения плоскости с плавным искажением поверхности. Хотя для сцены в реальном времени, это, скорее всего, лишнее - если речь не идёт о "шейдере".
Скачать полную программу.
|