Программирование построения изолиний на Delphi
Интерфейс программы построения изолиний показан на рис3.33. На этом рисунке отражены результаты выполнения тестовых расчетов на построение изолиний сферической поверхности, о которой было рассказано выше. Числовой массив, получаемый по программе Polusfera, сохраняется в файле с полным именем F:\temp\Tmas.dat (путь к файлу и его имя могут быть и другими). Программа построения изолиний читает этот файл, запрашивает у пользователя число рисуемых изолиний с помощью элемента интерфейса ComboBox1. После нажатия командной кнопки Botton1 в поле элемента ListBox1 выводятся номера изолиний и соответствующие им значения функции, а в прямоугольном окне рисуются изолинии, помеченные соответствующими номерами.
Как и следовало ожидать, картина изолиний сферической поверхности представляет собой концентрические окружности. Максимальное значение находится в центре, соответствует верхней точке сферы и равно .
Рис3.33. Результат работы программы построения изолиний на тестовой задаче
Программа построения изолиний
Программа построения изолиний реализована в процедуре обработки события Button1Click.
Procedure Tform6.Button1Click(Sender: Tobject);
Const M=50; N=50;
var T: array [1..M,1..N] of real;
Tmax, Tmin, DT, Tlin: real;
Nlin,I,j: integer;
F: File of real;
Procedure IZOLIN;
var l,b:integer; // левый нижний угол области вывода графика
w,h:integer; // ширина и высота области вывода графика
I, j, lin, k, e: integer;
ri, rj: real;
flag: oolean;
Procedure Pixels_9(e,k:integer);//закрашивание квадратика 3х3
var i1,j1:integer;
Begin
for i1 := -1 to 1 do
for j1 := -1 to 1 do
Form6.Canvas.Pixels[e+i1,k+j1]:=clBlack;
end;
Begin
l:=130; //Смещение вправо окна изолиний на 130 пикселей
b:=Form6.ClientHeight-20; //Y–координата левого нижнего угла
h:=Form6.ClientHeight-40; // максимальная высота окна
w:=Form6.ClientWidth-(l+20); // максимальная ширина окна
if M>N then w:=round(w*N/M); //пропорциональное уменьшение ширины
if M<N then h:=round(h*M/N); // или высоты
With Form6.Canvas do
Begin
//Границы прямоугольной области
MoveTo (l, b-h); LineTo(l,b); LineTo(l+w,b);
LineTo(l+w,b-h); LineTo(l,b-h);
//построение изолиний
for lin:=1 to Nlin do
Begin
Tlin:=Tmin+(lin-1)*DT;
flag:=true;
//пересечение с горизонтальными линиями сетки
For i:=1 to M-1 do
Begin k:=round(h/M*(M-i)+b-h); // граф. Координата по Y
For j:=1 to N-1 do
Begin
If (Tlin>=T[I,j]) and (T[I,j+1]>=Tlin) or (Tlin<=T[I,j]) and
(Tlin >= T[i,j+1])
then Begin //х-координата точки пересечения
if abs(T[I,j+1]-T[I,j])<1E-6//исключение деления на ноль
then rj:=j+1
else rj:=j+(Tlin-T[I,j])/(T[I,j+1]-T[I,j]);
e:=round(l+w/N*rj);//граф. Координата по X
Pixels_9(e,k) //Закрашивание области точки
End
End
end;
//пересечение с вертикальными линиями сетки
For j:=1 to N-1 do
Begin e:=round(l+w/N*j); //граф. Координата по X
For i:=1 to M-1 do
Begin
If (Tlin>=T[I,j]) and (Tlin<=T[i+1,j])or(Tlin<=T[I,j]) and
(Tlin>=T[i+1,j])
then Begin //y-координата точки пересечения
if abs(T[i+1,j]-T[I,j])<1E-6 then ri:=i+1
else ri:=i+(Tlin-T[I,j])/(T[i+1,j]-T[I,j]);
k:=round(h/M*(M-ri)+b-h); //граф. Координата по Y
//Вывод номера изолинии или закрашивание точки
If flag then begin TextOut(e,k,IntToStr(lin));
flag:=false end
else Pixels_9(e,k) //Закрашивание области точки
End
End
End
end //конец цикла вывода изолиний
end // end with
end; //конец процедуры изолиний
Begin
AssignFile(F,’F:\temp\Tmas.dat’); Reset(F);
for I := 1 to M do
for j := 1 to N do Read(F,T[I,j]);//Ввод массива из файла
//Вычисление max и min массива T
Tmax:=T[1,1]; Tmin:=T[1,1];
For i:=1 to M do
For j:=1 to N do
Begin
If T[I,j]>Tmax then Tmax:=T[I,j];
If T[I,j]<Tmin then Tmin:=T[I,j]
End;
//Ввод числа изолиний из поля ComboBox1
Nlin:=StrToInt(ComboBox1.Items[ComboBox1.ItemIndex]);
DT:=(Tmax-Tmin)/(Nlin-1); //Шаг изменение значения изолинии
//Вывод списка изолинийв поле ListBox1
ListBox1.Items.Add('Значения изолиний');
forI := 1 to Nlin do
Begin
ListBox1.Items.Add(IntToStr(i)+’:T=’+FloatToStrF(Tmin+(i-1) *DT,ffGeneral,4,2))
end;
IZOLIN //Обращение к процедуре построения изолиний
end;
Основные идеи алгоритма.Приведенная программа подробно прокомментирована, поэтому в ней можно разобраться самостоятельно. Поясним лишь некоторые основные идеи, заложенные в алгоритм.
1. Изображение изолинии получается из точек пересечения этой линии с горизонтальными и вертикальными линиями расчетной сетки. Чем гуще расчетная сетка (больше M×N), тем плотнее расположатся точки (рис.3.34)
2. Число изолиний заносится в переменную Nlin. Значения, соответствующие выводимым изолиниям, изменяются от минимального значения в массиве (Tmin) до максимального значения (Tmax) с шагом DT=(Tmax-Tmin)/(Nlin-1).
3. Для очередного значения изолинии Tlin определятся все пары ближайших узлов расчетной сетки, между которыми лежит это значение. Для горизонтальных линий сетки: . Для вертикальных линий сетки . Далее, путем линейного приближения вычисляется положение точки пересечения изолинии с соответствующей линией сетки. Например, для горизонтальных линий сетки положение точки пересечения получается в переменной rj, которое вычисляется оператором: rj:=j+(Tlin-T[I,j])/(T[I,j+1]-T[I,j]). Это значение будет удовлетворять условию: j≤rj≤j+1. Для вертикальных линий сетки положение точки пересечения вычисляется оператором: ri:=i+(Tlin-T[I,j])/(T[i+1,j]-T[I,j]). Отсюда i≤ri≤i+1.
4. Координаты точек пересечения изолиний с линиями расчетной сетки (i,rj) или (ri,j) пересчитываются в координаты ближайших точек графической сетки в окне вывода изображения (Canvas - холсте). Эти координаты получаются, соответственно, в переменных e, k. Затем на холсте в этом месте закрашивается черный квадратик размером 3×3 пикселя. Точка с координатами e, k находится в центре этого квадратика. Закрашивание производится процедурой Pixels_9. Номер каждой изолинии выводится только один раз при обнаружении ее первого пересечения с вертикальной линией вычислительной сетки. Для управления эти процессом используется логическая переменная flag.
Обращаем ваше внимание на весьма важное обстоятельство: значения констант M и N, определяющих размер расчетной сетки, должны быть одинаковыми в программе получения числового массива и в программе построения изолиний по значениям этого массива. Нарушение данного правила приведет к ошибке во время чтения из файла.
Вопросы и задания
1. Что такое изолиния функции двух переменных?
2. Как выглядит картина изолиний конической поверхности?
3. Чем отличаются между собой типизированные и текстовые файлы? Почему выгоднее хранить массивы вещественных чисел в типизированных файлах? Какие преимущества имеет хранение данных в текстовых файлах?
4. Какие элементы управления Delphi использованы в программе построения изолиний?
5. Изучите процедуру построения изолиний и ответьте на вопросы:
- как определяется положение на холсте и размер области вывода изолиний?
- как вычисляется шаг изменения значений изолиний?
- каким образом вычисляются координаты точек пересечения изолинии с линиями расчетной сетки?
- как происходит пересчет координат пересечения изолиний с линиями расчетной сетки в графические координаты холста?
- как обеспечивается однократный вывод номера изолинии на рисунок?