Прежде, чем приступить к созданию графических программ на Turbo Pascal, необходимо ознакомиться с богатейшими графическими возможностями этого языка, сосредоточенными в стандартных модулях (библиотеках) GRAPH и CRT (название CRT происходит от Cathode-Ray Tube электронно-лучевая трубка). Эти модули содержат описания стандартных констант, процедур и функций, используемых при работе с монитором в текстовом и графическом режимах.
В системе программирования Turbo Pascal имеется хорошо развитая встроенная служба помощи, позволяющая получать подробное описание стандартных подпрограмм с примерами их применения. Поэтому ниже приведены только названия, описание параметров и назначение наиболее употребительных процедур и функций.
|
|
Black = 0; {Черный}
Blue = 1; {Синий} Green = 2; {Зеленый} Cyan = 3; {Голубой} Red = 4; {Красный} Magenta = 5; {Фиолетовый} Brown = 6; {Коричневый} LightGray = 7; {Светлосерый} |
DarkGray = 8; {Темносерый}
LightBlue = 9; {Яркосиний} LightGreen = 10; {Яркозеленый} LightCyan = 11; {Яркоголубой} LightRed = 12; {Розовый} LightMagenta = 13; {Малиновый} Yellow = 14; {Желтый} White = 15; {Белый} |
SolidLn = 0; {Сплошная}
DottedLn = 1; {Точечная} CenterLn = 2; {Штрихпунктирная} |
DashedLn = 3; {Пунктирная}
NormWidth=1; {Нормальная толщина} ThickWidth = 3; {Тройная толщина} |
EmptyFill = 0;
SolidFill = 1; LineFill = 2; LtSlashFill = 3; SlashFill = 4; BkSlashFill = 5; LtBkSlashFill = 6; HatchFill = 7; XHatchFill = 8; InterleaveFill = 9; WideDotFill = 10; CloseDotFill = 11; UserFill = 12. |
{Заполнение цветом фона}
{Сплошная штриховка} {Горизонтальная штриховка} {/// штриховка} {/// штриховка толстыми линиями} {\\\ штриховка толстыми линиями} {\\\ штриховка} {Заполнение прямой клеткой} {Заполнение косой клеткой} {Заполнение частой сеткой} {Заполнение редкими точками} {Заполнение частыми точками} {Тип задается пользователем} |
Program ColorTable; Uses Crt; {подключение к программе библиотеки Crt} Const P = ' '; Var i, j : Integer; BEGIN ClrScr; {очистка экрана} Window(1, 1, 80, 7); {определение окна для заголовочной части таблицы} TextColor(Yellow); {установка желтого цвета символов} GoToXY(24, 1); WriteLn('ТЕКСТОВЫЙ ВЫВОД НА ЭКРАН ДИСПЛЕЯ'); GoToXY(30, 2); WriteLn('ТАБЛИЦА ЦВЕТНОСТИ'); TextColor(LightCyan); {установка яркоголубого цвета символов} WriteLn('0-Черный ',P,'4-Красный ',P,'8-Темносерый ',P,'12-Розовый '); WriteLn('1-Синий ',P,'5-Фиолетовый ',P,'9-Яркосиний ',P,'13-Малиновый '); WriteLn('2-Зеленый ',P,'6-Коричневый ',P,'10-Яркозеленый ',P,'14-Желтый '); Write ('3-Голубой ',P,'7-Светлосерый',P,'11-Яркоголубой',P,'15-Белый '); TextColor(3+128); WriteLn(' i+128-Мерцание'); TextColor(White); For i := 0 to 9 do {цикл по цветам фона таблицы цветности} begin Window(i*8+1, 7, i*8+8, 25); {oпределение окна для столбца таблицы} GoToXY(1, 1); {курсор в верхнем левом углу окна} TextBackGround(Black); {установка черного цвета фона} WriteLn(' Фон', i:2); WriteLn('----------'); TextBackGround(i); {установка текущего цвета фона окна } For j := 0 to 15 do begin TextColor(j); {установка текущего цвета надписей в окне } WriteLn('цвет', j:2); end; end; NormVideo; ReadLn END.
Program Lines; Uses Graph, Crt; {подключение к программе библиотек Crt и Graph} Var Key : Char; LineStyle : Word; {номер стиля рисования линии} Style : String; {название стиля } GrDriver, GrMode : Integer; {тип и режим работы графического драйвера} GrError : Integer; {код ошибки графики} BEGIN GrDriver := Detect; {автоопределение типа графического драйвера} InitGraph(GrDriver, GrMode, 'C:\TP\BGI'); {установка графического режима} GrError := GraphResult; If GrError<>GrOk then begin Writeln('Обнаружена ошибка!'); Halt end; SetBkColor(LightGray); SetColor(Red); {цвет фона и цвет рисования } {------------------------------------------------------------} OutTextXY(120, 100, 'Рисуем линию от точки (200,200) к точке (400,280)'); Line(200, 200, 400, 280); Key:=ReadKey; {приостановление исполнения программы} ClearViewPort; {очистка окна} {-----------------------------------------------------------} OutTextXY(240, 80, 'Рисуем ломанную'); Rectangle(110, 120, 520, 400); {рисование рамки } MoveTo(Round(GetMaxX/2), Round(GetMaxY/2)); {указатель в центре окна} Repeat {цикл прерывается нажатием любой клавиши} LineTo(Random(GetMaxX-250)+120, Random(GetMaxY-210)+120); Delay(100); until KeyPressed; Key := ReadKey; ClearViewPort; {-----------------------------------------------------------} OutTextXY(190, 80, 'Mеняем стили рисования линий'); For LineStyle := 0 to 3 do begin SetLineStyle(LineStyle, 0, 1); Case LineStyle of 0: Style:='Сплошная'; 1: Style:='Точечная'; 2: Style:='Штрихпунктирная'; 3: Style:='Пунктирная' end; Line(120, 150+LineStyle*50, 430, 150+LineStyle*50); OutTextXY(450, 145+LineStyle*50, Style); end; Key:=ReadKey; ClearViewPort; {очистка окна} {-----------------------------------------------------------} OutTextXY(180, 80, 'Меняем толщину рисования линий'); SetLineStyle(0, 0, 1); {толщина 1 пиксел } Line(140, 200, 430, 200); OutTextXY(450, 195, 'Нормальная'); SetLineStyle(0, 0, 3); {толщина 3 пиксела} Line(140, 250, 430, 250); OutTextXY(450, 245, 'Тройная'); ReadLn; CloseGraph; {закрытие графического режима} END.
Program Symbols; Uses Graph, Crt; {подключение к программе библиотек Crt и Graph} Var Key : Char; Font : String; {названия шрифтов } Size, MyFont : Word; GrDriver, GrMode : Integer; {тип и режим работы графического драйвера} BEGIN GrDriver := Detect; {автоопределение типа графического драйвера} InitGraph(GrDriver, GrMode, 'C:\TP\BGI'); {установка графического режима } If GraphResult <> GrOk then Halt; {-----------------------------------------------------------} SetTextStyle(DefaultFont, HorizDir, 2); OutTextXY(140, 80, 'Меняем размер символов'); OutTextXY(220, 100, 'и цвет фона'); For Size := 0 to 13 do {Size - цвет фона и размер символов} begin SetBkColor(Size); {изменение цвета фона } Rectangle(135, 425, 470, 450); {рисование рамки } SetTextStyle(DefaultFont, HorizDir, 1); OutTextXY(150, 435, 'Для продолжения нажмите любую клавишу !'); SetTextStyle(DefaultFont, HorizDir, Size); OutTextXY(250-Size*15, 200, 'HELLO'); Key := ReadKey; ClearViewPort; end; ReadLn; {-----------------------------------------------------------} SetBkColor(LightGray); SetColor(Red);{цвет фона и цвет рисования } SetTextStyle(DefaultFont, HorizDir, 2); {установка шрифта, направления и размера символов} OutTextXY(70, 100, 'Располагаем строку горизонтально'); SetTextStyle(DefaultFont, VertDir, 2); OutTextXY(310, 150, 'и вертикально'); Key:=ReadKey; ClearViewPort; {-----------------------------------------------------------} SetTextStyle(DefaultFont, HorizDir, 2); {установка шрифта, направления и размера символов} OutTextXY(220, 30, 'Меняем шрифты'); For MyFont := 0 to 9 do {цикл по номерам шрифтов} begin Case MyFont of 0: Font:='0 - Точечный (Default)'; 1: Font:='1 - Утроенный (Triplex)'; 2: Font:='2 - Уменьшенный (Small)'; 3: Font:='3 - Прямой (SansSerif)'; 4: Font:='4 - Готический (Gothic)'; 5: Font:='5 - Рукописный'; 6: Font:='6 - Курьер'; 7: Font:='7 - Красивый (Tаймс Italic)'; 8: Font:='8 - Таймс Roman'; 9: Font:='9 - Курьер увеличенный'; end; SetTextStyle(MyFont, HorizDir, 2); OutTextXY(40, 70+MyFont*35, 'abcdfxyz 0123456789');{вывод текста} SetTextStyle(DefaultFont, HorizDir, 1); OutTextXY(410, 80+MyFont*35, Font) {вывод названия шрифта} end; OutTextXY(380, 60, 'N шрифта Описание'); ReadLn; CloseGraph; {закрытие графического режима} END.
Program MusicColor; Uses Crt, Graph; {подключение к программе библиотек Crt и Graph} Var GrDriver, GrMode: Integer; {тип и режим работы графического драйвера} BEGIN GrDriver := Detect; {автоопределение типа графического драйвера} InitGraph(GrDriver, GrMode, 'C:\TP\BGI'); {установка графического режима} SetColor(White); {установка белого цвета рамки } Rectangle(130, 130, 460, 370); {рисование рамки } Randomize; {инициализация датчика случайных чисел} Repeat {цикл прерывается нажатием любой клавиши} Sound(Random(2000)); {изменение высоты звука } Delay(Random(1000)); {задержка } SetFillStyle(Random(4), Random(16)); {смена типа штриховки и цвета} Bar(140, 140, 450, 360); {рисование закрашенного прямоугольника} until KeyPressed; NoSound; {отмена звука } CloseGraph; ReadLn; {закрытие графического режима} END.
Program Star; Uses Crt, Graph; {подключение к программе библиотек Crt и Graph} Const { массив координат вершин многоугольника (звезды) } TopsStar: Array[1..18] of Integer = (300, 125, 325, 225, 425, 250, 325, 275, 300, 375, 275, 275, 180, 250, 275, 225, 300, 125); Var i, j, GrDriver, GrMode : Integer; BEGIN GrDriver := Detect; InitGraph(GrDriver, GrMode, 'C:\TP\BGI'); {установка графического режима} SetTextStyle(DefaultFont, HorizDir, 2); {установка шрифта, направления и размера символов} OutTextXY(220, 60, 'S T A R '); SetTextStyle(DefaultFont, VertDir, 2); OutTextXY(140, 150, 'S T A R '); SetTextStyle(DefaultFont, VertDir, 2); OutTextXY(500, 150, 'S T A R '); i:=0; Repeat j:=i mod 12; { j - остаток от деления i на 12 } SetFillStyle(j, Random(13)); { штриховка и фон } FillPoly(9, TopsStar); {рисование и штриховка звезды} Inc(i); {увеличение i на 1} Delay(500) until KeyPressed; {завершение цикла нажатием любой клавиши} CloseGraph END.
Program Sight; Uses Crt, Graph; {подключение к программе
библиотек Crt и Graph} Const Step = 5; {шаг изменения координат центра прицела } Instr = 'УПРАВЛЕНИЕ ДВИЖЕНИЕМ ПРИЦЕЛА - СТРЕЛКИ, ВЫХОД - ESC'; Var GrDriver, GrMode : Integer; {тип и режим работы графического драйвера} X, Y : Integer; {координаты центра прицела} XStr, YStr : String; Ch : Char; {-----------------------------------------------------------} Procedure MakeSight(X, Y : Integer); {процедура рисования прицела} Begin SetColor(White); Circle(X, Y, 80); SetColor(LightGreen); Line(X-80, Y, X+80, Y); Line(X, Y-63, X, Y+63); {вывод осей прицела} SetColor(LightRed); Circle(X, Y, 2); {окружность в центре прицела} Str(X, XStr); Str(Y, YStr); {перевод координат в строковый тип} SetColor(Yellow); OutTextXY(X+5, Y-35, 'x=' + XStr); {вывод координат центра прицела } OutTextXY(X+5, Y-20, 'y=' + YStr) End; {-----------------------------------------------------------} BEGIN GrDriver := Detect; InitGraph(GrDriver, GrMode, 'C:\TP\BGI'); SetColor(LightGray); X := GetMaxX div 2; Y := GetMaxY div 2; {координаты центра экрана} Rectangle(50, 425, 600, 460); {рисование рамки } OutTextXY(120, 440, Instr); MakeSight(X, Y); {рисование прицела в центре экрана} While TRUE do {цикл работы программы до прерывания по клавише ESC} begin Ch := ReadKey; Case Ch of #27: begin CloseGraph; Halt(1) end; {выход по клавише ESC} #75: X: = X-Step; {изменение координат x, y нажатием стрелок} #77: X: = X+Step; {"влево", "вправо", "вверх", "вниз" } #72: Y: = Y-Step; #80: Y: = Y+Step end; ClearViewPort; { очистка графического экрана } SetColor(LightGray); {восстановление рамки с надписью} Rectangle(50, 425, 600, 460); OutTextXY(120, 440, Instr); MakeSight(X, Y) {рисование прицела в текущих координатах} end; CloseGraph; END.
Program Animation; Uses Crt, Graph; {подключение к программе библиотек Crt и Graph} Const {вертикальные и горизонтальные координаты положения рук} Vert : Array[1..3] of Integer = (190, 157, 120); Horizont : Array[1..3] of Integer = (200, 190, 200); Var GrDriver, GrMode, GrError, i, j : Integer; BEGIN GrDriver := Detect; InitGraph(GrDriver, GrMode, 'C:\TP\BGI'); GrError := GraphResult; If GrError <> GrOk then Halt; SetColor(LightGray); { установка светлосерого цвета для рамки} Rectangle(20, 20, 480, 400); {рисование рамки} SetColor(LightCyan); {установка яркоголубого цвета для текста} OutTextXY(200, 40, 'П Р И В Е Т !'); SetColor(LightGray); Circle (250, 130, 20); {голова} SetColor(Yellow); Arc(250, 130, 0, 180, 26); {волосы} Arc(250, 130, 0, 180, 24); Arc(250, 130, 0, 180, 22); Line(250, 105, 244, 115); Line(250, 105, 250, 116); {чубчик} Line(250, 105, 256, 115); SetColor(LightCyan); Circle(241, 125, 4); {левый глаз } Circle(259, 125, 4); {правый глаз} SetColor(LightRed); SetFillStyle(SolidFill, LightRed); FillEllipse(250, 140, 6, 3); {рот } Setcolor(Green); Line(250, 152, 250, 220); {туловище } Line(250, 220, 210, 290); {левая нога } Line(250, 220, 290, 290); {правая нога} Repeat {цикл прерывается нажатием любой клавиши} For i := 1 to 3 do {Последовательный вывод трех положений рук:} begin { вниз, на уровне плеч, вверх } SetColor(LightCyan); Sound(200*i); Line(250, 157, Horizont[i], Vert[i]); {левая рука} Line(250, 157, 500-Horizont[i], Vert[i]); {правая рука} Delay(300); {задержка} SetColor(Black); {смена цвета на черный для повторного pисования рук в том же положении ("стирания" их с экрана) } Line(250, 157, Horizont[i], Vert[i]); {левая рука } Line(250, 157, 500-Horizont[i], Vert[i]); {правая рука} end until Keypressed; SetColor(LightCyan); Line(250, 157, Horizont[3], Vert[3]); {левая рука поднята } Line(250, 157, 500-Horizont[3], Vert[3]); {правая рука поднята} For i := 1 to 10 do { звуковая трель } begin Sound(1000); Delay(50); Sound(1500); Delay(50) end; NoSound; { выключение звука } CloseGraph; END.
Program Design; Uses Graph, Crt; {подключение к программе библиотек Crt и Graph} Const Height : Array[1..8] of Integer=(40,150,90,240,190,120,50,90); {массив высот столбиков диаграммы} Var Color : Word; {код цвета} Key : Char; i, x, y, y1, h : Integer; GrDriver, GrMode : Integer; {тип и режим работы графического драйвера} GrError : Integer; {код ошибки графики} BEGIN GrDriver := Detect; InitGraph(GrDriver, GrMode, 'C:\TP\BGI'); GrError := GraphResult; If GrError <> GrOk then Halt; y := 120; h := 50; y1 := 140; SetTextStyle(DefaultFont, HorizDir, 2); {шрифт, направление, размер} OutTextXY(160, 20, 'Конструируем интерьер'); SetFillStyle(5, LightRed); {тип штриховки и цвет (ярко красный)} For i := 4 downto 1 do begin {рисование параллелепипедов заданного размера} Bar3D(75, y1+i*h, 145, y1+(i+1)*h, 60, TopOff); Delay(200); end; Bar3D(75 , y1 , 145, y1+h , 60, TopOn); Delay(200); Bar3D(180, y , 290, y+h , 30, TopOn); Delay(200); Bar3D(330, 225 , 400, y+4*h , 30, TopOn); Delay(200); Bar3D(300, y+3*h, 370, y+5*h , 30, TopOn); Delay(200); Bar3D(370, y+3*h, 440, y+5*h , 30, TopOn); Delay(200); Bar3D(300, y , 370, y+h , 30, TopOn); Delay(200); Bar3D(370, y , 440, y+h , 30, TopOn); Delay(200); Bar3D(442, y , 500, y+5*h , 30, TopOn); Delay(200); Rectangle(135, 425, 470, 450); {рисование pамки для сообщения} SetTextStyle(DefaultFont, HorizDir, 1); OutTextXY(150, 435, 'Для продолжения нажмите любую клавишу !'); Key := ReadKey; ClearViewPort; {очистка окна} {-----------------------------------------------------------------} SetTextStyle(DefaultFont, HorizDir, 2); OutTextXY(100, 20, 'Рисуем столбиковую диаграмму'); x := 50; Randomize; {инициализация датчика случайных чисел} For i := 1 to 8 do {цикл по столбикам диаграммы} begin Color := Random(12)+1; {задание кода цвета (кроме черного)} SetFillStyle(i, Color); {задание типа штриховки и цвета} SetColor(Color); Bar3D(x, 350-Height[i], x+50, 380, 20, TopOn); {рисование столбика} x := x+70; {изменение координаты x }; Delay(200) {задержка} end; Key := ReadKey; CloseGraph; {Закрытие графического режима} END.
Program RandomFigures; Uses Graph, Crt; Var Key : Char; GrDriver, GrMode : Integer; Radius, MaxX, MaxY, Ugol : Word; {параметры процедур} BEGIN GrDriver := Detect; {автоопределение типа графического драйвера} InitGraph(GrDriver, GrMode, 'C:\TP\BGI'); {установка графического режима} SetTextStyle(DefaultFont, HorizDir, 2); {установка шрифта, направления и размера символов} OutTextXY(160, 50, 'Рисуем звездное небо'); Rectangle(110, 90, 520, 380); {рисование рамки } Randomize; {инициализация датчика случайных чисел} Repeat {цикл прерывается нажатием любой клавиши} PutPixel(Random(GetMaxX-250)+120, Random(GetMaxY-210)+100, Random(15)); {вывод пикселя в области, ограниченной рамкой} Delay(5) {задержка} until KeyPressed; Key:=ReadKey; ClearDevice; {очистка графического экрана} {---------------------------------------------------------------} SetColor(White); {цвет рисования} OutTextXY(140, 30, 'Рисуем случайные эллипсы'); Rectangle(100, 70, 560, 420); { рисование рамки } MaxX := GetMaxX; MaxY := GetMaxY; Radius := MaxY div 10; SetLineStyle(0, 0, 1); {толщина и стиль линии} SetViewPort(101, 71, 559, 419, ClipOn); {установка окна внутри рамки} Randomize; {инициализация датчика случайных чисел} Repeat {цикл прерывается нажатием любой клавиши} SetBkColor(Black); {цвет фона } SetColor(Random(13)+1); {цвет рисования} SetFillStyle(Random(12), Random(13)+1); {образец и цвет штриховки} FillEllipse(Random(MaxX), Random(MaxY), {координаты центра эллипса} Random(Radius), Random(Radius)); {полуоси эллипса} until KeyPressed; Key:=ReadKey; ClearDevice; {очистка графического экрана} {------------------------------------------------------------------} SetColor(White); SetViewPort(1, 1, GetMaxX, GetMaxY, ClipOn); OutTextXY(140, 20, 'Рисуем случайные секторы'); Rectangle(90, 60, 570, 420); {рисование рамки} SetViewPort(92, 62, 569, 419, ClipOn); {установка окна внутри рамки} Repeat {цикл прерывается нажатием любой клавиши} SetFillStyle(Random(12), Random(13)+1); {изменение штриховки и цвета} Ugol := Random(360); {угол сектора} Sector(Random(MaxX-200), Random(MaxY-180), Random(Ugol), Ugol, Random(Radius*2), Random(Radius*2)); {рисование сектора} until KeyPressed; ClearViewPort; {очистка окна} CloseGraph; {закрытие графического режима} END.
Перемещение и изменение размеров изображений на экране можно организовать по разному. Так, в примере 8.6 эффект движения изображения достигается следующим образом: выводится изображение, затем оно стирается с экрана с помощью процедуры ClearViewPort, повторно выводится с некоторым перемещением и т.д.
В примере 8.7 применяется другой способ. Сначала на экран выводится рисунок, затем тот же рисунок повторно изображается цветом фона, отчего он становится невидимым, далее рисунок выводится в исходном цвете, но с некоторым перемещением и т.д.
Оба способа имеют одинаковый недостаток
движение изображения является
прерывистым и вызывает мелькание экрана.
В этой программе для организации более плавного движения изображения по экрану используется возможность формировать изображение на разных страницах видеопамяти (обычно их две или четыре, в зависимости от типа графического адаптера).
Изображение сначала создается на странице с нулевым номером, видимой по умолчанию, а на невидимой странице с номером 1 формируется изображение с небольшим перемещением. Затем страница с номером 1 делается видимой, а новое изображение формируется на ставшей невидимой странице с нулевым номером и т.д.
Program Space; {составил студент Тетуев Р., мат.фак. КБГУ} Uses Graph, Crt; Const RadOrb = 250 {радиус орбиты Земли}; RadSun = 70 {радиус Солнца}; RadGal = 100 {радиус галактики }; RadZem = 18 {радиус Земли }; Naklon = 0.2 {коэффициент наклона плоскости орбиты Земли}; PressZem = 0.65 {коэффициент сплющенности полюсов Земли}; Compress = 0.8 {коэффициент сжатия при переходе из }; {расширения режима VGA в режим CGA } Var ZemX, ZemY, UgMer, PixelY, DUgZem , UpDown, XRad, Grad, UgZem, PixelX, StAngle, Ua, Ub, ParallelY , Color, ZemPix, EndAngle, VisualPage, GrMode, GrError, GrDriver, i : Integer; Ugol, CompressZem, Expansion, DUgol, Projection, PolUgol : Real; BEGIN {установка графического режима и проверка возможных ошибок} GrDriver := EGA; GrMode := EGAHi; InitGraph(GrDriver, GrMode, 'C:\TP\BGI'); GrError := GraphResult; If GrError<>GrOk then Halt; SetBkColor(Black); SetFillStyle(1, Yellow); {установка стиля заполнения и цвета Cолнцa} Ugol := 0; DUgol := 2*Pi/180; {орбитальное угловое смещение Земли} UgZem := 0; DUgZem := 14; {осевое угловое смещение Земли} {------------------------------------------------------------------} VisualPage := 1; Repeat {цикл прерывается нажатием любой клавиши} SetVisualPage(1- (VisualPage mod 2)); {установка номера видимой видеостраницы} VisualPage := VisualPage+1; {листание видеостраниц} SetActivePage(1 - (VisualPage mod 2)); {установка номера невидимой (активной) видеостраницы,} {используемой для построения смещенного изображения } ClearDevice; {очистка графического экрана} {--------------------------------------------------------------} {Рисование "расходящейся" галактики} RandSeed:=1; {исходное значение датчика случайных чисел} Expansion:=VisualPage/100; {cкорость расширения галактики} For i:= 1 to VisualPage do begin XRad := Trunc(Expansion*RadGal*Random); {текущее расстояние от звезды до центра галактики} PolUgol:= 2*Pi*Random-VisualPage/30; {текущий центральный угол положения звезды галактики} PixelX := 370+Trunc(XRad*cos(PolUgol+1.8)); {координаты} PixelY := 250+Trunc(XRad*0.5*sin(PolUgol)); { звезды } PutPixel(PixelX, PixelY, White) {рисование звезды} end; {--------------------------------------------------------------} {Рисование мерцающих звезд} Randomize; {инициализация датчика случайных чисел} For i:=1 to 70 do PutPixel(Random(640),Random (350),White); {вспыхивающие звезды} {--------------------------------------------------------------} For i := 1 to 100 do {Рисование орбиты} PutPixel(320+Round(RadOrb * cos((i+VisualPage/5)*Pi/50+0.3)), 160+Round(RadOrb*Naklon*sin((i+VisualPage/5)*Pi/50-Pi/2)),15); {--------------------------------------------------------------} PieSlice(310, 160, 0, 360, RadSun); {Рисование Солнца} {--------------------------------------------------------------} {Рисование Земли (ее параллелей и меридианов)} Ugol := Ugol+DUgol ; {угол поворота Земли относительно Солнца} Grad := Round(180*Ugol/Pi) mod 360; {в рад.(Ugol) и в град.(Grad)} ZemX := 320+Round(RadOrb*cos((Ugol+Pi/2+0.3))); { координаты } ZemY:=160+Round(RadOrb*Naklon*sin(Ugol)); {центра Земли} CompressZem := 2.5-cos(Ugol+0.3); {коэффициент учета удаленности Земли от наблюдателя} ZemPix := Round(RadZem*CompressZem); {текущий радиус Земли} UgZem := UgZem+DUgZem; {угол поворота Земли относительно своей оси} For i := 0 to 11 do { рисование меридианов } begin UgMer := (UgZem+i*30) mod 360; If (90<UgMer) and (UgMer<270) {установка начального и конечного} then begin StAngle := 90; EndAngle := 270 end { углов дуги } else begin StAngle := 270; EndAngle := 90 end; {эллипса меридиана} Ua := (Grad+220) mod 360; Ub := (Grad+400) mod 360; {установка цветов рисования затененной и освещенной частей меридиана} Color := LightBlue; If Ua<=Ub then if (Ua<UgMer) and (UgMer<Ub) then Color := White; If Ua >Ub then if (Ua<UgMer) or (UgMer<Ub) then Color := White; SetColor(Color); XRad := round((ZemPix*cos(UgMer*Pi/180))); Ellipse(ZemX,ZemY,StAngle,EndAngle,abs(XRad),round(PressZem*ZemPix)); end; For i := 2 to 7 do {рисование параллелей} begin XRad := abs(Round(ZemPix*sin(i*Pi/9))); {большая полуось эллипса параллели} UpDown := Round(ZemPix*PressZem*cos(i*Pi/9)); {высота параллели над плоскостью экватора} ParallelY := ZemY+UpDown; {координата Y центра эллипса параллели} SetColor(LightBlue); Ellipse(ZemX, ParallelY, 0, 360, XRad, Round(Naklon*XRad)); {затененная часть параллели} SetColor(White); Ellipse(ZemX,ParallelY,Grad+220,Grad+400,XRad,Round(Naklon*XRad)); {освещенная часть параллели} end; {------------------------------------------------------------------} {Повторное рисование Cолнца, если оно ближе к наблюдателю, чем Земля} If CompressZem<2 then PieSlice(310, 160, 0, 360, RadSun); {------------------------------------------------------------------} RandSeed := VisualPage mod 12; For i := 1 to 250 do {Рисование протуберанцев} begin Projection := (1-sqr(Random))*Pi/2; XRad := RadSun+Round((20)*sin(Projection))-15; PolUgol := 2 * Pi * Random+VisualPage/20; {PolUgol, XRad - полярные координаты протуберанца} PixelX := 310 + Round( XRad * cos(PolUgol)); PixelY := 160 + Round( Compress * XRad * sin(PolUgol)); PutPixel(PixelX, PixelY, LightRed) end; until KeyPressed END.
Пример 8.11. Программа рисует прямоугольную систему координат, отображает в ней заданное множество точек и строит все возможные пары треугольников с вершинами в этом множестве такие, чтобы один треугольник лежал строго внутри другого.
Для работы программы необходимо предварительно создать в текущем каталоге
текстовый файл dan.dat, содержащий координаты точек множества. Файл
должен иметь структуру:
x1 y1
x2 y2
... xn yn
, где 0 < xi <
400, 0 < yi <
600.
Пример файла dan.dat, содержащего координаты десяти точек:
20 20 150 40 90 300 500 400 50 380 110 130 370 290 300 140 70 60 500
170
Пустых строк в файле dan.dat быть не должно.
Program Triangles; {Составил студент Тезадов С., 1 к. мат. фак. КБГУ} Uses Crt,Graph; Const DemoN = 10; DemoX: array [1..DemoN] of Integer = (20,150,90,500,50,110,370,300,70,500); DemoY: array [1..DemoN] of Integer = (20,40,300,400,380,130,290,140,60,170); Var X, Y : Array[1..50] of Integer; {координаты точек множества} InX, InY : Array[1..50] of Integer; {координаты вершин внутренних} Flag : Boolean; {треугольников} Ch : Char; Coord, Num : String; i, j, k, p, i1, j1, k1, n, n1 : Integer; GrDriver, GrMode, GrError : Integer; {--------------------------} Procedure InputOutput; {Описание процедуры считывания координат точек множества из текстового файла dan.dat в массивы X и Y и вывода точек на графический экран } Var f : Text; a,b : Real; Begin Assign(f, 'dan.dat'); {установление связи между физическим } {файлом dan.dat и файловой пеpеменной f} {$I-} {- отключаем автоматическую проверку существования файла} Reset(f); i:=0; {открытие файла f для чтения} {$I+} If IOResult = 0 then begin {если файл существует} While not eof(f) do {цикл "пока не будет достигнут конца файла"} begin Read(f,a,b); Inc(i); {считывание из файла f пары координат} X[i]:=Trunc(a-1); Y[i]:=Trunc(428-b) {преобразование декартовых} end; {координат в координаты графического экрана} n:=i; {n - количество введенных точек множества} Close(f); {закрытие файла f} end Else begin {если файла не существует, то используем множество точек,} n := DemoN; {заданное в DemoN, DemoX, DemoY.} For i:=1 to DemoN do begin x[i] := DemoX[i]; y[i] := 428 - DemoY[i]; end; end;
SetColor(LightCyan); OutTextXY(200,30,'ИСХОДНОЕ МНОЖЕСТВО ТОЧЕК'); For i:=1 to n do {рисование и нумерация точек множества} begin Circle(X[i], Y[i], 2); Str(i, Num); OutTextXY(X[i]+4, Y[i]+3, Num) end; Ch:=ReadKey; ClearViewPort; {очистка графического окна} End; {of InputOutput} {--------------------------} Procedure Drawing_Axes; {описание процедуры рисования осей координат} Begin SetColor(White); MoveTo(30,0); LineTo(30,430); LineTo(639,430); {оси ОХ,OY} OutTextXY(27,0,'^'); OutTextXY(630,427,'>'); {стрелки осей OX, OY} SetColor(LightGreen); OutTextXY(18,0,'y'); OutTextXY(630,434,'x'); OutTextXY(25,433,'0'); SetColor(LightMagenta); {установка розового цвета} For i:=1 to 20 do {нанесение делений и числовых отметок на ось OY} begin Str(20*(21-i), Coord); j:=i*20+10; OutTextXY(2, j-5, Coord); Line(28, j, 30, j) end; For i:=1 to 29 do {нанесение делений и числовых отметок на ось OX} begin Str(20*i,Coord); j:=i*20+30; If Odd(i) then OutTextXY(j-8, 436,Coord); Line(j,430, j,432) end; SetViewPort(31,4,630,429,FALSE) {установка текущего графического окна} End; {of Drawing_Axes} {--------------------------} Function Inside(i, j, k, p : Integer ) : Boolean; {функция Inside возвращает TRUE, если точка с номером p находится внутри треугольника с вершинами в точках i, j, k} Var S1, S2 : Real; {---------------------------------------------------} Function Area(x1, y1, x2, y2, x3, y3 : Real) : Real; {функция вычисления площади треугольника} {с вершинами в точках (x1,y1), (x2,y2), (x3,y3)} Begin Area:=abs((x1*(y2-y3)+x2*(y3-y1)+x3*(y1-y2))/2) End; {of Area} {--------------------------------------------------------} Begin S1:=Area(X[i], Y[i], X[j], Y[j], X[k], Y[k]); {S1 - площадь треугольника с вершинами в точках i, j, k} S2 := Area(X[i], Y[i], X[j], Y[j], X[p], Y[p]) + Area(X[j], Y[j], X[k], Y[k], X[p], Y[p]) + Area(X[k], Y[k], X[i], Y[i], X[p], Y[p]); {S2 - сумма площадей трех треугольников с вершинами в точках (i,j,p), (j,k,p), (i,k,p) } Inside:=S1>S2 - 0.001 End; {of Inside} {--------------------------} Procedure Triangle(x1, y1, x2, y2, x3, y3 : Integer; Color : Byte); Begin {описание процедуры рисования треугольника цвета Color} SetColor(Color); Line(x1, y1, x2, y2); Line(x2, y2, x3, y3); Line(x3, y3, x1, y1) End; {of Triangle} {--------------------------} BEGIN GrDriver:=Detect; InitGraph(GrDriver, GrMode, 'C:\TP\BGI'); GrError:= GraphResult; If GrError<>GrOk then begin WriteLn(' Ошибка графики!'); Halt end;
Drawing_Axes; {вызов процедуры рисования осей координат} InputOutput; {вызов процедуры ввода и вывода исходных данных} Flag:=FALSE; For i:=1 to n -2 do {циклы по номерам вершин внешнего треугольника} For j:=i+1 to n -1 do For k:=j+1 to n do begin SetColor(LightCyan); {установка яркоголубого цвета} For p:=1 to n do {рисование и нумерация точек множества} begin Circle(X[p], Y[p], 2); {рисование точки} Str(p, Num); OutTextXY(X[p]+4, Y[p]+3, Num) {вывод номера точки} end; n1:=0; {занесение координат точек, находящихся внутри треугольника, в массивы InX и InY} For i1:=1 to n do begin If (i1<>i) and (i1<>j) and (i1<>k) and Inside(i,j,k,i1) then begin Inc(n1); InX[n1]:=X[i1]; InY[n1]:=Y[i1] end; end; If n1>=3 then {если число точек внутри треугольника не меньше трех,} begin Flag:=TRUE; {то строятся внутренние треугольники} For i1:=1 to n1-2 do {циклы по номерам вершин внутренних} For j1:=i1+1 to n1-1 do {треугольников} For k1:=j1+1 to n1 do begin {рисование внешнего треугольника красным цветом} Triangle(X[i],Y[i],X[j],Y[j],X[k],Y[k],LightRed); {рисование внутреннего треугольника зеленым цветом} Triangle(InX[i1],InY[i1],InX[j1],InY[j1],InX[k1],InY[k1], LightGreen); OutTextXY(80,450,'Найдено решение. Нажмите любую клавишу!'); Ch:=ReadKey; SetColor(Black); {"стирание" сообщения} OutTextXY(80,450,'Найдено решение. Нажмите любую клавишу!'); {“стирание” внутреннего треугольника} Triangle(InX[i1],InY[i1],InX[j1],InY[j1],InX[k1],InY[k1], Black) end {конец циклов по номерам вершин внутренних треугольников} end; {"стирание" внешнего треугольника} Triangle(X[i], Y[i], X[j], Y[j], X[k], Y[k], Black) end; {конец циклов по номерам вершин внешнего треугольника} SetColor(White); If not Flag then OutText('Для данного множества нет решений задачи') else OutText('РАБОТА ПРОГРАММЫ ЗАВЕРШЕНА'); OutTextXY(80,450,' Нажмите любую клавишу ...'); Ch:=ReadKey; CloseGraph {закрытие графического режима} END.