Чтобы разрешить неопределенность, придется выполнить дополнительные расчеты. Разделим "подозрительную" ячейку на четыре части (рис. 12.12) и рассчитаем значение функции в центральной точке. Если функция задана аналитически, это делается очень просто, а если в

12.2. Поля превышений и линии уровня нашем распоряжении только экспериментальные данные, то можно получить "воображаемое" значение, интерполируя по какому-либо закону уже имеющиеся данные в вершинах исходной ячейки. Скорее всего, что ситуация в новых ячейках будет однозначной. Если это не так, то "подозрительную" четвертушку придется опять разделить.

Рис. 12.10. Неоднозначная интерпретация маркировки вершин ячейки

Рис. 12.11. Пример разной интерпретации одного и того же варианта маркировки вершин ячейки

Рис. 12.12. Разбиение ячейки Программный код, реализующий этот метод, весьма незамысловат. В программе организуется цикл по всем ячейкам. Функция cell(), текст которой приведен ниже, определяет тип ячейки - один из шестнадцати. Аргументы функции - а, Ь, с и d - значения выборок, соответствующих вершинам ячейки.

int cell(double a, double b, double с , double d) {

/* THRESHOLD = значение уровня для формируемой линии */ int n=0;

if(a>THRESH0LD) n+=l; if(b>THRESH0LD) n+=8; if (OTHRESHOLD) n+=4;

Глава 12. Визуализация данных научных исследований

if(d>THRESHOLD) n+=2; return n;
}

Теперь нужно отнести ячейку к одному из четырех уникальных типов. Это выполняется оператором логического анализа switch ():

switch(n) {
case 1: case 2: case 4: case 7: case 8: case 11: case 13: case 14:

/* Линия уровня отсекает один угол */

draw_one(num, i,j,a,b,c,d);
break;
case 3: case 6: case 9: case 12:

/* Линия уровня пересекает ячейку от одного ребра до противоположного */ draw_adjacent(num,i,j,a,b,c,d); break; case 5: case 10: /* Неоднозначный вариант */ draw_opposite(num, i,j,a,b,c,d); break; case 0: case 15: /* Линия не пересекает ячейку */ break;

}

Теперь разработаем три функции, которые будут вычерчивать сегмент, - каждая в своем варианте. Например, функция draw_one() будет вычерчивать сегмент, проходящий между двумя соседними ребрами ячейки. Переменные s_x и s_y - размеры ячейки в направлении осей хну соответственно, а переменные ох и оу - координаты левого нижнего угла ячейки (рис. 12.13). Программный код этой функции представлен ниже.


⇐ Предыдущая| |Следующая ⇒