Методичка. Полный обучающий курс по Turbo Pascal. Полный обучающий курс Turbo Pascal
Скачать 0.56 Mb.
|
Глава 6. Графика в системе Турбо ПаскальПостроение графиков функцийДля построения графиков функций при помощи графического режима предполагается свободное владение учениками понятием функции, ее графическим и аналитическим представлением. Необходимо также использовать операторы цикла, которые помогут избежать однообразного труда по вычислению ординаты каждой точки. До сих пор при создании рисунков использовали только первый квадрант системы координат. Для построения большинства функций в требуемом интервале изменения необходимо работать хотя бы в двух квадрантах. В общем случае полезно изображать систему координат в любой части плоскости, но наиболее наглядно располагать ее в центре экрана. В таких случаях, установив начало координат в точке (x0, y0) на экране, можно координаты (x, y) произвольной точки кривой определять разностью (x-x0, y-y0). После этого в программе можно употреблять не только положительные, но и отрицательные значения. Рисунок получается маленьким, поэтому требуется увеличить масштаб изображения. Если для функции будет использован весь экран, надо увеличить рисунок по x и по y в зависимости от выбранного экрана. Выбрать масштаб увеличения можно следующим образом: -определить горизонтальный и вертикальный размеры графика (для этого вводятся границы области значений и определяются максимальное и минимальное значение функции на заданной области определения, затем вычисляются разности максимального и минимального значений аргументов и функции, которые и являются горизонтальным и вертикальным размерами графика соответственно); -определить масштаб (сначала определяются масштабы изображения по горизонтали и вертикали с учетом размеров выбранного экрана по формуле: масштаб(г/в) = размер экрана (по г/в) / размер графика (по г/в), затем из них выбирается меньший, который и принимается за необходимый масштаб. В нашем случае графический экран имеет размеры 640 на 480. В любом случае, чтобы высветить на экране точку, надо взять x, вычислить по данной абсциссе y и выполнить рисование точки. Так как на экране можно получить лишь ограниченное количество значений х, то их перебираем с помощью цикла. Пример. Построить график функции y=x2 Вариант 1program f; uses graph; var gd, gm: integer; x, y: real; begin gd:= detect; initgraph( gd, gm, ‘c/ bp’); SetColor(5); Line(0, 240, 640, 240); Line(320, 0, 320, 480); x:= -20; While x<=20 do begin y:= -Sqr(x); PutPixel( x *5 + 320, y*5 +240, 15); x:=x + 0.01; end; end. Вариант 2program f; uses graph, crt; var gd, gm: integer; x, y, mx, my, m,x1, x2, y1, y2,h: real; function f(x:real): real; begin f:= Sqr(x); end; clrscr; Write(‘Введите границы отрезка’); Read(x1, x2); y1:=f(x1); y2:=f(x2); mx:=640 /(x2 –x1); my:=480 / (y2 – y1); If mx< my Then m:=mx else m:= my; h:= 1/m; x:=x1; gd:= detect; initgraph(gd, gm, ‘c/ bp’); SetColor (5); Line(0, 240, 640, 240); Line(320, 0, 320, 480); While x<= x2 do begin y:= -f(x); PutPixel(x *m +320, y*m +240, 15); x:= x+ h; end; end. Рассмотрим построение графика функции, заданной параметрически. В отличие от функции, заданной в явном виде y=f(x), параметр х в этом случае также является функцией, зависящей от некоторого значения. Пример. Построить график функции (кардиоида) x = a cos t ( 1+ cost), y = a sin t( 1+cost), a > 0, t Î [0, 2p ) Приведем фрагмент программы: SetColor (5); Line(0, 240, 640, 240); Line(320, 0, 320, 480); t:=0; a:=3; While t<= 3.1415 do begin x:=a*cos(t)*(1+cos(t)); y:= - a sin(t)*(1+cos(t)); PutPixel(x*5 +320, y*5 +240, 15); x:= x+ 0.01; end; Глава 6. Графика в системе Турбо ПаскальЦиклы в графике. Построение случайных процессовДля того, чтобы картинки не были монотонными и регулярными, можно задавать фигурам случайные размеры, цвет, координаты. Для этого имеется специальная функция Random. Она генерирует случайные числа из [0, 1). Для расширения первоначального промежутка используется функция Random(I: word), которая выдает число из диапазона 0… I. На самом деле эти функции генерируют некоторую последовательность псевдослучайных чисел, и чтобы добиться иллюзии полной «случайности» используют команду Randomize, которая изменяет базу датчика случайных чисел. Пример. Нарисовать в случайном месте экрана точку случайного цвета Фрагмент программы: Randomize x:=random(640); y:=Random(480); c:=Random(15); PutPixel(x, y, c); Пример. Нарисовать 5000 точек случайного цвета в случайном месте. Фрагмент программы: For i:=1 to 5000 do begin x:=Random(640); y:=Random(480); c:=Random(15); PutPixel(x, y, c); end; Глава 6. Графика в системе Турбо ПаскальСоздание иллюзии движенияСоздать видимость движения изображения на экране можно несколькими способами. Рассмотрим два из них. I способ. Имитация движения объекта на экране за счет многократного выполнения программой набора действий: нарисовать – пауза – стереть (нарисовать в том же месте цветом фона) – изменить координаты положения рисунка. Перед началом составления программы надо продумать описание «двигающегося» объекта, характер изменения координат, определяющих текущее положение объекта, диапазон изменения и шаг. Упражнение 1. Изучить текст программы, которая рисует модель атома. Проверить ее действие. program Model_At; uses Crt, Graph; const Ra=100;{радиус атома} Rc=10; {радиус ядра} Re=4; {радиус электрона} k=0.5; {коэффициент сжатия орбит электронов} Dr=30; {параметр изменения координат электрона} Step1=0.2; {шаг изменения положения электрона} Step=100; {время задержки – скорость движения электронов} var cx, cy, y, y1, y2, x, x1, x2, x3, y3:integer; I, I1, I2, I3: real; gd, gm: integer; begin clrscr; gd:=detect; initgraph(gd, gm, ‘путь к драйверу’); SetTextStyle(0, 0, 2); OutTextXY(200, 30, ‘Модель атома’); cx:= GetMaxX div 2; {определить центр экрана- положение ядра} cy:= GetMaxY div 2; PieSlice(cx, cy, 0, 360, Rc);{нарисовать ядро атома} SetColor(Red); SetLineStyle(0, 0, 3); Line(cx-7, cy, cx+7, cy); Line(cx, cy-5, cx, cy+5); SetLineStyle(0,0,1); SetFillStyle(1, 1); I:=Pi/4; {задать начальное положение 4 электронов} I1:= - Pi/4; I2:= - Pi/2; I3:= Pi/2; SetTextStyle(0, 0, 1);SetColor(jellow); OutTextXY(180, 420,’Для отмены нажмите любую клавишу’); While not KeyPressed do {повторять, пока не нажата любая клавиша } begin { определить координаты электронов} x:=Round (Ra*cos(I)) +cx; Y:= Round (k+Ra*sin(I)) +cy; x1:= Round((Ra+Dr)*cos(I1)) +cx; y1:= Round (k*(Ra+Dr)*sin(I1)) +cy; x2:= Round((Ra-Dr)*cos(I2)) +cx; y2:= Round (k*(Ra-Dr)*sin(I2)) +cy; x3:= Round((Ra-Dr)*cos(I3)*2.3) +cx; y3:= Round (k*(Ra-Dr)*sin(I3)*2.3) +cy; {установить синий цвет и нарисовать электроны} SetColor(1); Circle (x, y, Re); PutPixel(x, y, 2); Circle (x1, y1, Re); PutPixel(x1, y1, 2); Circle (x2, y2, Re); PutPixel(x2, y2, 2); Circle (x3, y3, Re); PutPixel(x3, y3, 2); Delay(Step); {нарисовать электроны цветом фона} SetColor(0); Circle (x, y, Re); PutPixel(x, y, 2); Circle (x1, y1, Re); PutPixel(x1, y1, 2); Circle (x2, y2, Re); PutPixel(x2, y2, 2); Circle (x3, y3, Re); PutPixel(x3, y3, 2); {задать изменение положения электронов} I:=I + Step1; I1:=I1 – Step1; I2:=I2 + Step1; I3:=I3 + Step1; end; {конец цикла} CloseGraph; end. II способ. Иллюзия движения создается при помощи специальных процедур и функций. Функция ImageSize(x1, y1, x2, y2: integer):word возвращает размер памяти в байтах, необходимый для размещения прямоугольного фрагмента изображения, где x1,y1 – координаты левого верхнего и x2, y2 – правого нижнего углов фрагмента изображения. Процедура GetImage(x1, y1, x2, y2:integer, var Buf) помещает в память копию прямоугольного фрагмента изображения, где x1, ..,y2 – координаты углов фрагмента изображения, Buf – специальная переменная, куда будет помещена копия видеопамяти с фрагментом изображения. Buf должна быть не меньше значения, возвращаемого функцией ImageSize с теми же координатами. Процедура PutImage(x1, y1, x2, y2:integer, var Buf, Mode:word) выводит в заданное место экрана копию фрагмента изображения, ранее помещенную в память процедурой GetImage. X, Y – координаты левого верхнего угла того места на экране, куда будет скопирован фрагмент изображения; Buf –специальная переменная, откуда берется изображение, Mode – способ копирования. Координаты правого нижнего угла не указываются, так как они полностью определяются размерами выводимой на экран копии изображения. Координаты левого верхнего угла могут быть любыми, лишь бы только копия уместилась в пределах экрана (если копия не размещается на экране, то она не выводится , и экран остается без изменений). Параметр Mode определяет способ взаимодействия размещаемой с уже имеющимся на экране изображением ( табл. 7)
Упражнение 2. Изучить программу, которая рисует звездное небо и перемещает на его фоне рисунок НЛО. Проверить действие программы. program NLO; uses crt, graph;const k=20; Pause=50; var gd, gm, xmin, xm, ymin, ym, x, y, tx, ty, rx, ry, size, i, dx, dy, width, height: integer; sauser:Pointer; begin Randomize; gd:= detect; initgraph(gd, gm, ‘путь к драйверу’); SetTextStyle(0, 0, 2); OutTextXY(50, 10, ‘Демонстрация движения НЛО’); {Рисуем НЛО} x:=R*5; y:=R*2; xm:=GetmaxX- 5; ym:=GetmaxY-25; Ellipse(x, y, 0, 360, R, R div 3+2); Ellipse(x, y-4, 190, 357, R, R div 3); Line(x + 7, y - 6, x + 10, y - 12); Line(x -7, y - 6, x + 10, y - 12); Circle(x + 10, y - 10, 2); Circle(x -10, y - 10, 2); FloodFill(x+1, y+4, White); {определяем габариты НЛО и помещаем в специальную динамическую переменную} Tx:= x-R; Ty:=y-14; Rx:;=x+R; Ry:=y+R div3 +3; Width:=Rx-Tx+1; Size:=ImageSize(Tx, Ty, Rx, Ry); GetMem(sauser, Size); GetImage(Tx, Ty, Rx, Ry, sauser^); {стираем построенное изображение} PutImage(Tx, Ty, sauser^, XorPut); {рисуем звездное небо} SetStyle(1, blue); {установить стиль и цвет закраски голубое небо} SetColor(White); {начертить прямоугольник и открыть окно} Rectangle(xmin, ymin, GetmaxX, GetmaxY); SetViewPort(xmin, ymin, GetmaxX, GetmaxY, ClipOn); FloodFill(xmin+1, ymin+1, White); For i:=1 to 500 do {нарисовать 500 звезд белого цвета} PutPixel(Random(GetmaxX), Random(GetmaxY- ymin), 15); {задаем начальное положение НЛО} x:=xm div 3 – xmin; y:=ym div 3 – ymin; dx:=6; dy:=6; Repeat {цикл: повторять, пока не нажата любая клавиша} PutImage(x, y, sauser^, XorPut); {изображаем объект} Delay (Pause);{ задержка} PutImage(x, y, sauser^, XorPut); {после паузы стираем объект} {перемещаем объект} If (x begin {если объект смещается влево-вверх за границы окна, изменить координаты так, чтобы он оставался в окне} If (x- Dx< xmin) then x:= xmin else x := x- Dx; If (y- Dy< ymin) then y:= ymin else y := y- Dy; Dx:= GetmaxX div 10 - Random(GetmaxX div 4); Dy:= GetmaxY div 10 - Random(GetmaxY div 4); end else begin { если объект смещается вправо-вниз за границы окна, изменить координаты так, чтобы он оставался в окне} If (x + Dx< xm) then x:= x + Dx else x:= Random(GetmaxX) - Random(GetmaxX div 4); If (y + Dy< ym) then y:= y + Dy else y:= Random(GetmaxY) - Random(GetmaxY div 3); end; until KeyPressed; {завершить, как только будет нажата клавиша } FreeMem (sauser, Size); Closegraph; end; end. Задание: В любую из этих программ добавить свой «движущийся» объект. |