НОВОСИБИРСКИЙ ГОСУДАРСТВЕННЫЙ УНИВЕРСИТЕТ СПЕЦИАЛИЗИРОВАННЫЙ УЧЕБНО-НАУЧНЫЙ ЦЕНТР Кафедра физики
Кандауров И.В., Мезенц...
12 downloads
257 Views
543KB Size
Report
This content was uploaded by our users and we assume good faith they have the permission to share this book. If you own the copyright to this book and it is wrongfully on our website, we offer a simple DMCA procedure to remove your content from our site. Start by pressing the button below!
Report copyright / DMCA form
НОВОСИБИРСКИЙ ГОСУДАРСТВЕННЫЙ УНИВЕРСИТЕТ СПЕЦИАЛИЗИРОВАННЫЙ УЧЕБНО-НАУЧНЫЙ ЦЕНТР Кафедра физики
Кандауров И.В., Мезенцев Н.А., Мешков О.И., Мучной Н.Ю., Пиндюрин В.Ф., Симонов Е.А.
МОДЕЛИРОВАНИЕ ФИЗИЧЕСКИХ ЯВЛЕНИЙ НА ЭВМ
Методическое пособие Часть I Общие сведения о курсе Справочная информация по языку PASCAL Построение графиков функций
Новосибирск 2000
Данное пособие является первым в серии учебно-методических материалов по специализированному курсу "Моделирование физических явлений на ЭВМ", преподаваемого учащимся Специализированного учебнонаучного центра Новосибирского государственного университета (СУНЦ НГУ). Пособие включает в себя вводные сведения о целях курса и о компьютерном классе СУНЦ НГУ, справочные сведения по используемому языку программирования PASCAL и его библиотечным модулям. Основная часть пособия посвящена методам построения графиков различных функций – необходимой основы для дальнейших занятий по курсу. Также предлагается набор задач для самостоятельного решения. Наряду с учащимися СУНЦ НГУ, пособие может быть полезным для учащихся старших
классов
специализированных
школ
физико-математического
профиля и для студентов младших курсов вузов соответствующих специальностей.
Рецензенты: доцент кафедры физики СУНЦ НГУ Харитонов В.Г. профессор кафедры теор. физики НГУ, к.ф.- м.н. Коткин Г.Л.
Новосибирский государственный университет, 2000 г.
Подготовлено при поддержке ФЦП «Интеграция», проект «Современные компьютерные технологии в ранней профессиональной ориентации и подготовке физиков-исследователей» (рег. № 274)
1
СОДЕРЖАНИЕ Введение в курс
3
Основные сведения о компьютерном классе
4
Справочные сведения по языку программирования PASCAL
6
Структура программы
6
Выполняемые операции и выражения
11
Выполняемые операторы
13
Библиотечные модули
17
Полезные приемы вычисления функций
23 24
Построение графиков функций Способы задания функций
24
Предварительный анализ функции
26
Масштабирование и выбор координат
27
Ввод-вывод текстовой информации в графическом режиме
29
Примеры построения графиков функций
33
Некоторые замечательные плоские кривые
40
Построение плоской проекции 3-х мерных объектов
50
Задачи на построение трехмерных объектов
56 57
Рекомендуемая литература
2
ВВЕДЕНИЕ В КУРС Компьютеры стремительно и необратимо вошли в нашу жизнь. Сегодня они находят применение практически во всех сферах человеческой деятельности, принимая на себя огромную массу рутинной работы и открывая человеку новые возможности для творчества. С развитием электронных вычислительных машин (ЭВМ) возникло много новых подходов и к решению большого количества научно-технических задач, расширился круг осуществимых экспериментов, увеличилась точность получаемых научных результатов. Одно из перспективных применений ЭВМ в современной науке – это возможность численного моделирования различных природных явлений и процессов. Во многих случаях компьютерное моделирование позволяет существенно сэкономить время и средства при решении конкретных научнопрактических задач. Иногда такое моделирование даже является единственно доступным способом получения результата. И, несомненно, компьютерное моделирование позволяет глубже понять фундаментальные законы природы. Чем больше вычислительная мощность ЭВМ, тем более сложную и точную модель какого-либо физического, или иного явления можно исследовать численными методами. С 1985 года для учащихся СУНЦ НГУ научными сотрудниками Института ядерной физики Сибирского отделения РАН (ИЯФ СО РАН) преподается специализированный курс «Моделирование физических явлений на ЭВМ». Возникнув на основе компьютерного класса, созданного совместными усилиями сотрудников ИЯФ, НГУ и СУНЦ, и оборудованного (вполне современными тогда) микро-ЭВМ «Электроника-60М», курс прошел ряд этапов в своем развитии, параллельно с бурным развитием компьютерной техники, и в настоящее время проводится в учебных классах компьютерного центра СУНЦ, на базе персональных компьютеров класса Pentium II. Главная цель обучения по программе данного курса – приобретение базовых теоретических и практических навыков моделирования физических явлений на ЭВМ. Разумеется, использование компьютера при решении физических и других задач не может отменить необходимость владения 3
теорией и умения решать проблемы «обычными», аналитическими методами. Так же, как обладание обычным калькулятором бесполезно без знания правил вычислений, равно и наличие даже самой мощной ЭВМ не поможет без умения сформулировать задачу и выбрать правильный алгоритм расчетов; понимания, как проверить физическую правдоподобность и оценить погрешности получаемых результатов. С этой точки зрения компьютер – всего лишь мощный инструмент, а будете ли вы им заколачивать гвозди, как простым физическим телом, или получать с его помощью красивые и правильные результаты, определяется исключительно вашими знаниями и умением. Свой вклад на разных этапах развития курса внесли более 15 научных сотрудников ИЯФ СО РАН. Ими было отобрано и подготовлено большое количество задач по численному моделированию физических явлений, которые и легли в основу обучения по курсу. Предполагается, что все программы для решения задач курса пишутся самими учащимися. Многолетняя практика преподавания подтверждает, что освоение курса вполне по силам даже для человека, который никогда ранее не имел дела с компьютером. Как правило, после года занятий на курсе учащийся способен самостоятельно моделировать на ЭВМ достаточно сложные физические явления. Языком программирования для выполнения задач курса, по причине простоты освоения и ясности текстов программ, выбран язык PASCAL. Основной упор при решении задач делается на представление получаемых результатов в наглядном графическом виде (графики функций, траектории частиц, изображения полей, гистограммы и т. д.). Графическая интерпретация решений позволяет легче найти закономерности, наглядно увидеть динамику процессов. Следует также сказать, что значительная часть предлагаемых задач либо не решается аналитически, либо решается достаточно сложными методами. И последнее замечание. Несмотря на то, что курс построен, в основном, на задачах физики, большинство из используемых численных методов – построение графиков, нахождение корней уравнений, численное дифференцирование и интегрирование, численное решение дифференциальных уравнений, статистические методы – являются достаточно общими и применимы для решения проблем из других областей 4
знания: химии, экономики, биологии и т. д. Поэтому полученные в процессе обучения знания будут полезны для вас даже и в том случае, если ваша будущая деятельность не будет связана с физикой напрямую. Желаем успеха !
ОСНОВНЫЕ СВЕДЕНИЯ О КОМПЬЮТЕРНОМ КЛАССЕ Рабочие места класса (всего их в классе 12) оборудованы IBM PC – совместимыми персональными компьютерами. В состав каждого рабочего места входит системный блок (собственно компьютер), оснащенный процессором типа Intel Celeron, графический дисплей SVGA, а также клавиатура и мышь. Каждый компьютер имеет собственный жесткий магнитный диск. Дисководы гибких магнитных дисков при работе не используются. Все компьютеры класса подключены по локальной сети к центральному компьютеру файлового сервера с дополнительным объемом дискового пространства. Рабочим языком программирования на курсе является язык высокого уровня PASCAL. Подготовка, отладка и запуск программ по задачам курса ведутся в среде разработки приложений Borland Pascal 7.0 Жесткий магнитный диск каждой рабочей станции поделен на два логических диска с именами C и D. Диск C используется для хранения системного программного обеспечения, он доступен только для чтения и запрещен для записи. Диск временного хранения D открыт для записи и является основным рабочим диском для подготовки учащимися собственных программ. Вся информация на диске D ежедневно стирается по завершении занятий с целью освобождения места на нем. Поскольку написание и отладка типичной программы по задачам курса требует времени, как правило, более одного занятия, для долговременного хранения текстов подготавливаемых программ используется место на диске файлового сервера. Каждому учащемуся выделен фиксированный объем дискового пространства на сервере. Забота о сохранении результатов работы лежит на самом учащемся, поэтому в конце занятия необходимо скопировать нужные файлы с текстами 5
программ с диска D рабочей станции на диск сервера, а в начале следующего занятия, соответственно, прочитать их с диска сервера на диск D. При архивировании файлов на диск сервера рекомендуется пользоваться компрессирующими программами типа RAR, ZIP или ARJ. Для получения доступа к диску файлового сервера, необходимо предварительно зарегистрироваться в списке пользователей, получить логическое имя для входа и начальный пароль (который в дальнейшем можно поменять). Как правило, регистрация пользователей производится централизованно, в начале учебного года, во время интенсивного начального курса информатики и обучения языку программирования. ВНИМАНИЕ! Не разрешается производить компиляцию и запуск программ непосредственно на диске сервера! Наряду с замедлением скорости компиляции, это может также помешать нормальной работе других учащихся. Кроме того, запрещается хранить на диске сервера исполняемые файлы с расширениями .EXE, .COM, .BAT и прочие файлы, не имеющие прямого отношения к задачам учащихся.
СПРАВОЧНЫЕ СВЕДЕНИЯ ПО ЯЗЫКУ ПРОГРАММИРОВАНИЯ PASCAL
Структура программы В общем случае программа состоит из 8 разделов: • названия программы; • списка используемых библиотек; • описания меток; • описания констант; • определения типов данных; • описания переменных; • описания процедур и функций; • тела программы (выполняемых операторов).
6
Любой
раздел,
кроме
раздела
выполняемых
операторов,
может
отсутствовать. 1.
Заголовок программы – в нем указывается имя программы и
список параметров (который может и отсутствовать). Например: Program Name (Input, Output, File1, . . . FileN);
2.
Раздел используемых модулей – список имен используемых в
программе библиотечных модулей. Библиотечные модули могут быть стандартными или написанными пользователем. Например: Uses Crt, Graph;
использование стандартных библиотечных модулей для работы с экраном и клавиатурой (CRT.TPU) и для работы с графикой (GRAPH.TPU). 3.
Раздел меток – список используемых в программе меток. Любой
выполняемый оператор может иметь метку – целую положительную константу. Метка находится перед оператором и отделяется от него двоеточием. Метки используются в выражениях вида:
goto NumberN;
которые позволяют изменять последовательность выполнения программы. Синтаксис: Label Number1, …... ,NumberN;
4.
Раздел констант – константами называются параметры, которые не
меняются в процессе выполнения программы. Использование констант делает программу более наглядной, удобной при отладке и при внесении изменений. Синтаксис: const Constant1 = Value1; Constant2 = Value2;
Здесь: ConstantN – имя константы, ValueN – значение константы. 7
Пример: const E = 2.71828; EOL = 1; NormT: real = 273.3; Ist = True; Outwr = 'Выход'; Key = 'Z';
5.
Раздел типов – описываются все вводимые пользователем типы,
отличные от стандартных: type TypeName1 = AnyType1; ... TypeNameN = AnyTypeN;
Здесь: TypeNameХ – идентификатор вводимого типа AnyTypeХ, (Х=1,2…N). Пример: type Color = (Black, Blue, Green, Red, White); RealList = array[1..10] of Real;
6.
Раздел переменных – описываются переменные, которые будут
использоваться в программе: var VarName11, ..., VarName1K: Type1; ... VarNameN1, ..., VarNameNM: TypeN;
Здесь: VarName11, ..., VarName1K – имена переменных с типом Type1 ; а VarNameN1, ... VarNameNK; – имена переменных с типом TypeN.
Каждая переменная должна быть описана до ее использования в программе и отнесена только к одному типу. Тип переменной можно задать двумя способами: указать имя типа (real, Color, RealList… ) или описать сам тип (array[1..10] of Real). Названия разделов (const, type, var, . . . ) указываются только один раз.
8
Пример описания переменных: type Name = String[2]; RealList = array[1..10] of Real; var I, J, K: Integer; ScrX, ScrY: Shortint; Massa, Gr: word; Polus: Extended; Za, Zb, Zc: Single; Apol, B: Real; Key: Boolean; L: Char; Month: String[10]; Comm: String; Res: Name; Vector: array[1..100] of Double; ID: array[1..2, 0..5] of Real; High: array[1..7] of Integer; A: RealList; Keys: array[-12..12] of Boolean;
Наиболее употребительные типы переменных: •
целый тип (Integer, Shortint, Longint, Byte, Word, Comp);
•
вещественный тип (Real, Single, Double, Extended);
•
булевский тип (Boolean);
•
литерный (строковый) тип (Char, String);
•
массив (Array). Целые типы Название
Диапазон чисел
shortint
-128..127
Длина в байтах 1
integer
-32768..32767
2
longint
-2147483648..2147483647
4
byte
0..255
1
word
0..65535
2
9
Вещественные типы Название
Диапазон чисел
Число знач. цифр мантиссы
Число занимаемых байт
single
± 1.5⋅10-45..1.7⋅1038
7-8
4
real
± 2.9⋅10-39..1.7⋅1038
11-12
6
15-16
8
double
± 5.0⋅10
-324
..1.7⋅10
308
extended
± 3.4⋅10-4932..1.1⋅104932
19-20
10
comp
− 9.2⋅1018..9.2⋅1018
19-20
8
Примечание:
Хотя тип
Comp считается вещественным типом, он
содержит только целые числа из широкого диапазона значений, которые представляются в вычислениях как вещественные (с нулевой мантиссой). Булевский тип Boolean – может принимать только два значения: True ("истинно") и False ("ложно"). Символьный тип Char – используется для хранения одиночных символов, например: 'a', 'h', '*', '7' и т.д. Массив Array – упорядоченная структура, состоящая из фиксированного числа элементов одного типа. Примеры описаний массивов см. выше. Строка
String – является массивом символов, с динамической длиной и
максимальным размером до 255 символов. Если размер строки не задается, то он считается равным 255. Для этого типа переменных возможны следующие арифметические операции: + (конкатенация, сложение строк), и операции сравнения = , , < , > , = . Примеры строковых переменных: 'Turbo Pascal 7.0'; 'Matrix'; 'VelosityX'
10
7.
Процедуры (Procedure) и функции (Function). Procedure Name (Param1; Param2;...ParamN)
начало текста подпрограммы-процедуры с названием Param2,...ParamN
–
параметры
подпрограммы,
Name;
которые
Param1,
задаются
в
следующем виде: ParName1, ... ParNameM: Type;
где: ParName1,...ParNameM − имена формальных входных параметров типа Type.
Параметры
процедуры
будут
также
выходными
(параметрами-
переменными), если их описать в виде: var ParName1,...ParNameM: Type;
Подпрограмма может иметь свои собственные разделы (label, const, type, var). Выполняемая часть подпрограммы начинается с ключевого слова begin и завершается словом end.
Пример процедуры, вычисляющей и распечатывающей на дисплей n
значение суммы
∑sin(ix) : i =1
Procedure Sumn(n:integer; x:real; var S:real); var i:integer; begin S:=0; for i:=1 to n do S:=S+Sin(i*x); write('S=',S); end;
Обращение к процедуре:
Sumn(10, Xcur, Sum);
Function Name (Param1; Param2; ..., ParamN): NameType;
– начало текста подпрограммы-функции типа
NameType
с названием
Name, которому в тексте должно быть присвоено некоторое вычисленное
значение: Name := выражение;
11
Пример функции, вычисляющей sin (m x) . e x : Function F(m:integer; X:Real): Real ; begin F := Sin(m*X)*Exp(X) end;
Вызов функции: Point := 40+175*F(mult,Xabs) ;
Раздел выполняемых операторов программы начинается с
8.
ключевого слова begin и заканчивается словом end , после которого должна стоять точка.
Выполняемые операции и выражения Арифметические операции с целыми и вещественными числами: +
сложение целых и вещественных чисел;
−
вычитание целых и вещественных чисел;
*
умножение целых и вещественных чисел;
/
деление вещественных чисел;
DIV
целочисленное деление − целая часть частного;
MOD
остаток от деления целых чисел.
Логические
операции с
целыми
(побитное
выполнение
над
соответствующими двоичными кодами чисел) и булевскими переменными: NOT
– логическое отрицание:
NOT a – "истина", если a есть "ложь",
"ложь", если a есть "истина"; AND
– логическое умножение:
a AND b – "истина", если как a, так и b – "истина", "ложь", если либо a, либо b – "ложь"; OR
– логическое сложение: 12
a OR b – "истина", если либо a, либо b − "истина",
"ложь", если как a, так и b − "ложь"; – логическое исключающее сложение:
XOR
a XOR b – "истина", если a не равно b, "ложь", если a = b.
Операции отношения – результат всегда булевского типа: =
равно;
не равно;
больше чем;
=
больше или равно.
Правила вычисления выражений: действия выполняются слева направо с соблюдением следующего старшинства: 1) функции и выражения в скобках; 2) NOT ; 3) * , / , DIV , MOD , AND ; 4) + , − , OR ; 5) = , , < , > , = . Недопустима последовательная запись двух знаков операций. Пример: A*−B – неправильно; A*(−B) – правильно.
Выполняемые операторы Оператор присваивания ( := ) VarName := Expression;
13
где: VarName – переменная, Expression – выражение и := – оператор присваивания. Переменной VarName присваивается вычисленное значение выражения Expression, стоящее в правой части оператора. Выражение Expression может содержать константы, переменные, названия функций,
знаки операций и скобки. Пример: F:= 3*C+2*sin(X); A[4*I - 3] := 17 div I;
Оператор безусловного перехода ( goto ) goto N;
где: N – метка, на которую передается управление. Метка должна быть описана в разделе Label. Составной оператор Если
при
некотором
условии
надо
выполнить
определенную
последовательность операторов, то их объединяют в один составной оператор. Составной оператор начинается ключевым словом begin и заканчивается словом end, после которого должна стоять точка с запятой (end;). Пример: begin I:=2; K:=I/5; end;
Оператор условного перехода ( if ) if Expression then Statement;
где: Expression – булевское выражение, Statement – оператор (простой либо составной). Если Expression – "истина", то выполняется оператор Statement. Если Expression – "ложь", то управление сразу передается следующему за Statement оператору.
14
Оператор if может иметь другой вид: if Expression then Statement1 else Statement2;
где:
Expression – булевское выражение;
Statement1,
Statement2
–
операторы. Если Expression – "истина", то выполняется оператор Statement1. Если
Expression – "ложь", то выполняется оператор Statement2. Затем в
обоих случаях управление передается следующему оператору. Примеры: 1) if A0 then B:=X/A; 2) if (A>0) OR (A1 then begin I:=I+1; B:=1/A; end; else goto 15;
Оператор выбора (case) case Selector of C11, ..., C1M: Statement1; ... CN1, ..., CNL: StatementN; else Statement; end;
Здесь: Selector – переключатель; C11, . . . , C1M, . . . , CN1, . . . , CNL − списки констант выбора. Переключатель и константы выбора должны быть одного и того же скалярного типа (кроме вещественного). Оператор case передает управление тому оператору Statement, с одной из констант выбора которого совпало значение переключателя Selector, а затем – на оператор, следующий за end. Если ни одна из констант не равна текущему значению селектора, выполняется оператор, стоящий за словом else. Если слово else отсутствует, управление передается следующему за end
оператору.
15
Пример: case I of 2: X := 0; 3,4: X := X*X; 11..20: X := Cos(X); 100: begin X := Sin(X) ; K := 1; end; end;
Оператор цикла ( while) while Expression do Statement;
где Expression – булевское выражение, Statement – оператор (простой либо составной). Выражение Expression вычисляется перед каждым выполнением цикла. Если Expression
– "истина", то выполняется оператор
Statement
и
управление передается на вычисление Expression. Если Expression – "ложь", то оператор Statement не выполняется и происходит выход из цикла. Если первоначальное значение Expression – "ложь", то цикл не выполняется ни разу. Пример: while X0 do begin C := C+1/X; X := X-1; end;
Оператор цикла ( repeat) repeat Statement1; Statement2; ... StatementN until Expression;
где
Statement1,
Statement2,
... StatementN – группа выполняемых
операторов, Expression – булевское выражение.
16
Работает оператор так: выполняется группа операторов и вычисляется выражение Expression. Если оно "ложь", то вычисления повторяются. Если оно "истина", то выполнение цикла заканчивается. Пример: repeat C := C+1/X; X := X-1; until X=0;
Оператор цикла ( for) for Var := First to Last do Statement;
Здесь: Var – переменная цикла, First – начальное значение переменной цикла, Last – конечное значение переменной цикла, Statement – оператор (простой либо составной). Var,
First
и
Last
должны быть скалярного
типа (кроме вещественного), для целого типа шаг переменной цикла всегда равен единице. Цикл по убывающим значениям параметра Var имеет вид: for Var := First downto Last do Statement;
Пример вычисления суммы S = 1 + 1/2 + 1/3 +...+ 1/50: S := 0; for I:=1 to 50 do S := S+1 /I;
Операторы ввода и вывода Read (V1, V2, ... VN); – ввод параметров V1, V2, ... VN. Write (V1, V2, ... VN); – вывод параметров V1, V2, ... VN.
Отличие операторов ReadLn и WriteLn от Read и Write: • ReadLn после приема параметров переходит на новую строку; • WriteLn после вывода параметров переходит на новую строку. Примеры: Read (I, A, B); – прием трех чисел;
17
ReadLn; – ожидание нажатия на клавишу <ENTER>; Write (' X=', X, ', Y=', Y); – вывод значений переменных X и Y (с
комментариями); WriteLn (X:10:2); – форматированный вывод переменной X (10
позиций отводится под выводимое число, из них 2 позиции– под дробную часть) и переход на новую строку.
Библиотечные модули Системный модуль SYSTEM.TPU Содержит встроенные процедуры и функции языка PASCAL. Этот модуль не требуется указывать при описании используемых
библиотечных
модулей,
поскольку
при
компиляции
программы он подключается автоматически. Наиболее употребительные функции и процедуры модуля: Int(x:real): real – целая часть действительного числа (здесь и дальше после
идентификатора аргумента и функции указаны их типы); Frac(x:real): real – дробная часть действительного числа; Trunc(x:real): Longint – усечение
действительного числа до ближайшего
целого; Round(x:real): Longint – округление действительного числа до ближайшего
целого; Abs(x) – абсолютное значение числа (тип результата совпадает с типом
аргумента); Exp(x:real): real – экспонента от действительного числа; Ln(x:real): real – натуральный логарифм действительного числа; Sqr(x) – возведение числа x в квадрат (тип результата совпадает с типом
аргумента); 18
Sqrt(x: real): real – квадратный корень действительного числа; Sin(x: real): real – синус действительного числа (значение угла в радианах); Cos(x: real): real – косинус действительного числа (значение угла в радианах); ArcTan(x: real): real – арктангенс действительного числа (значение угла в
радианах); Pi:real – функция, возвращающая значение числа π = 3.141592653589793238; Random [(x: word)] – псевдослучайное
целое
(word)
число,
имеющее
равномерное распределение на интервале [0, x]. Если аргумент отсутствует, то результатом будет псевдослучайное вещественное число (real) с равномерным распределением в интервале [0,1]; Примечание: аргумент функции, взятый в квадратные скобки, является необязательным и может отсутствовать. Randomize – инициализация генератора случайных чисел; Exit – выход из подпрограммы во внешний блок программы; если указан в
основной части программы, то выход в систему программирования; Halt [(x: Word)] – прекращение выполнения программы и выход в систему
программирования, x – выходной код программы; Str (x [:width:[:decimals ]], s) – преобразование числа x в символьную строку s.
Здесь: width – число выводимых позиций, decimals – число позиций под дробную часть; полученная строка может выводиться подпрограммами Write или OutText; Val (s, x, Code) – преобразование строки s в число x ; здесь: Code – целая
переменная, равная позиции неправильного символа (если Code=0, то ошибок нет).
19
Модуль CRT.TPU
Содержит процедуры и функции для работы с
клавиатурой и с экраном в текстовом режиме, а также некоторые другие. Наиболее употребительные процедуры и функции модуля: TextColor (Color: Byte) – задание цвета (Color) вывода на экран; TextBackground (Color: Byte) – задание
цвета
фона
(не
работает
при
установленном графическом режиме экрана); Window (X1, Y1, X2, Y2: Byte) – задание текстового окна под вывод на экране:
(X1, Y1) – координаты верхнего левого угла окна на экране, (X2, Y2) – координаты правого нижнего угла окна; ClrScr – очистка активного текстового окна; GoToXY(X,Y: Byte) – установка текущего положения курсора в активном
текстовом окне в позицию с координатами (X, Y); KeyPressed: Boolean – отвечает на вопрос "Была ли нажата какая-нибудь
клавиша на клавиатуре?": если какая-то клавиша была нажата, то – "истинно", иначе – "ложно"; ReadKey: Char – читает символ с клавиатуры; пример работы: repeat ... until KeyPressed; WriteLn (‘Получен символ: ‘,ReadKey); Sound(Hz: Word) – включение внутреннего громкоговорителя, где Hz –
частота в Гц; NoSound – выключение внутреннего громкоговорителя; Delay(N: Word) – задержка выполнения программы на N миллисекунд.
20
Содержит процедуры и функции для
Графический модуль GRAPH.TPU работы в графическом режиме экрана.
Графическая мода VGA позволяет вывести на экран 640 × 480 точек. Каждая точка может быть окрашена в один из 16 цветов. Начало координат находится в левом верхнем углу экрана, как показано на рисунке.
(639,0)
(0,0)
X
экран дисплея (0,479)
(639,479)
Y
Палитра цветов EGA/VGA Черный 0 Темно-серый 8 Синий 1 Светло-синий 9 Зеленый 2 Светло-зеленый 10 Сине-зеленый 3 Светло-сине-зел 11 Красный 4 Светло-красный 12 Розовый 5 Светло-розовый 13 Коричневый 6 Желтый 14 Светло-серый 7 Белый 15 Для работы в графическом режиме необходимо переключить дисплей персонального компьютера в графическую моду работы: uses Graph; var GraphDriver, GraphMode: Integer; ... begin GraphDriver := Detect;
21
InitGraph(GraphDriver, GraphMode, 'D:\TP\BGI'); if GraphResult grOk then Halt(1); ... end.
Наиболее употребительные процедуры и функции модуля: CloseGraph
– выход из графического режима и возращение дисплея в текстовую моду;
ClearDevice – очистка всего экрана дисплея; SetViewPort (X1,Y1,X2,Y2:Integer; Clip:Boolean) – задание
текущего
графического окна для вывода: (X1,Y1) – координаты (на полном
экране)
левого
верхнего
угла
окна,
(X2,Y2) –
координаты правого нижнего угла окна; булевская константа Clip запрещает (ClipOn) или разрешает (ClipOff) вывод за
пределами окна; ClearViewPort – очистка текущего графического окна; SetColor(Color:Word) – задание текущего цвета вывода; SetBkColor(Color:Word) – задание цвета фона; PutPixel (X,Y:Integer; Color:Word) вывод точки с цветом Color в позиции (X,Y); MoveTo(X,Y:Integer) – установка текущего положения точки в позицию (X,Y)
(без вывода точки на экран); Line(X1,Y1,X2,Y2:Integer) – вывод линии с текущим цветом из точки (X1,Y1) в
точку (X2,Y2); LineTo(X,Y:Integer) – вывод линии с текущим цветом из текущей точки на
экране в точку с координатами (X,Y); Пример проведения линии из начальной точки с координатами X=10, Y=20 в конечную точку с координатами X=100, Y=100 : Первый способ:
MoveTo(10, 20); LineTo(100, 100);
22
Второй способ:
Line(10, 20, 100, 100);
OutText(TextString:string) – вывод текста TextString на дисплей, начальные
координаты
левого
верхнего
угла
вывода
определяются текущим положением точки; OutTextXY(X,Y:Integer; TextString:string) – вывод строки TextString на дисплей,
(X,Y) – начальные координаты левого верхнего угла выводимой строки; Пример вывода на дисплей текста 'X=' и значения переменной X : uses Graph; var X: Real; S: String[5]; begin ... OutTextXY(100, 100, 'X='); Str(X:5:2, S); OutText(S); ... end. Circle(X,Y:Integer; Radius:Word) вывод окружности с текущим цветом, с
центром в положении (X,Y) и с радиусом Radius; Rectangle(X1,Y1,X2,Y2: Integer) вывод прямоугольника с текущим цветом:
(X1,Y1) – координаты
левого
верхнего
угла
прямоугольника, (X2,Y2) – координаты правого нижнего угла; GetMaxX – отдает
значение
максимальной
(правой)
горизонтальной
координаты экрана; GetMaxY – отдает
значение
максимальной
координаты экрана; GetX – отдает X-координату текущей точки; GetY – отдает Y-координату текущей точки.
23
(нижней)
вертикальной
Полезные приемы вычисления функций Вычисление функции типа y x В среде программирования Borland Pascal (Turbo Pascal) отсутствует библиотечная функция, позволяющая непосредственно вычислять выражения вида
y x , однако эту проблему можно обойти, используя функции exp ( x ) и
ln x. Действительно, y x = exp ( ln y x ); С другой стороны, ln y x = x ln y; Таким образом, получаем: y x = exp ( x ln y). Применяя данное выражение, помните, что ln y определен только для значений
y > 0.
Вычисление arcsin ( x ) и arccos ( x ) Отсутствующие в среде Borland Pascal обратные тригонометрические функции arcsin ( x) и arccos ( x) могут быть выражены, с помощью известных формул тригонометрии, через функцию arctg ( x), которая входит в состав библиотеки встроенных функций: arcsin (x) = arctg
x 1 − x2
и
arccos (x) = arctg
1 − x2 x
Следует помнить, что эти формулы верны только для главных значений обратных
функций,
а
именно,
в
24
пределах
π
π
− 2 ≤ arcsin (x) ≤ 2 и
0 ≤ arccos (x) ≤ π . Более того, формула для arccos (x) верна только для положительных значений x.
ПОСТРОЕНИЕ ГРАФИКОВ ФУНКЦИЙ
Способы задания функций Функция, описывающая какую-либо физическую величину, может быть задана разными способами. Наиболее широко используется задание в декартовых координатах, в полярных координатах (на плоскости) и в параметрическом виде. В декартовых координатах (см. Рис.) каждому значению аргумента x, определенному в интервале задания [a, b], ставится в соответствие значение функции y, вычисляемое по заданной зависимости f
:
y = f ( x), x = [a, b] В полярных координатах каждому значению полярного угла ϕ на интервале задания [ϕa, ϕb ] ставится в соответствие значение модуля радиусвектора r, определяемое по заданной зависимости g :
Y
(x, y)
r ϕ
X
a
b 25
ϕ = [ϕa, ϕb ] .
r = g (ϕ) ,
Связь между декартовыми и полярными координатами осуществляется по формулам: x = r cos(ϕ) , y = r sin(ϕ) . Существует большой класс функций, которые либо невозможно представить в виде y = f ( x ), либо значительно удобнее задать в так называемом параметрическом виде: x = ψ ( t ); y = χ ( t ); t = [ta, tb]; где: ψ и χ – функции для вычисления координат x и y от некоторого параметра t, при изменении которого меняются x и y. Параметр t может быть физическим параметром, например, временем, а может быть и формально введенным удобным для описания параметром. Особенностью построения таких функций является то, что диапазон изменения значений x и y определяется диапазоном изменения параметра t.
Предварительный анализ функции При
построении
функций
нужно
всегда
помнить
некоторые
особенности выполнения вычислений на ЭВМ. К таким особенностям, прежде всего, нужно отнести деление на нуль и вычисление функции в области задания аргумента, в которой функция не определена. Попытка выполнения таких действий на ЭВМ приведет либо к ошибке вычислений, либо к получению совершенно бессмысленных результатов. Поэтому перед написанием программы построения какой-либо функции всегда полезно провести ее предварительный анализ на предмет наличия у функции особых
26
точек, в которых она может обращаться в бесконечность, и определить правильные границы ее задания. Пусть, для примера, нам нужно построить во всей области задания простейшую функцию: y=
1
(a – константа) .
x − a2 2
Сразу видно, что при x = a в знаменателе получится ноль, и при делении 1 на 0 возникнет неопределенность, которая поставит ЭВМ в тупик. Такая же особая точка будет и при x = – a. Кроме того, при x < a под знаком корня будет отрицательное число, что также весьма «озадачит» ЭВМ, поскольку функция квадратного корня
sqrt
определена лишь для
положительных значений аргумента. Таким образом, правильной областью задания аргумента x для построения функции будет: – xm ≤ x ≤ – a – δ , где: δ = – a +
a + δ ≤ x ≤ x m,
(xm ≥ 0) .
a2 + 1 ym2 , а xm и ym – заданные максимальные значения,
которые может принимать аргумент и функция, соответственно. Отметим еще одну особенность рассматриваемой функции – то, что она имеет две не связанные между собой области задания [ – xm ,– a – δ] и [a + δ, xm]. Такая ситуация характерна для многих функций. Так, например, для функции y = tg (x) таких областей задания может быть бесконечно много: (– π/2 + δ) + k⋅π ≤ x ≤ (π/2 – δ) + k⋅π, где: k = ± 0, 1, 2, … . . .
; δ = arcctg (ym) ; и где ym – допускаемое максимальное
значение функции (ym ≥ 0).
Масштабирование и выбор координат 27
Значения аргумента и функции в общем случае могут принимать произвольные значения, однако в большинстве физических задач тип переменных аргумента x и функции y должен быть вещественным. Изобразить
же
график функции
на
экране
ЭВМ
можно
лишь
в
прямоугольнике экрана с ограниченным числом точек по горизонтали и вертикали. Так, для используемого цветного графического адаптера VGA максимальное число точек на экране по горизонтали и вертикали составляет 640 и 480, соответственно. Число точек экрана для построения графиков может быть и меньше, если для вывода используется заранее выбранное графическое окно, составляющее лишь часть экрана. Поэтому, прежде чем приступить к построению графика, нужно выбрать положение осей координат
и
масштабные
множители,
которые
позволят
разместить
интересующий участок функции на экране компьютера. Будем
называть
(x, y),
переменные
описывающие
функцию,
физическими координатами, а переменные (X, Y), определяющие положение точки на экране компьютера, экранными координатами. По своему смыслу экранные координаты, в отличие от физических координат, должны быть переменными целого типа. Эти переменные могут принимать значения от 0 до Xmax для X-координаты, и от 0 до Ymax для Y-координаты. Для полного
экрана Xmax = 639 и Ymax = 479. Значения Xmax, Ymax могут быть также найдены с помощью библиотечных функций: Xmax := GetMaxX ;
Ymax := GetMaxY.
Пусть нам надо нарисовать функцию y, которая изменяется от значения ymin до значения ymax в пределах изменения аргумента x от xmin до xmax
. Для
того, чтобы функция не выходила за пределы экрана, определим масштабные множители:
28
XS =
X max ( x max − x min )
– масштаб по X
,
YS =
Ymax ( y max − y min )
– масштаб по Y
.
Заметим, что для масштабных множителей используются вещественные переменные XS, YS. Если значение функции, равное нулю, попадает в интервал [ymin , ymax], то можно провести ось абсцисс с координатами Y := round (Ymax – yfmin*YS); Line (0,Y,Xmax,Y);
где вещественная переменная yfmin соответствует значению функции ymin. Аналогично можно построить ось ординат, если значение аргумента, равное нулю, попадает в диапазон [xmin , xmax]: X := round (–xfmin*XS); Line (X, 0, X, Ymax);
где вещественная переменная xfmin соответствует значению функции xmin. Построение очередной точки функции y, предварительно сохраненной в вещественной переменной yf, при аргументе x ( xf – соответствующая вещественная переменная) проводится в этих координатах по формулам: X:=round((xf–xfmin)*XS); Y:=Ymax–round((yf–yfmin)*YS); PutPixel(X,Y,Color); { Color − цвет точки }
В общем случае, когда трудно определить диапазоны изменений x и y, нахождение максимальных и минимальных значений функции и аргумента xmin, xmax
, ymin, ymax выполняют во время работы программы, вводя эти
значения с клавиатуры. Возможны и широко используются также способы автоматического масштабирования графиков. Желающие могут попробовать сделать автоматическое масштабирование самостоятельно.
29
Построение графиков функций, заданных в полярных координатах или в параметрическом виде, производится аналогично рассмотренному случаю. Во всех случаях сначала вычисляются значения физических координат x и y в декартовой системе, после чего производится нужное масштабирование и вычисление экранных координат X и Y для построения графика.
Ввод-вывод текстовой информации в графическом режиме Находящийся перед вами компьютер имеет всего один экран (монитор), который используется для ввода и вывода информации как в текстовом режиме, так и в графическом. Существенно, что одновременно экран может находиться лишь в одном из этих режимов, то есть, если вы переключились в графический режим, то этот режим устанавливается для всего экрана. Если же вы перешли в текстовый режим, то он также устанавливается для всего экрана, и вы не можете использовать весь экран или его часть в графическом режиме. Для
построения
графиков
однозначно
необходим
переход
в
графический режим. Очень часто при решении задач, кроме вывода графиков, бывает полезным одновременный вывод и текстовой информации. Говоря здесь о текстовой информации, мы имеем в виду не только вывод каких-либо надписей на экране, но и вывод чисел, поскольку любое число является соответствующим набором знаковых символов, то есть может быть представлено в виде текстовой информации. Например, при рисовании траектории частицы интересно знание значений ее текущих координат или ее текущей энергии. Возможны два способа вывода такой информации на экран в графическом
режиме.
Первый
способ
подразумевает
использование
специальных процедур и функций, имеющихся в библиотеке Graph. Во втором способе используются стандартные операторы вывода write и writeln, 30
работающие, вообще говоря, в текстовом режиме. Ввод же текстовой информации выполняется также стандартными операторами read и readln. Имеется
ряд
особенностей
использования
указанных
операторов
в
графическом режиме, которые полезно знать для правильного применения операторов. Пусть
в
графическом
режиме
нам
нужно
выдавать
текущую
y - координату частицы, и пусть значение этой координаты находится в соответствующей переменной yf. С использованием средств библиотеки Graph такая выдача может быть организована следующим образом (см. также Пример 1): 1. Для вывода открывается графическое окно, занимающее часть экрана: SetViewPort(Xt1, Yt1, Xt2, Yt2, Clip).
Здесь: (Xt1, Yt1) – координаты (на полном экране) верхнего левого угла окна, (Xt2, Yt2) − координаты правого нижнего угла окна (целого типа). Clip – переменная булевского типа. Если для нее установлено значение ClipOn, то вся выводимая в окно информация при выходе за пределы границ окна не будет отображаться на экране. Если установлено значение ClipOff, то выходящая за границы окна информация будет также отображаться. 2. Производится очистка окна: ClearViewPort.
Если этого не сделать, то выводимая в окно информация будет накладываться на ранее отображенную информацию, которая уже имелась в окне. 3. Устанавливается цвет вывода информации: SetColor(Color).
Если эта процедура не делается, то информация будет выводиться последним установленным цветом.
31
4. Производится преобразование переменной yf в знаковый тип: Str(yf:m:n,s).
Здесь: m – полная ширина поля для изображения числа (количество символов; кроме цифр здесь могут быть символы знака числа и десятичной точки), n – число цифр после десятичной точки (дробная часть числа). Параметры m и n необязательны и могут не задаваться, в этом случае перевод выполняется по стандартному I-формату (для целых чисел) или по Eформату (для вещественных чисел) так же, как и в операторе write. Перевод производится в строковую переменную s. 5. Производится вывод надписи и значения числа на экран: OutText ('y = '); OutText (s);
Для предварительного позиционирования вывода текста в окне может использоваться процедура MoveTo(Xp,Yp) , где: Xp, Yp – координаты точки в окне (целые переменные) для начала текста. Начальное позиционирование и вывод текста могут также производиться процедурой OutTextXY(Xp,Yp,s) . 6. Производится возвращение в графическое окно, где рисуется график: SetViewPort(Xg1,Yg1,Xg2,Yg2,Clip) ,
здесь: (Xg1,Yg1), (Xg2,Yg2) – координаты (на полном экране) границ окна для вывода графика. При выводе текстовой информации описанным способом и при рисовании графика точками с помощью процедуры PutPixel(X,Y,Color) дополнительных особенностей не возникает. Если же график выводится линиями,
то
предыдущей
приходится точки
сохранять
графика
значения
(Xold, Yold),
экранных
поскольку
координат
переключение
графических окон с выводом в них информации, естественно, изменяет положение текущего указателя на экране. Вывод очередной точки графика с текущими экранными координатами (X,Y) выполняется тогда как: 32
Line(Xold,Yold,X,Y); Xold:=X; Yold:=Y;
Более простым является второй способ, когда используются обычные операторы write и writeln (см. Пример 2). Для того, чтобы эти операторы нормально работали в графическом режиме, необходимо
присвоить
переменной DirectVideo значение False: DirectVideo := False;
Такое задание означает, что вывод из программы на экран будет осуществляться не прямо в видеопамять экрана, а через посредство системных программных средств операционной системы, ответственных за ввод и вывод информации. По умолчанию переменная DirectVideo имеет значение True. Рассмотренный выше вывод текущего значения переменной yf может быть выполнен здесь в виде: GoToXY (XS,YS); write ('y = ',yf:m:n);
Здесь процедура GoToXY(XS,YS) производит позиционирование для начала вывода текста в знаковых позициях XS, YS (XS = 1,2,...,80; YS = 1,2,...,25). Процедурой TextColor(Coltext) может быть установлен желаемый цвет вывода текстовой информации. Если указанная процедура не используется, то текстовый вывод производится белым цветом. Ограничением является установка цвета фона для вывода. Цвет фона задается в графическом режиме процедурой SetBkColor(Color) и одинаков для вывода графической и текстовой информации, по умолчанию предполагается черный цвет. При описанном способе вывода текста положение текущей точки графика на экране не изменяется, поэтому можно одновременно выводить и текст, и график как точками, так и линиями без принятия каких-либо специальных мер по сохранению координат предыдущей точки графика.
33
Ввод текстовой информации и в текстовом, и в графическом режиме может выполняться стандартными операторами read и readln без каких-либо особенностей. Часто бывает полезным приостановить работу программы до ввода с клавиатуры какого-нибудь знака, чтобы, например, подробно рассмотреть выведенный график. Наиболее просто такая процедура приостановки программы может быть выполнена с помощью оператора readln без параметров. Дойдя до этого оператора программа «зависнет» на нем до введения с клавиатуры <ENTER>. Но нужно помнить – чтобы «зависание» на этом операторе происходило, последним перед ним оператором ввода не должен быть read (но может быть readln ) !
Примеры построения графиков функций Пример 1. Построить график функции во всей области ее задания: y=
1
( a − константа )
x − a2 2
Эта функция рассматривалась выше, там же был сделан ее анализ. Будем вводить с клавиатуры значение константы a, а также значение максимальной координаты xm и максимальное значение функции ym. Строить функцию будем в двух интервалах: [– xm, – a – δ] и [a + δ, xm]. Число точек n для построения функции в каждом интервале определим из соотношения: n = (xm – a) / δ. Построение функции проведем точками. Вариант программы: uses Crt, Graph; var Gd, Gm: Integer; i,n,k,X,Y: integer; xf,yf,XS,YS,Xm,Ym,a,Delta: real;
34
s: string; label 1; Procedure Visu; begin yf := 1/sqrt(sqr(xf) – sqr(a)); {вычисление функции y} { Вычисление экранных координат X,Y } X := round((xf + Xm)*XS); Y := round(349 – yf*YS); PutPixel(X, Y, white); {вывод белой точки с координатами X, Y} {Вывод на экран текущих значений x, y} SetViewPort(10, 30, 110, 60, ClipOn);{установка окна для вывода} ClearViewPort; {очистка окна} SetColor(green); Str(xf:5:1,s) {перевод числа xf в знаковый вид} OutText('X = '); OutText(s); {вывод текущего значения x} Str(yf:5:1,s); {перевод числа yf в знаковый вид} MoveTo(0,20); OutText('Y = '); OutText(s); {вывод текущего значения y} SetViewPort(0, 0, 639, 349, ClipOn); {возвращение в окно для вывода графика} end; begin 1: ClrScr; {очистка экрана} writeln('Введите максимальные значения аргумента и функции:'); write('Xm = '); read(Xm); if Xm < 0 then goto 1; {проверка на корректность введенного Xm} write('Ym = '); read(Ym); if Ym < 0 then goto 1; {проверка на корректность введенного Ym} write('Введите параметр a = '); readln(a); {но не read(a), иначе не будет «зависания» на следующем readln} if (a < 0) or (a > Xm) then goto 1; {проверка на корректность a и Xm} Delta:=-a + sqrt(sqr(a) + 1/sqr(Ym)); n := Trunc((Xm - a)/Delta); {вычисление числа точек для рисования графика} { Переход в графический режим экрана} Gd:=Detect; InitGraph(Gd,Gm,'c:\bp\bgi'); if GraphResult grOk then Halt(1); { Построение осей абсцисс и ординат} setcolor(blue); Line(0,349,639,349); Line(319,0,319,349); { Вычисление масштабирующих множителей} XS:=639/2./Xm;
35
YS:=349/Ym; {Построение асимптотических осей функции в точках с x= -a и x=a} SetColor(red); X:=round((-a+Xm)*XS); Line(X,0,X,349); X:=round((a + Xm)*XS); Line(X,0,X,349); { Вывод графика и текущих значений x,y} { вывод левой ветви графика} for i:=0 to n do begin xf:= -Xm + Delta*i; {физическая координата x} Visu; end; { вывод правой ветви графика} for i:=1 to n+1 do begin xf:=a+Delta*i; Visu; end; ReadLn; {'зависание' на приеме <Enter> с клавиатуры} CloseGraph; {выход из графического режима экрана} GoTo 1; end.
Пример 2.
Построить функцию (спираль Архимеда), заданную в
полярных координатах: r = a ϕ ; a − константа,
ϕ = [0, ∞] .
Отметим, прежде всего, что в указанной области задания функция не имеет особенностей. Константа a фактически является масштабирующим множителем, будем вводить ее значение с клавиатуры. Станем увеличивать угол ϕ с постоянным шагом dϕ от 0 до тех пор, пока величина радиуса r не станет больше размера половины экрана по вертикали. В качестве шага dϕ возьмем 1 градус (π /180).
36
Вариант программы: uses Crt, Graph; var Gd, Gm: Integer; X,Y: integer; r,a,fi,dfi: real; label 1; begin dfi := Pi/180; {вычисление шага по углу} 1: DirectVideo := False; {отключение прямого доступа к видеопамяти экрана} ClrScr; {очистка экрана} textcolor(green); {установка зеленого цвета для текстового вывода} writeln('...Спираль Архимеда: r = a*fi ...'); write('Введите a='); readln(a); if a < 0 then goto 1; {проверка на корректность введенного a} {Переход в графический режим экрана} Gd:=Detect; InitGraph(Gd,Gm,'c:\bp\bgi'); if GraphResult grOk then Halt(1); {Построение осей координат синим цветом} setcolor(blue); Line(145,174,495,174); Line(319,0,319,349); setcolor(white); {установка белого цвета для графика} MoveTo(319,174); {установка начальной точки графика} fi:= 0; {установка начального значения угла} {Построение графика и вывод текущих значений угла и радиуса} repeat fi:= fi + dfi; {текущий угол} r:= a*fi; {текущий радиус} {Вычисление экранных координат} X:= 319 + round(r*cos(fi)); Y:= 174 - round(r*sin(fi)); {Рисование линии из предыдущей точки в текущую} LineTo(X,Y); {Вывод на экран текущих значений угла и радиуса} gotoXY(65,4); write('fi=',fi:6:1); gotoxy(65,5); write('r = ',r:5:1); until r > 175; ReadLn; {зависание на приеме <Enter> с клавиатуры} CloseGraph; {выход из графического режима} GoTo 1; end.
37
Пример 3. Построить график функции (Декартов лист), заданной в параметрическом виде: x=
3t 1 + t3
,
y=
3 t2 1 + t3
,
t = [–100, 100] .
Видно, что функция имеет особенность в точке t = –1. Выделим эту точку и будем строить график функции в двух интервалах: [–100, –1 – δ] (левая ветвь) и [–1+ δ, 100] (правая ветвь) При δ с клавиатуры} CloseGraph; {выход из графического режима} GoTo 1; end.
НЕКОТОРЫЕ ЗАМЕЧАТЕЛЬНЫЕ ПЛОСКИЕ КРИВЫЕ. Задание по разделу: Построить графики приведенных ниже кривых в декартовом, полярном или параметрическом представлении, по выбору. Исследовать форму кривых при различных значениях свободных параметров, там, где это необходимо. Верзиера Исследование этой кривой связывается с именем Марии Аньези (1718–1799). Отсюда другое название верзиеры – «локон Аньези». Уравнение кривой в декартовых координатах: y=
a3 x2 + a 2
( a>0 )
или в параметрическом представлении: y=
x = t,
a3 t2 + a 2
Строфоида Впервые строфоиду исследовал Торичелли (1645), вследствие чего кривую долгое время называли «крылом Торичелли». Название «строфоида» происходит от греческого слова σ τ ρ ο φ η
– поворот. В
математическую литературу это название было введено лишь в середине 19 века. Кроме
многочисленных
геометрических
приложений,
строфоида
встречается также в некоторых вопросах оптики и начертательной геометрии. 40
Уравнение кривой в декартовых координатах: x 2a − x
y = ± (x − a)
,
(a > 0);
в полярных координатах: ρ=a
1 ± sin ϕ ; cos ϕ
или в параметрическом представлении: x= Декартов
2 at2
,
1 + t2
лист Впервые
y= в
истории
at(t2 − 1)
;
1 + t2
математики
кривая,
названная
впоследствии декартовым листом, определяется в письме Декарта к Ферма в 1638 г., как кривая, для которой сумма объемов кубов, построенных на абсциссе и ординате каждой точки, равняется объему параллелепипеда, построенного на абсциссе, ординате и некоторой константе. Название же «декартов лист» прочно установилось только с начала 18 века. Уравнение кривой в прямоугольной системе координат: x3 + y 3 – 3 a x y = 0 ; в параметрическом представлении: x =
3 at 1 + t3
y =
,
3 at2 1 + t3
;
в полярных координатах: ρ=
Циссоида
2a cos ϕ sin ϕ cos 3 ϕ + sin 3 ϕ
Диоклеса Открытие
циссоиды
приписывается
Диоклесу,
жившему в 3 веке до нашей эры, в поисках решения «делосской задачи» –
41
возможности найти графическим путем ребро куба с объемом, в два раза большим объема данного куба. Уравнение кривой в прямоугольной системе координат: y2 =
x3 2a − x
;
в параметрическом представлении: x=
a 1+ t
2
,
y=
a t (1 + t 2 )
;
в полярных координатах: ρ=
2a sin 2 ϕ cos ϕ
Конхоида Никомеда Первое исследование этой кривой приписывается Никомеду (3 век до нашей эры), который и применил ее для решения задачи о трисекции угла. Уравнение кривой в декартовых координатах: ( x 2 + y 2 ) ( y − a) 2 − l 2 y 2 = 0 ; в полярных координатах: ρ=
a +l sin ϕ
Форма конхоиды зависит от взаимного соотношения параметров a и l. Соответственно, выделяются случаи a > l, a = l и a < l.
42
Улитка Паскаля Также относится к числу трисектрис, т. е. кривых, позволяющих осуществить трисекцию угла. Уравнение кривой в декартовых координатах: (x 2 + y 2 − 2 ax) 2 − l 2 ( x 2 + y 2) = 0 ; в полярных координатах: ρ = 2a cos ϕ + l ; в параметрическом задании: x = 2a cos 2 t + l cos t ; y = 2a cos t sin t + l sin t Форма улитки зависит от соотношения параметров a и l. Интерес представляют случаи l > 2a, l = 2a и l < 2a. Интересное полезное качество данной кривой заключается в том, что вращающийся эксцентрик, профиль которого очерчен по улитке Паскаля (l > 2a), будет заставлять совершать гармонические колебания стержень,
скользящий по профилю эксцентрика. Розы Впервые исследованием роз занимался итальянский геометр Гвидо Гранди. Полная теория этих кривых была изложена им в сочинении «Flores geometrici ex rhodanearum et claelarum descriptione resultantes», изданном в 1728 году. В полярных координатах уравнение для роз записывается в виде ρ = a sin k ϕ или в виде ρ = a cos k ϕ ; где a и k – постоянные положительные числа. 43
Обратимся к исследованию формы роз. Поскольку правая часть уравнения не может превышать величины a, то и вся роза, очевидно, умещается внутри круга радиусом a. Количество же лепестков розы зависит от величины модуля k: 1. Если модуль k – целое число, то роза состоит из k лепестков при нечетном k, и из 2k лепестков при k четном.
m n (n >1), то роза состоит
2. Если модуль k – рациональное число, равное
из m лепестков в случае, когда оба числа m
и
n нечетные, и из 2m
лепестков, если одно из этих чисел является четным. При этом, в отличие от первого случая, каждый следующий лепесток будет частично перекрывать предыдущий. 3. Если модуль k – иррациональное число, то роза состоит из бесчисленного
множества лепестков, частично накладывающихся друг на друга. Математическим исследованием формы цветов и листьев занимался также Хабеннихт – геометр 19 столетия. Им был получен целый ряд уравнений,
которые
с
весьма
хорошим
приближением
выражали
аналитически формы листьев клена, щавеля, ивы и т. д. Вот некоторые из этих уравнений: ρ = 4 (1 + cos 3ϕ) + 4 sin 2 3ϕ ρ = 4 (1 + cos 3ϕ ) − 4 sin 2 3ϕ
– лист щавеля; – лист трилистника;
ρ = 3 (1 + cos2 ϕ ) + 2 cos ϕ + sin2 ϕ − 2 sin2 3 ϕ⋅cos 4
Колосья
ϕ – лист плюща; 2
Ближайшими родственниками роз являются кривые, имеющие
уравнения вида ρ=
a sink φ
,
или
44
ρ=
a ; cosk φ
где k – любое рациональное число. Кривые состоят из k конгруэнтных гиперболических ветвей при целом и нечетном значении модуля k, и из 2k ветвей при k целом четном. Ввиду сходства каждой ветви с абрисом колоса ячменя, эти кривые называют «колосьями». К колосьям относятся некоторые известные кривые: ρ=
ρ=
ρ=
a – крестообразная кривая; sin2φ a
– трисектриса Маклорена;
φ cos 3 a cos 3φ
– трисектриса Лоншама.
Циклоидальные кривые Эти кривые могут быть получены в результате следующего
процесса:
представим
себе,
что
некоторая
окружность
(называемая «производящей») катится без проскальзывания по профилю другой (неподвижной) окружности. Если на производящей окружности зафиксировать некоторую точку, то кривая, вычерчиваемя этой точкой в процессе движения, и будет называться циклоидальной. Получаемые кривые подразделяются на эпициклоиды и гипоциклоиды в зависимости от того, катится ли производящий круг с внешней или с внутренней стороны неподвижного круга, соответственно. Если обозначить радиус неподвижного круга как R, радиус катящегося круга как r, а также ввести параметр |m| =
r , то уравнения циклоидальных R
кривых удобно представить в параметрическом виде: 45
x = ( R + m R ) cos m t − mR cos ( t + m t ), y = ( R + m R ) sin m t − mR sin ( t + m t ) При
m>0
эти
уравнения выразят эпициклоиду,
при
m l – в этом случае овал будет состоять из двух замкнутых линий.
47
3.
a=l
– полярное уравнение выражает лемнискату Бернулли,
которая является, таким образом, частным случаем овалов Кассини. В качестве примера из области физики можно привести тот факт, что два параллельных тока, текущие по бесконечно длинным проводникам, создают в
плоскости,
к
ним
перпендикулярной,
потенциальное
поле,
эквипотенциальные линии которого представляют собой семейство овалов Кассини. Фокусы этого семейства находятся в точках пересечения проводников с рассматриваемой плоскостью. Спираль Архимеда Может быть определена как траектория точки, участвующей одновременно в двух равномерных движениях, одно из которых совершается вдоль прямой, а другое – по окружности. Изобретение этой
спирали
приписывается,
по
некоторым
источникам,
Конону
Сомосскому, однако свойства ее были изучены Архимедом. Уравнение кривой в декартовом представлении:
x 2 + y 2 = a arctg
y ; x
в полярных координатах: ρ=aϕ Логарифмическая спираль В истории математики
логарифмическая
спираль упоминается впервые в письме Декарта к Мерсену в 1638 г., в котором Декарт определяет новую спираль как линию, отношение длины дуги которой к радиус-вектору является постоянным. Независимо от Декарта логарифмическая спираль была открыта Торичелли. Особенно много внимания логарифмической спирали уделил Я. Бернулли, назвавший ее sp ir a mi rab i li s – дивная спираль. Само же название логарифмической спирали было предложено Вариньоном.
48
Уравнение кривой в полярных координатах: ρ=a
ϕ ctga
(a > 0)
Логарифмическая спираль имеет многочисленные применения в технике, основанные на свойстве этой кривой пересекать все свои радиус-векторы под одним и тем же углом. Имеет эта спираль проявления и в природе, в частности, по ней очерчены раковины некоторых моллюсков.
Гиперболическая спираль
ρ=
a ϕ
По мере роста ϕ спираль устремляется к полюсу, делая вокруг него бесконечное множество витков, расстояние между которыми убывает. Спираль Ферма
ρ= a ϕ
Любопытное отличие спирали Ферма от других спиралей заключается в том, что расстояние между ее витками неограниченно убывает по мере удаления от полюса. Спираль Галилея
ρ = aϕ2 − l
(l ≥ 0)
Спираль Галилея вошла в историю математики в 17 столетии в связи с постановкой проблемы определения формы линии, по которой должна двигаться свободно падающая в области экватора точка, если бы она не обладала начальной скоростью, сообщаемой ей вращением земного шара.
Спираль «жезл»
ρ=
a ϕ
Еще одна спираль. По форме напоминает жезл египетских фараонов.
49
Фигуры Лиссажу Представляют собой траекторию точки, совершающей одновременно
два
взаимноперпендикулярных
гармонических направлениях.
колебания Впервые
в были
двух изучены
Ж. Лиссажу. Уравнения фигур Лиссажу в параметрическом представлении: x = sin ( ω1 t + ϕ 1); y = cos ( ω2 t + ϕ 2)
ПОСТРОЕНИЕ ПЛОСКОЙ ПРОЕКЦИИ Т Р Е Х МЕРНЫХ ОБЪЕКТОВ Предположим, что перед нами стоит задача отображения на экране графиков 3-х мерных функций, гистограмм или траекторий. Для решения задач
подобного
типа
главное – определить
законы
преобразования
декартовых трехмерных координат точки (x, y, z) в координаты Xэкр и Yэкр двухмерной системы координат, связанной с экраном монитора. Прежде всего, необходимо задать взаимное расположение трехмерной и двухмерной систем координат – иначе говоря, точку наблюдения. Как это сделать? Пусть, для начала, трехмерная декартова система координат, в которой решается задача, расположена относительно наблюдателя (плоскости экрана), как это показано на рисунке A слева: ось направо, ось
x направлена горизонтально слева
y – вертикально снизу вверх, а ось z направлена на наблюдателя
перпендикулярно плоскости экрана. На рисунке A справа показан вид на эту же систему со стороны положительной ветви оси x: ось y направлена вверх, а ось
z – справа налево.
Координаты (xp, yp, zp) определяют положение произвольной точки p.
50
Повернем систему на угол θz относительно оси
z (см. рисунок B, слева) и
получим закон преобразования координат точки при переходе от осей x, y, к новым осям
x', y', z': x ′p = x p ⋅ cos(θ z ) + y p ⋅ sin(θ z ) ; y ′p = − x p ⋅ sin(θ z ) + y p ⋅ cos(θ z ) ; z ′p = z p
51
z
Ось
z' совпадает с осью z , и на рисунке B слева мы ее по-прежнему не
видим. На рисунке B, справа, представлен вид на систему x', y', z' со стороны положительной ветви оси оси
x' на угол θx.
x'. Далее мы повернем систему координат вокруг
Закон перехода к новым осям
x", y", z" иллюстрирует
рисунок C.
x ′p′ = x ′p ; y ′p′ = y ′p ⋅ cos(θ x ) + z ′p ⋅ sin(θ x ) ; z ′p′ = − y ′p ⋅ sin(θ x ) + z ′p ⋅ cos(θ x ) . Рассмотрев рисунок можно заметить, что при последнем повороте возникла проекция оси z на плоскость наблюдения (x",
y"), причем эта
проекция всегда вертикальна. Выражение же для z" далее использовать не будем, так как ось z" перепендикулярна плоскости наблюдения. В итоге, преобразование
x, y, z координат произвольной точки к ее экранным
координатам при описанной процедуре поворота системы координат на углы θz и θx запишется как:
X экр ( x, y , z ) = x ⋅ cos ( θ z ) + y ⋅ sin ( θ z ) ; Yэкр ( x, y , z ) = [− x ⋅ sin ( θ z ) + y ⋅ cos ( θ z )]⋅ cos ( θ x ) + z ⋅ sin ( θ x ) . Таким образом, мы выполнили задачу и получили формулы для пересчета координат точки из трехмерной системы координат в экранную. Пусть
нашей
следующей
задачей
является
построение
графика
произвольной явно заданной функции двух переменных: z = f (x, y). Вопервых, мы должны задать диапазоны изменения переменных следует
задать
сетку
построения
графика – диапазоны
x и y. Далее изменения
переменных x и y разбиваются на фиксированное число отрезков 52
(интервалов). Значения функции
z = f ( x, y) мы будем вычислять (а также и
рисовать) только в у з ла х сетки, для ограниченного набора пар переменных x и
y. Организуя цикл по всем узлам заданной сетки, вычисляем диапазон
изменения значений функции. Заданный получившимися тремя диапазонами элемент
пространства
является,
очевидно,
параллелепипедом.
Задав
произвольно два угла θz и θx, выполним преобразования координат из трехмерных в двухмерные экранные, согласно приведенным выше формулам, для всех восьми вершин параллелепипеда, ограниченного диапазонами (xmin,
xmax), (ymin, ymax), (zmin, zmax). Преобразования координат к Xэкр (x, y, z) и Yэкр (x, y, z) удобно оформить в виде отдельных подпрограмм. Среди получившихся восьми пар плоских координат вершин параллелепипеда, выберем максимальные и минимальные значения
Xэкр и Yэкр – размер
плоской проекции в новой системе координат. Чтобы нарисовать оси трехмерной системы координат на экране монитора, введем дополнительные масштабирующие множители ScaleX и ScaleY для сжатия или растяжения изображения по
Xэкр и Yэкр координатам, чтобы уместить его в экран (или
выбранную область экрана), с одновременным преобразованием координат к целому типу переменных. Нарисовав оси, приступаем к выводу собственно графика функции. Для этого организуем вложенные циклы по x и y переменным в заданных пределах и с шагами
dx и dy, определяющими выбранную для вывода
графика функции сетку. В каждой точке сетки ( xi , yi ) вычисляем zi = f (xi, yi) и переводим получившиеся трехмерные координаты в экранные
Xэкр и Yэкр.
То же самое делаем для точек (xi + dx, yi), (xi + dx, yi + dy), (xi, получаем
yi + dy) и
Xэкр и Yэкр координаты четырех соседних точек графика. По зтим
координатам, при помощи библиотечной функции 53
FillPoly,
строим
четырехугольник и переходим к следующей точке. В качестве примера, на рисунке
показан
график
функции
f ( x, y ) =
sin ( r ) , r
построенный
программой Cube, текст которой приведен ниже.
Вариант программы Program Cube; Uses Crt, Graph; function f(x,y:real): real; {Функция, которую будем рисовать} var r: real; begin r:= sqrt(x*x + y*y); if r=0 then f:=10 else f:=10*sin(r)/r; end; { Свободные поля по периметру экрана, в пикселах } const xoff=40; yoff=40; Var {глобальные переменные } Gd,Gm: integer; RotX,RotZ: real; Xlo,Xst,Xhi,Xd,Xt: real; Ylo,Yst,Yhi,Yd,Yt: real; Zlo,Zst,Zhi,Zd,Zt: real; Xmin,Xmax,Ymin,Ymax: real; ScaleX,ScaleY: real; function X3d(x,y,z:real):real; {горизонтальная проекция точки (x,y,z)} begin
54
X3d := x*cos(RotZ) + y*sin(RotZ); end; function Y3d(x,y,z:real):real; {вертикальная проекция точки (x,y,z)} begin Y3d := (-x*sin(RotZ) + y*cos(RotZ))*cos(RotX) + z*sin(RotX); end; function X3(cx,cy,cz:integer):real;{горизонтальная проекция вершины куба} begin X3 := X3d(Xd*cx,Yd*cy,Zd*cz); end; function Y3(cx,cy,cz:integer):real; {вертикальная проекция вершины куба} begin Y3 := Y3d(Xd*cx,Yd*cy,Zd*cz); end; function ScreenX(x:real):integer; {реальный X -> экранный X} begin ScreenX := xoff + round((x - Xmin)/scalex); end; function ScreenY(y:real):integer; {реальный Y -> экранный Y} begin ScreenY := GetMaxY - yoff - round((y - Ymin)/scaley); end; procedure line3d(a,b,c,d:real); {Проекция 3d-линии на экран} begin line(ScreenX(a),ScreenY(b),ScreenX(c),ScreenY(d)); end; procedure Get_Plot_Sizes; {Определение масштабов } var ctx,cty,ctz: integer; X,Y: real; begin {Определение диапазонов графика по x,y,z осям} Zlo:= f(Xlo,Ylo); Zhi:= Zlo; Xt:= Xlo; while Xt < Xhi do begin Xt:= Xt + Xst; Yt:= Ylo; while Yt < Yhi do begin Yt:= Yt + Yst; Zt:= f(Xt,Yt); if Zt > Zhi then Zhi:= Zt else if Zt < Zlo then Zlo:= Zt; end; end; Xd:= Xhi - Xlo; Yd:= Yhi-Ylo; Zd:= Zhi - Zlo; {Определение масштабов для вывода изображения на экран } Xmin:= X3(0,0,0); Xmax:= Xmin; Ymin:= Y3(0,0,0); Ymax:= Ymin; for ctx:= 0 to 1 do for cty:= 0 to 1 do
55
for ctz:= 0 to 1 do begin X:= X3(ctx,cty,ctz); if X > Xmax then Xmax:=X else if X < Xmin then Xmin:= X; Y:= Y3(ctx,cty,ctz); if Y > Ymax then Ymax:= Y else if Y < Ymin then Ymin:= Y; end; ScaleX:= (Xmax - Xmin)/(GetMaxX - xoff*2); ScaleY:= (Ymax - Ymin)/(GetMaxY - yoff*2); end; Procedure Plotlines; {Собственно рисование функции 4-угольниками } var p: array[1..4] of PointType; begin Xt:= Xlo; while Xt < Xhi do begin Yt:= Ylo; while Yt < Yhi do begin p[1].x:= ScreenX(X3d(Xt - Xlo, Yt - Ylo, f(Xt,Yt) - Zlo)); p[1].y:= ScreenY(Y3d(Xt - Xlo, Yt - Ylo, f(Xt,Yt) - Zlo)); p[2].x:= ScreenX(X3d(Xt-Xlo, Yt-Ylo+Yst, f(Xt,Yt+Yst)-Zlo)); p[2].y:= ScreenY(Y3d(Xt-Xlo, Yt-Ylo+Yst, f(Xt,Yt+Yst)-Zlo)); p[3].x:= ScreenX(X3d(Xt-Xlo + Xst, Yt-Ylo+Yst, f(Xt+Xst, Yt+Yst)-Zlo)); p[3].y:= ScreenY(Y3d(Xt-Xlo+Xst, Yt-Ylo+Yst, f(Xt+Xst, Yt+Yst)-Zlo)); p[4].x:= ScreenX(X3d(Xt-Xlo+Xst, Yt-Ylo,f(Xt + Xst,Yt)-Zlo)); p[4].y:= ScreenY(Y3d(Xt-Xlo+Xst, Yt- Ylo,f(Xt + Xst,Yt)-Zlo)); FillPoly(4,p); Yt:=Yt + Yst; end; Xt:=Xt + Xst; end; end; begin DetectGraph(gd,gm); InitGraph (gd,gm,''); if GraphResult grok then Halt(1); RotX:= 30; {углы наблюдения, градусы} RotZ:= 60; RotX:= RotX*Pi/180; RotZ:= RotZ*Pi/180; {углы наблюдения, радианы} Xlo:= -10; Xst:= 0.25; Xhi:= 10; {диапазон и сетка по X} Ylo:= -10; Yst:= 0.25; Yhi:= 10; {диапазон и сетка по Y} Setfillstyle(1,Black); {стиль для FillPoly} Setcolor(LightBlue); Rectangle(0,0,GetMaxX,GetMaxY); {рамка} Get_Plot_Sizes; {масштабы} Setcolor(White); {цвет для осей} line3d (X3(0,0,0), Y3(0,0,0), X3(0,0,1), Y3(0,0,1) ); {оси} line3d (X3(0,0,0), Y3(0,0,0), X3(0,1,0), Y3(0,1,0) ); line3d (X3(0,0,0), Y3(0,0,0), X3(1,0,0), Y3(1,0,0) ); line3d (X3(1,1,1), Y3(1,1,1), X3(1,1,0), Y3(1,1,0) );
56
line3d (X3(1,1,1), Y3(1,1,1), X3(0,1,1), Y3(0,1,1) ); line3d (X3(1,0,0), Y3(1,0,0), X3(1,1,0), Y3(1,1,0) ); line3d (X3(0,1,0), Y3(0,1,0), X3(1,1,0), Y3(1,1,0) ); line3d (X3(0,1,0), Y3(0,1,0), X3(0,1,1), Y3(0,1,1) ); line3d (X3(0,0,1), Y3(0,0,1), X3(0,1,1), Y3(0,1,1) ); SetColor(Yellow); Plotlines; {рисуем функцию} SetColor(White); line3d(X3(1,1,1),Y3(1,1,1),X3(1,0,1),Y3(1,0,1));{еще оси } line3d(X3(1,0,0), Y3(1,0,0), X3(1,0,1), Y3(1,0,1) ); line3d(X3(0,0,1), Y3(0,0,1), X3(1,0,1), Y3(1,0,1) ); ReadKey; CloseGraph; end.
Задачи на построение трехмерных объектов. Задача 1. Построить график функции, заданной явно: а.
x2 y2 − = 2z p q
( гиперболический параболоид; p, q > 0 )
б.
x2 y2 + = 2z p q
( эллиптический параболоид; p, q > 0 )
Задача 2. Построить график функции, заданной параметрически: а.
x = a u cos v , y = b u sin v ,
z = cu
(a, b – константы; u, v – изменяемые параметры) б.
x = a ch u ⋅ cos v ,
x = b ch u ⋅ sin v , z = c sh u
в.
x=
x = q u sin v ,
p u cos v ,
z=u
u 2
(эллиптический параболоид; p, q > 0 )
Задача 3. Построить сетку параллелей и меридианов на поверхности Земли.
57
РЕКОМЕНДУЕМАЯ ЛИТЕРАТУРА 1.
Е. А. Зуев. Язык программирования Turbo Pascal 6.0. М., «Унитех», 1992.
2.
В. В. Фаронов. Основы Турбо Паскаля. М., «НВТУ-Фесто Дидактик», 1992.
3.
А. Епанешников, В. Епанешников.
Программирование в среде Turbo
Pascal 7.0. М., «Диалог-МИФИ», 1993. 4.
А. И. Маркушевич. Замечательные кривые. М., «Наука», 1978.
5.
А. А. Савелов. Плоские кривые. М., 1960.
6.
Г. Н. Берман. Циклоида (об одной замечательной кривой линии и некоторых других, с ней связанных). М., «Наука», 1980.
58