Как сделать кривую в паскале

Обновлено: 04.07.2024

Возникла тут небольшая задачка - сделать (на паскале, но это совершенно не важно) программу, рисующую кривую Пеано. Что это за кривая, я примерно себе представлял, но смутно, поэтому пришлось обратиться к Википедии за подробностями .

Всю историю пересказывать не стану, тем более, что я её не знаю. В XVIII-XIX веках активно развивался аналитический аппарат теории функций на волне успехов дифференциального и интегрального исчисления, уточнялись базовые понятия, в том числе дело дошло и до понятия кривой. Появилась надежда, что любую непрерывную функцию можно представить при помощи рядов Фурье, потом коварный Дюбуа-Реймон эту надежду похоронил, потом Кантор, поправ существующий в матанализе инструментарий, построил понятие кривой средствами теории множеств. Как пишет Рыбников в "Истории математики", кривых снова оказалось больше, чем формул. В 1882 году Жордан дал определение кривой как совокупность точек плоскости с координатами (x(t), y(t)), где x и y - непрерывные функции от параметра t на некотором отрезке. А в 1890 году Пеано подарил миру плоскую кривую, которая, подпадая под определение Жордана, заполнила собой некоторый квадрат целиком.

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

Вот она, красавица, точнее, одна из первых итераций, использующихся для её построения. Немного похоже на нагревательный элемент в системе "тёплый пол", правда?

Вот она, красавица, точнее, одна из первых итераций, использующихся для её построения. Немного похоже на нагревательный элемент в системе "тёплый пол", правда?

При виде этой картинки возникает закономерный вопрос: а чё так сложно-то? Нельзя, что ли, было просто заштриховать и не мучиться?

Оказывается, нет, нельзя. Дело в том, что кривая Пеано не просто заполняет единичный квадрат, но делает это непрерывно. Смысл тут такой. Если взять любую точку квадрата, то найдётся содержащий эту точку маленький квадратик, который точно таким же образом, как и большой квадрат, будет под завязку заполнен некоторым участком кривой Пеано. Грубо говоря, некоторой окрестности из образа (квадратику) должна соответствовать некоторая окрестность из прообраза (кусочек кривой). Короче говоря, кривая Пеано обладает свойством самоподобия, и это важно для непрерывности.

Какому правилу должен подчиняться размер этой матрицы? Если посмотреть на первую итерацию, то выглядит она так:

Всем привет! У всех студентов, и у меня в том числе, началась летняя сессия. Все сдают зачеты и лабы, закрывают пропуски и т.п.


Я давно сдал все лабы, и у меня осталось несколько программ, которые, думаю, многим еще пригодятся. Все они в основном на Паскале и Делфи. Я писал уже о методе Эйлера и Адамса 4-го порядка на Паскале. В этом посте пойдет речь о снежинке Коха на Паскале (Pascal).

Фракталы наверняка вам знакомы и я не буду писать о том, что это такое и с чем их "едят". Давайте просто сразу перейдем к коду. Он на языке Паскаль и адаптирован под PascalABC (скачать PascalABC можно с официального сайта тут ). Это не мой код, я нашел его на одном из форумов. Я лишь чуть-чуть изменил его, проще говоря, удалил лишнее.

Снежинка Коха на Паскале (Pascal)

Вот такая снежинка у вас должна получиться:


Вкратце про параметры процедуры Draw:

1 и 2 параметр - это координаты начальной точки, откуда будет рисоваться линия;

4 - полярный угол;

5 - количество шагов.

Можете поэкспериментировать с количеством шагов, и получится что-то вроде этого:


Кривая Коха на Паскале (Pascal)

Как вы поняли, снежинка рисуется из 3-х кривых Коха. И для того чтобы нарисовать кривую Коха, используем тот же код с разницей лишь той, что процедура Draw вызывается один раз и с другими параметрами.

Как видите, изменилось мало чего: полярный угол стал равен нулю и начальная точка смещена немного вверх. И вот что получилось:


Разбираться в коде я не стал, но если возникнут вопросы - пишите в комментариях. Вместе разберемся.

В чем заключается вопрос: Как начать работать с графикой на языке Pascal. Основные процедуры(команды).

Сложность: средняя.

Сразу стоит сказать что если вы будите использовать для графики программу PascalABC, то эта статья вам не много не подойдет, за исключение нескольких процедур(команд). Для этой статьи могут использоваться программы Turbo и FreePascal.

Для того чтобы рисовать в Паскале всякие графики, линии, круги и т.д., нужен определенный модуль uses graph, который подключается в самом начале программы:

Дальше в программе нужно открыть окно где мы будет рисовать, т.е. когда мы запустим программу откроется окно графического режима где будет отображено, то что мы нарисовали.

Не надо сильно думать над этой строкой, она практически всегда одинакова. Но про неё расскажу. Как я и сказал это процедура используется для открытия графического режима. У неё 3 параметра:

1-й : Графический драйвер.
2-й : Режим работы этого драйвера.
3-й : Путь к файлу(графическому драйверу) EGAVGA . BGI

Графический драйвер Константа режима Растр Палитра Число страниц
Имя Значение Имя Значение
Detect 0 Выбор драйвера автоматически
CGA 1 CgaC0 0 320*200 C0 1
CgaC1 1 320*200 C1 1
CgaC2 2 320*200 C2 1
CgaC3 3 320*200 C3 1
CgaHi 4 640*200 2 цвета 1
MCGA 2 McgaC0 0 320*200 C0 1
McgaC1 1 320*200 C1 1
McgaC2 2 320*200 C2 1
McgaC3 3 320*200 C3 1
mcgaMed 4 640*200 2 цвета 1
McgaHi 5 640*480 2 цвета 1
EGA 3 EgaLo 0 640*200 16 цвет. 4
EgaHi 1 640*350 16 цвет. 2
VGA 9 VgaLo 0 640*200 16 цвет. 2
VgaMed 1 640*350 16 цвет. 2
VgaHi 2 640*480 16 цвет. 1

Файл EGAVGA . BGI лежит у вас папке с программой в папке bgi если его нет, то его можно скачать в интернете и закинуть в папку с программой. Пример:

Вот это стандарт, т.е. написав вот это, только поменяв путь к файлу вы сможете спокойно работать, не думая ни о чем, режим у вас установится автоматически, если вы хотите свой режим то присвойте переменным d и m цифры из таблицы.

Если напишете так, будет ошибка:

Ну а дальше осталось только рисовать. В принципе дальше можно не читать всё равно не запомните)). Дальнейший материал поможет вам в решение задач, которые мы вскоре разберем и будем обращаться сюда.

Основные процедуры(команды)

Установка цвета.

Имя константы Номер цвета Цвет
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 Белый

Например цвет линий которые будут отображаться на экране можно задать так:

Установка цвета фона.

Чтобы установить цвет фона для всего экрана, используется процедура:

Если процедура установки цвета фона не вызвана, экран будет черным.

Установка указателя вывода.

Процедура MoveTo ( x, y: integer) перемещает указатель в точку с координатами x, y.

Процедура MoveRel ( dx, dy: integer) перемещает указатель на dx, dy пикселей относительно последнего положения.

Функции GetX и GetY возвращают координаты x, y указателя вывода.

Установка точки

Процедура PutPixel ( x, y: integer; color: word) устанавливает точку с координатами ( x, y) и закрашивает ее указанным цветом color.

Функция GetPixel ( x, y: integer): word возвращает значение цвета, в который окрашена точка с координатами ( x, y).

Рисование линий

Процедура Line ( x1, y1, x2, y2: integer) вычерчивает линию между двумя точками экрана с координатами ( x1, y1) и ( x2, y2).

Процедура LineTo ( x, y: integer) вычерчивает линию от последнего положения указателя до точки с координатами ( x, y).

Окружность, эллипс, дуга, сектор

Процедура Circle ( x, y: integer; r: word) вычерчивает окружность радиуса r с центром в точке с координатами ( x, y).

Процедура Arc ( x, y, ugol_ begin, ugol_ end, r: integer) вычерчивает дугу окружности радиуса r с центром в точке с координатами ( x, y). Параметры ugol_ begin и ugol_ end задают угловые координаты начала и конца дуги. Отсчет углов ведется против часовой стрелки. Значения угловых координат задается в градусах.

Процедура Ellips ( x, y: integer; ugol_ begin, ugol_ end, rx, ry: word) вычерчивает эллипс или дугу эллипса с центром в точке с координатами ( x, y). Параметры ugol_ begin и ugol_ end задают угловые координаты начала и конца дуги. Параметры rx и ry определяют горизонтальный и вертикальный радиусы эллипса.

Процедура PieSlice ( x, y: integer; ugol_ begin, ugol_ end, r: word) вычерчивает сектор окружности радиуса r с центром в точке с координатами ( x, y ). Параметры ugol_ begin и ugol_ end задают угловые координаты начала и конца сектора.

Сектор может быть закрашен в соответствии со стилем, заданным процедурой SetFillStyle (о ней читайте ниже).

Процедура Sector ( x, y: integer; ugol_ begin, ugol_ end, rx, ry: word) вычерчивает сектор эллипса с центром в точке с координатами ( x, y) и горизонтальным радиусом rx, вертикальным — ry. Параметры ugol_ begin и ugol_ end задают угловые координаты начала и конца сектора.

Сектор может быть закрашен в соответствии со стилем, заданным процедурой SetFillStyle.

Прямоугольник, закрашенный прямоугольник, параллелепипед

Процедура Rectangle ( x1, y1, x2, y2: integer) вычерчивает контур прямоугольника. Параметры x1, y1 задают положение левого верхнего угла, x2, y2 – правого нижнего.

Процедура Bar ( x1, y1, x2, y2: integer) вычерчивает закрашенный прямоугольник. Параметры x1, y1 задают положение левого верхнего угла, x2, y2 – правого нижнего. Стиль и цвет заливки определяется процедурой SetFillStyle.

Процедура Bar3 D ( x1, y1, x2, y2: integer; глубина: word; граница: boolean) вычерчивает параллелепипед. Параметры x1, y1 задают положение левого верхнего угла, x2, y2 – правого нижнего угла ближней грани. Параметр глубина задает расстояние между передней и задней гранями в пикселях. Параметр граница определяет, нужно ли вычерчивать верхнюю границу задней грани параллелепипеда. Стиль и цвет заливки ближней грани определяется процедурой SetFillStyle.

Вывод текста в графическом режиме.

Процедура OutText ( text: string) выводит строку символов text от текущей позиции указателя вывода и перемещает указатель в точку, расположенную за последним выведенным символом.

Процедура OutTextXY ( x, y: integer; text: string) выводит строку символов text, начиная с точки с координатами ( x, y), при этом указатель своего положения не меняет, т.е. остается в точке ( x, y ).

Стиль вычерчиваемых линий, контуров

Процедура SetLineStyle ( type, pattern, thick: word) устанавливает стиль вычерчиваемых линий. Здесь type, pattern, thick – соответственно тип, образец и толщина линии.

Тип линии может быть задан с помощью одной из следующих констант:

  • SolidLn=0
  • DottedLn=1
  • CenterLn=2
  • DashedLn=3
  • UserBitLn=4

Параметр Pattern учитывается только для линий, вид которых определяется пользователем, т.е. если type=4. Во всех остальных случаях можно поставить любое значение типа word (но обязательно поставить, все-таки это параметр процедуры, значит должен быть).

Каким образом можно задать пользовательский тип линии? Под тип линии отводится переменная типа word, т.е. два байта. Эти два байта и определяют образец линии: каждый установленный в единицу бит этого слова соответствует светящейся точке, нулевой бит — несветящийся пиксель. Таким образом, задается отрезок линии длиной в 16 пикселей. Этот образец периодически повторяется по всей длине линии.

Параметр thick может принимать одно из двух значений:

Стиль и цвет заливки

Процедура SetFillStyle ( style, color: word) устанавливает стиль и цвет заливки (закрашивания) областей ( Bar, Bar3 D, Sector и др.). В качестве параметра style используют одну из констант:

  • 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

Стиль вывода текста

Процедура SetTextStyle ( font, orient, size: word) устанавливает шрифт font, ориентацию orient и размер size текста, выводимого на экран. Параметр font может принимать одну из констант:

  • DefaultFont=0
  • TriplexFont=1
  • SmallFont=2
  • SansSerifFont=3
  • GothicFont=4

В 7.0 версии Паскаля набор шрифтов значительно расширен, но для новых шрифтов не придуманы мнемонические константы, поэтому можно использовать такие номера шрифтов:

Замечание: все шрифты, кроме стандартного (матричного), являются векторными, что позволяет изменять их размеры без ухудшения качества. Каждый из этих шрифтов размещается в отдельном файле. Для использования этих шрифтов необходимо разместить соответствующий файл в рабочем каталоге, в противном случае вызов этого шрифта игнорируется и подключается стандартный шрифт.

Параметр orient задает ориентацию выводимого текста:

Каждый шрифт способен десятикратно изменять свои размеры. Размер шрифта задается параметром size, который может иметь значения от 1 до 10 (точечный или матричный шрифт – в диапазоне от 1 до 32).

Заполнение (закрашивание) произвольной замкнутой фигуры

Процедура FloodFill ( x, y: integer; border: word) заполняет произвольную замкнутую фигуру, используя текущий стиль и цвет заполнения. Координаты точки ( x, y ) указывают, начиная с какой точки будет производиться заливка. Если точка находится внутри замкнутой фигуры, то будет закрашена внутренняя область. Если фигура не замкнута, то заливка разольется по всему экрану. Параметр border указывает цвет граничной линии.

Очистка графического экрана

Процедура ClearDevise очищает графический экран, устанавливает указатель в левый верхний угол.

Сразу вы естественно это не поймёте, нужна практика и еще раз практика иначе не как. Удачи. Спасибо за внимание.

Рассмотрим подробнее процедуры и функции, с которыми мы будем работать.

Circle (X, Y, R), где переменные X, Y, R типа Word - Рисуется окружность в центре (X, Y) c радиусом R.

Arc (X, Y, BegA, EndA, R), где переменные X, Y, BegA, EndA, R типа Word - Рисуется дуга (часть окружности) с координатами центра (X, Y), с радиусом R, которая начинается от угла BegA до угла EndA в полярной системе координат.

Например, чтобы начертить дугу (смотри рисунок) от окружности радиуса 50 пикселей и координатами центра (100, 230) надо набрать команду: Arc (100, 230, 45, 135, 50)

Нетрудно заметить, что если мы будем чертить дугу от 0 до 360, то начертим окружность.

Ellipse(X, Y, BegA, EndA , хR, yR), где переменные X, Y переменные типа integer, а BegA, EndA, хR, yR типа Word - рисуется дуга эллипса, у которого центр находится в точке (X, Y), BegA - начальный угол, EndA - конечный угол, хR - радиус по горизонтальной оси, yR - радиус по вертикальной оси.

Например, чтобы начертить дугу ABC от эллипса надо дать такую команду Ellipse(150, 200, 30, 240, 80, 50).

Вполне очевидно, чтобы начертить весь эллипс надо определить углы черчения дуги от 0 до 360. А также, чтобы “вытянуть” эллипс вверх надо радиус по вертикальной оси сделать больше, чем по горизонтальной (если радиусы будут равны, то будет начерчена дуга окружности или сама окружность).

Rectangle (X1, Y1, X2, Y2), где переменные X, Y переменные типа integer - рисуется прямоугольник, X1, Y1 - координаты верхнего левого угла, X2, Y2 - координаты нижнего угла.

SetLineStyle (Type, Pattern, Thick), где переменные X, Y переменные типа Word - устанавливает стиль линий. Здесь Type - тип линии, Pattern - образец линии, Thick - толщина линии. Тип линии может быть задан с помощью одной из следующих констант:

0 - непрерывная линия
1 - линия из точек
2 - линия из точек и тире
3 - пунктирная линия
4 - линия,задаваемая пользователем

Параметр Pattern учитывается только для линий, вид которых определяет пользователь. Пользователь таким образом может задать линии в виде отрезков длиной до 16 пиксель.

Толщина линий:
1 - толщина в один пиксель
3 - толщина в три пикселя

Задание. Теперь, пользуясь этими процедурами, дорисуйте кораблик (например, иллюминаторы, якорь и др.), а также придумайте и нарисуйте предметы вокруг него, чтобы получилась картинка. Покажите результат работы в конце занятия учителю для оценки.

После того как Вы нарисовали картинку, у Вас, верно, возникло желание ее раскрасить. Для этого есть различные способы. Познакомимся с одним из них - “заливкой” замкнутых площадей различными видами заполнения. Для этого существуют две процедуры SetFillStyle и FloodFill.

SetFillStyle (Pattern, Color), где переменные Pattern, Color типа Word - определяет стиль заполнения и цвет заполнения.

Значения Pattern можно взять из следующей таблицы:

Например, если мы употребили процедуру SetFillStyle (WideDotFill, Red) или SetFillStyle (10, 4), то выбрали стиль закраски “редкими” точками красного цвета.

Теперь же, когда Вы указали компьютеру ЧЕМ Вы будете закрашивать (стиль и цвет), можно указать, ЧТО Вы будете закрашивать. Для этого существует процедура

FloodFill(X, Y, ColorBorder), где X, Y переменные типа integer, а Border - переменная типа word -процедура, которая позволяет заполнить замкнутую область выбранным стилем и цветом закраски. Необходимо только выполнить несколько требований:

    первые два параметра (X, Y) являются координатами так называемой “затравочной” точки, т. е. точки, лежащей обязательно внутри закрашиваемой области;

Например, пусть следующая фигура начерчена синим цветом

Чтобы закрасить ее выбранным стилем и цветом (“редкие” точки красного цвета, см. выше) нужно дать команду FloodFill(180, 200, 1).

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

Чтобы Вас уберечь от многих ошибок и, соответственно, сохранить Ваше время, хочу посоветовать относиться к рисованию фигур и их закраске, как к аппликации. Т. е. если нарисовали фигуру, постарайтесь сразу же ее закрасить, а также рисовать фигуры, начиная от самых больших и заканчивая самыми маленькими.

SetBkColor(Color), где переменная Color типа Word - процедура, устанавливающая цвет фона.

Примечание. После замены цвета фона на любой, отличный от черного, Вы не сможете более использовать цвет 0 как черный, он будет заменяться на цвет фона, т.к. процедуры модуля Graph интерпретируют цвет с номером 0 как цвет фона.

ClеarDeviсe - процедура, которая очищает экран и устанавливает курсор в позицию (0,0).

GraphDefaults - cбрасывает заданные пользователем параметры графического режима и устанавливает исходные (определяемые по умолчанию при запуске процедуры InitGraph).

Задание. Раскрасьте кораблик, используя различные стили и цвета. Покажите учителю полученную картинку и листинг программы.

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




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


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

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

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

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

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

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

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

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

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

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

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


Итак, отложим по оси ОХ числа от 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.

Читайте также: