Линиив Pascal: Line, LineTo, MoveTo

Графика в PascalABC.Net

При работе с графическим окном нужно учитывать две особенности. Во-первых, начало координат – точка (0, 0) – находится не где-то посредине окна, а в левом верхнем углу. Вторая особенность связана с первой: положительное направление оси OY показывает не вверх, а вниз (OX направлена вправо).

Но что делать, если требуется нарисовать геометрическую фигуру или график функции в «нормальной», привычной для нас системе координат? Надо выполнить преобразование системы координат таким образом, чтобы точка (0, 0) находилась посредине окна (в любой нужной точке), а ось OY была направлена вверх. Стандартное преобразование в прямоугольной правой системе координат выглядит следующим образом:

Здесь x0 и y0 – координаты точки, в которую мы хотим перенести начало координат новой системы, x и y – координаты точки в старой системе, x1 и y1 – координаты точки в новой системе. Но поскольку ось OY в графическом окне Паскаля направлена вниз, то для её разворота вверх нужно, естественно, знак координаты y поменять на противоположный (вместо y поставить -y). Таким образом, окончательно получим преобразование координат в графическом окне PascalABC.Net:

В результате последних преобразований вышеуказанная система координат будет иметь следующий вид:

Pдесь начало координат перемещено в центр графического окна, а ось OY направлена вверх. В результате этого стали доступны не только положительные координаты, но также отрицательные.

Напишем простую программу, демонстрирующую все вышесказанное. Для этого, забегая наперед, укажем три полезные в графическом режиме PascalABC.Net процедуры:

TextOut(x, y, s)Вывод текста в графическое окно. При этом текст (строка s) записывается в прямоугольную область таким образом, что точка с координатами (x, y) находится в левом верхнем углу первой буквы;

Line(x1, y1, x2, y2)Проводит отрезок от точки (x1, y1) до точки (x2, y2);

DrawCircle(x, y, r)Рисует окружность с центром (x, y) и радиусом r.

Программа рисует окружность относительно графического окна (x0 = 0, y0 = 0), а через 3 секунды эта окружность появляется относительно нарисованной в центре системы координат. Перепишите эту программу в среду PascalABC.Net и запустите. Вот, собственно, сам код:

 

01.uses

02.GraphABC;

03.

04.const

05.r = 90; //радиус окружности

06.

07.var

08.x0, y0, x, y: integer;

09.

10.begin

11.{ Начало координат: }

12.x0 := WindowWidthdiv2; //половина ширины окна

13.y0 := WindowHeightdiv2; //половина высоты окна

14.x := 100; y := 100; //координаты центра окружности

15.Line(x0 - 250, y0, x0 + 250, y0); //ось OX

16.Line(x0, y0 - 200, x0, y0 + 200); //ось OY

17.Circle(x, y, r); //окружность с центром (x, y) и радиусом r

18.Circle(x, y, 2); //центр окружности (маленькая окружность)

19.TextOut(x + 5, y, '(100, 100)');//надпись возле центра окружности

20.sleep(3000); //делаем паузу на 3 секунды

21.ClearWindow; //очищаем графическое окно белым цветом

22.Line(x0 - 250, y0, x0 + 250, y0); //ось OX

23.Line(x0, y0 - 200, x0, y0 + 200); //ось OY

24.{ Делаем преобразование координат: }

25.x := x0 + x;

26.y := y0 - y;

27.{ Рисуем окружность, центр окружности и надпись: }

28.Circle(x, y, r);

29.Circle(x, y, 2);

30.TextOut(x + 5, y, '(100, 100)');

31.end.


Здесь необходимо сделать некоторые пояснения:
WindowWidth - ширина графического окна;
WindowHeight - высота графического окна (в пикселях);
ClearWindow - эта процедура очищает окно белым цветом;
sleep(ms) - задержка (пауза) на ms миллисекунд.


 

Графики функций в паскале

Для построения системы координат нам необходимо знать, в каких границах графического окна она будет находиться. Можно было бы опустить этот этап и строить декартову систему так, чтобы она занимала все графическое окно. Но это не очень удобно и просто некрасиво выглядит, когда график функции занимает всю область, не имея свободных полей слева-справа и сверху-снизу. Поэтому, чтобы задать прямоугольник, в котором будет находиться система координат, достаточно знать координаты левого верхнего и правого нижнего его углов.

Пусть (xLeft; yLeft) – координаты левого верхнего угла декартовой системы координат в графическом окне PascalABC.Net, (xRight; yRight) – соответственно координаты правого нижнего угла. Следующая задача – провести оси координат OX и OY. Будем считать, что нам нужны все четыре четверти координат. В этом случае обе оси будут иметь положительные и отрицательные значения. Чтобы правильно поставить центр координат (x0; y0), необходимо знать границы изменения аргумента x по оси OX и значения функции f по оси OY.

Итак, отложим по оси ОХ числа от a до b с интервалом dx, по оси OY – числа от fmin до fmax с разницей dy; причем обязательные условия: a≤0, b≥0, fmin≤0, fmax≥0. Для правильного отображения засечек на осях необходимо также, чтобы dx было делителем a и b, а dy было делителем fmin и fmax, и эти числа придется выбирать самостоятельно для каждого интервала. Но сначала нам придется познакомиться с таким понятиемкак масштаб системы координат в графическом окне паскаля.

Что такое масштаб? Масштаб – это величина, или коэффициент, показывающий, сколько пикселей графического окна паскаля приходится на единицу в той или иной оси системы координат. Например, по оси ОХ нужно расположить числа от -4 до 16 (всего 20 единиц), а ширина графического окна паскаля равна 1000 пикселей; тогда на единицу величины оси ОХ приходится 1000:20=50 пикселей/единицу. Это и есть масштаб по оси ОХ. Чтобы узнать, сколько пикселей содержат n единиц, надо просто умножить n на 50.

График функции будем строить по точкам, используя процедуру SetPixel(x, y, c), где x, y - координаты точки в графическом окне паскаля, c - цвет точки. Для рисования осей координат ОХ и OY воспользуемся процедурой Line(x1, y1, x2, y2), где (x1; y1) - координаты начальной точки, (x2; y2) - координаты конечной. Последовательность такова: сначала строим систему координат, а после (в самом конце) вычисляем значения функции, вычисляем соответствующие координаты точки в графическом окне и ставим точку (x, y), закрашенную в зеленый цвет. Откройте PascalABC или PascalABC.Net, скопируйте следующий код и запустите программу:

01.uses

02.graphABC; //Подключаем графический модуль

03.

04.const

05.W = 800; H = 500;//Размеры графического окна

06.

07.functionF(x: real): real;

08.begin

09.F := (x + 1) * (x - 2) * (x - 3); //Функция

10.end;

11.

12.var

13.x0, y0, x, y, xLeft, yLeft, xRight, yRight, n: integer;

14.a, b, fmin, fmax, x1, y1, mx, my, dx, dy, num: real;

15.i: byte;

16.s: string;

17.

18.begin

19.SetWindowSize(W, H); //Устанавливаем размеры графического окна

20.//Координаты левой верхней границы системы координат:

21.xLeft := 50;

22.yLeft := 50;

23.//Координаты правой нижней границы системы координат:

24.xRight := W - 50;

25.yRight := H - 50;

26.//интервал по Х; a и b должно нацело делится на dx:

27.a := -2; b := 6; dx := 0.5;

28.//Интервал по Y; fmin и fmax должно нацело делится на dy:

29.fmin := -10; fmax := 20; dy := 2;

30.//Устанавливаем масштаб:

31.mx := (xRight - xLeft) / (b - a); //масштаб по Х

32.my := (yRight - yLeft) / (fmax - fmin); //масштаб по Y

33.//начало координат:

34.x0 := trunc(abs(a) * mx) + xLeft;

35.y0 := yRight - trunc(abs(fmin) * my);

36.//Рисуемосикоординат:

37.line(xLeft, y0, xRight + 10, y0); //осьОХ

38.line(x0, yLeft - 10, x0, yRight); //осьОY

39.SetFontSize(12); //Размершрифта

40.SetFontColor(clBlue); //Цветшрифта

41.TextOut(xRight + 20, y0 - 15, 'X'); //Подписываемось OX

42.TextOut(x0 - 10, yLeft - 30, 'Y'); //Подписываемось OY

43.SetFontSize(8); //Размершрифта

44.SetFontColor(clRed); //Цветшрифта

45.{Засечкипооси OX: }

46.n := round((b - a) / dx) + 1; //количество засечек по ОХ

47.fori := 1ton do

48.begin

49.num := a + (i - 1) * dx; //Координата на оси ОХ

50.x := xLeft + trunc(mx * (num - a)); //Координата num в окне

51.Line(x, y0 - 3, x, y0 + 3); //рисуем засечки на оси OX

52.str(Num:0:1, s);

53.ifabs(num) > 1E-15then//Исключаем 0 наоси OX

54.TextOut(x - TextWidth(s) div2, y0 + 10, s)

55.end;

56.{ Засечки на оси OY: }

57.n := round((fmax - fmin) / dy) + 1; //количествозасечекпоОY

58.fori := 1ton do

59.begin

60.num := fMin + (i - 1) * dy; //Координата на оси ОY

61.y := yRight - trunc(my * (num - fmin));

62.Line(x0 - 3, y, x0 + 3, y); //рисуем засечки на оси Oy

63.str(num:0:0, s);

64.ifabs(num) > 1E-15then//Исключаем 0 наоси OY

65.TextOut(x0 + 7, y - TextHeight(s) div2, s)

66.end;

67.TextOut(x0 - 10, y0 + 10, '0'); //Нулевая точка

68.{ График функции строим по точкам: }

69.x1 := a; //Начальное значение аргумента

70.whilex1 <= b do

71.begin

72.y1 := F(x1); //Вычисляем значение функции

73.x := x0 + round(x1 * mx); //Координата Х в графическом окне

74.y := y0 - round(y1 * my); //Координата Y в графическом окне

75.//Если y попадает в границы [yLeft; yRight], то ставим точку:

76.if(y >= yLeft) and(y <= yRight) thenSetPixel(x, y, clGreen);

77.x1 := x1 + 0.001//Увеличиваем абсциссу

78.end

79.end.

Вы должны увидеть следующее:

А теперь программа для тех, у кого нет PascalABC, но есть TurboPascal или FreePascal. Итак, скопируйте нижеприведенный код в блокнот, сохраните в формате .pas и откройте в турбо паскале, потом запустите (ctrl+F9):

01.uses

02.Graph; { Подключаеммодуль }

03.

04.functionF(x: real): real;

05.begin

06.F := (x + 1) * (x - 2) * (x - 3); { Функция }

07.end;

08.

09.var

10.Gd, Gm, x0, y0, x, y, xLeft, yLeft, xRight, yRight, n: integer;

11.a, b, fmin, fmax, x1, y1, mx, my, dx, dy, num: real;

12.i: byte;

13.s: string;

14.begin

15.x0 := 0;

16.Gd := Detect;

17.InitGraph(Gd, Gm, 'C:\tp7\bgi'); { Инициализируем графический режим }

18.{ Координаты левой верхней границы системы координат: }

19.xLeft := 50;

20.yLeft := 50;

21.{ Координаты правой нижней границы системы координат: }

22.xRight := GetMaxX - 50;

23.yRight := GetMaxY - 50;

24.{ интервал по Х; a и b должно нацело делится на dx: }

25.a := -2; b := 6; dx := 0.5;

26.{ Интервал по Y; fmin и fmax должно нацело делится на dy: }

27.fmin := -10; fmax := 20; dy := 2;

28.{ Устанавливаем масштаб: }

29.mx := (xRight - xLeft) / (b - a); { масштаб по Х }

30.my := (yRight - yLeft) / (fmax - fmin); { масштаб по Y }

31.{ начало координат: }

32.x0 := trunc(abs(a) * mx) + xLeft;

33.y0 := yRight - trunc(abs(fmin) * my);

34.{Рисуемосикоординат: }

35.line(xLeft, y0, xRight + 10, y0); { осьОХ }

36.line(x0, yLeft - 10, x0, yRight); { осьОY }

37.SetColor(4); { Цветшрифта }

38.SetTextStyle(1, 0, 1); { Устанавливаемстильшрифта: }

39.OutTextXY(xRight + 20, y0 - 15, 'X'); { Подписываемось OX }

40.OutTextXY(x0 - 15, yLeft - 35, 'Y'); { Подписываемось OY }

41.SetColor(14); { Цветшрифта }

42.{ Засечки по оси OX: }

43.n := round((b - a) / dx) + 1; { количество засечек по ОХ }

44.fori := 1ton do

45.begin

46.num := a + (i - 1) * dx; { Координата на оси ОХ }

47.x := xLeft + trunc(mx * (num - a)); { Координата num в окне }

48.Line(x, y0 - 3, x, y0 + 3); { рисуем засечки на оси OX }

49.str(Num:0:1, s);

50.ifabs(num) > 1E-15then{ Исключаем 0 наоси OX }

51.OutTextXY(x - TextWidth(s) div2, y0 + 10, s)

52.end;

53.{ Засечки на оси OY: }

54.n := round((fmax - fmin) / dy) + 1; { количествозасечекпоОY }

55.fori := 1ton do

56.begin

57.num := fMin + (i - 1) * dy; { КоординатанаосиОY }

58.y := yRight - trunc(my * (num - fmin));

59.Line(x0 - 3, y, x0 + 3, y); { рисуем засечки на оси Oy }

60.str(num:0:0, s);

61.ifabs(num) > 1E-15then{ Исключаем 0 наоси OY }

62.OutTextXY(x0 + 7, y - TextHeight(s) div2, s)

63.end;

64.OutTextXY(x0 - 10, y0 + 10, '0'); { Нулевая точка }

65.{ График функции строим по точкам: }

66.x1 := a; { Начальное значение аргумента }

67.whilex1 <= b do

68.begin

69.y1 := F(x1); { Вычисляем значение функции }

70.x := x0 + round(x1 * mx); { Координата Х в графическом окне }

71.y := y0 - round(y1 * my); { Координата Y в графическом окне }

72.{ Если y попадает в границы [yLeft; yRight], то ставим точку: }

73.if(y >= yLeft) and(y <= yRight) thenPutPixel(x, y, 12);

74.x1 := x1 + 0.001{ Увеличиваем абсциссу }

75.end;

76.SetColor(15);

77.OutTextXY(GetMaxX div2- 50, 50, 'y = (x+1)(x-2)(x-3)');

78.readln

79.end.

Если все сделано правильно, вы должны увидеть такой график функции:


Линиив Pascal: Line, LineTo, MoveTo

На предыдущих страницах мы говорили об точках в Паскале: изучили процедуры GetPixel (определить цвет данного пикселя) и PutPixel, SetPixel (задать данному пикселю определенный цвет – там мы строили линии и не только с помощью точек). Здесь рассмотрим одни из наиболее важных процедур в графике Паскаля – построение линий Line, LineTo и вспомогательная для последней MoveTo.

Так чем же отличаются Line и LineTo, и зачем нужна загадочная MoveTo?

✎Line(x1, y1, x2, y2) – Эта процедура соединяет отрезком точки (x1, y1) и (x2, y2).

12345678 usesGraphABC; { Подключаем графический модуль } begin{ Проводим отрезок от точки с координатами (50, 80) до точки с координатами (300, 400): }Line(50,80,300,400)end.

Теперь немного разукрасим отрезок и увеличим его толщину, так как в предыдущем примере по умолчанию цвет черный, а толщина линии 1 пиксель:

1234567891011 usesGraphABC; //Подключаем модуль для рисования в графическом окне beginSetWindowTitle('Отрезок'); //Заголовок окнаSetPenWidth(3); //Толщина отрезка 3 пикселяSetPenColor(clRed); //Цвет отрезка - красный{ Проводим отрезок от точки с координатами (50, 80) до точки с координатами (300, 400): }Line(50,80,300,400)end.

Ниже представлены примеры программ случайных появляющихся отрезков:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 uses GraphABC; //Модуль для рисования в графическом окне   begin SetWindowCaption('Случайные отрезки'); var W := WindowWidth; //Ширина графического окна var H := WindowHeight; //Высота графического окна randomize; { Следующий цикл будет бесконечным, поскольку условие True в цикле While всегда истинно: } while true dobegin var n := random(5, 50); //количествоотрезковот 5 до 50 forvari := 1 to ndobegin SetPenWidth(random(1, 10)); //толщинаотрезков SetPenColor(ClRandom); //случайныйцветотрезка { Координаты первой точки: } var x1 := random(50, W - 50); var y1 := random(50, H - 50); { Координаты второй точки: } var x2 := random(50, W - 50); var y2 := random(50, H - 50); { Рисуем отрезок от точки (x1, y1) до точки (x2, y2): } Line(x1, y1, x2, y2) end; sleep(2000); //задержка на 2 секунды ClearWindow //очищаем окно белым цветом end end.

 

✎Line(x1, y1, x2, y2, C) – Проводит отрезок от точки (x1, y1) до точки (x2, y2), закрашивая отрезок цветом C. Есть только в PascalABC.Net. Толщина линии при этом равна 1 пиксель и её изменить нельзя.

123456789 usesGraphABC; beginrandomize;{ Проводим отрезок от точки (100,150) до точки (400,300), закрашенный случайным цветом clrandom: }Line(100,150,400,300,ClRandom)end.

✎MoveTo(x, y) – Устанавливает начальную точку (позицию) рисования в (x, y). Если эту процедуру не задействовать, то начальная точка по умолчанию принимается за (0, 0) – левый верхний угол окна. Процедура MoveTo используется совместно с LineTo (см. ниже).

✎LineTo(x, y) – Рисует отрезок от точки, в которой на данный момент находится конец отрезка (текущая позиция), до точки (x, y); начальная позиция задается с помощью MoveTo (см. выше), а новая позиция переходит в точку (x, y). Данная процедура задействуется при построении последовательной цепочки линий (отрезков) – когда конец каждой линии является одновременно началом следующей.

Код PascalABC, PascalABC.Net
123456789101112 usesGraphABC; //Подключаем модуль для рисования в графическом окне beginSetWindowTitle('Треугольник'); //Заголовок окнаSetPenWidth(3); //Толщина сторон треугольника 3 пикселяSetPenColor(clRed); //Цвет сторон - красныйMoveTo(100,50); //Ставим первую точку (100,50)LineTo(500,200); //Проводим отрезок к точке (500,200)LineTo(300,400); //Проводим отрезок к точке (300,400)LineTo(100,50)//Проводим отрезок к первоначальной точкеend.

А как нарисовать звезду на паскале? Ниже представлен пример программы для рисования звезды в PascalABC.Net с указанным количеством концов. Все комментарии с в коде:

N-конечная звезда

 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 uses GraphABC;   //Рисует n-конечную звезду proceduremyStar(n, x0, y0, r1, r2, pw: integer; C1, C2: Color); //r1 > r2 var x, y, i, R: integer; a, da: real; begin a := pi * random; //Начальный угол поворота - случайный da := pi / n; //Интервал изменения градуса(в радианах): 360/(2n) SetPenColor(C1); SetPenWidth(pw); fori := 0 to 2 * n dobegin //sleep(1000); //Задержка на 1 сек.(можно удалить) a := a + da; //Увеличиваем угол ifodd(i) then R := r2 //Равен меньшему радиусу else R := r1; //Равен большему радиусу { Преобразование координат: } x := x0 + Round(R * cos(a)); y := y0 + Round(R * sin(a)); if i = 0 thenMoveTo(x, y) //Устанавливаем начальную позицию elseLineTo(x, y) //Проводим отрезки end; FloodFill(x0, y0, C2) //Закрашиваем внутринность звезды цветом C end;   var x0, y0, r1, r2, n, pw: integer; C1, C2: Color;   begin n := 7; //Количество концов(углов) звезды { Координаты центра звезды - по центру окна: } x0 := WindowWidthdiv 2; y0 := WindowHeightdiv 2; r1 := 200; //Больший радиус r2 := 80; //Меньший радиус pw := 3; //Толщина границы в пикселях C1 := clGreen; //Цвет границы звезды C2 := clYellow; //Цвет заливки звезды { Вызываем процедуру рисования звезды, передавая все нужные параметры: } myStar(n, x0, y0, r1, r2, pw, C1, C2) end.
       

Результат выполнения программы представлен на рисунке:

 


Дата добавления: 2018-04-15; просмотров: 2273; Мы поможем в написании вашей работы!

Поделиться с друзьями:




Мы поможем в написании ваших работ!