Язык программирования
В языке программирования существует специальный раздел start, предназначенный для выполнения инициализационного кода перед циклом формирования кадров (код, вне раздела start исполняется при формировании каждого кадра). Обычно в разделе start объявляют и настраивают глобальные переменные, формируют параметры начальной стадии анимации. В разделе start нельзя описывать фигуры и модели из них. Однако, в разделе start обязательно необходимо включать модули, содержащие инициализационный код, причем без параметров, с индексами, которые используются при покадровом использовании. Также в разделе start описывают параметры сцены. В теле модуля может быть несколько разделов start или не одного.
Пример:
start {
<инициализационный код>
}
<покадровый код>
int – целое 32 бита
dbl – вещественное двойной точности 64 бита
vec - вектор, запись содержащая вещественные поля типа dbl – (x,y,z)
log – логический тип, значения true и false
chr - символьный тип данных
Переменные в языке программирования делятся на 2 вида – локальные и глобальные. Глобальные обычно объявляются и настраиваются в разделе start и далее используются в вычислениях в каждом кадре, предназначены для обозначения стадии анимации. Локальные переменные объявлявляются и используются для локальных расчетов и уничтожаюся после выполнения кода, в котором были объявлены.
Декларация переменной имеет следующую структуру:
<обозначение типа переменной> <имя переменной> [=<выражение соответствующего типа>]
<обозначение типа переменной>:
- int, dbl, vec, log, chr – для локальных переменных
- gint, gdbl, gvec, glog, gchr – для глобальных переменных
<имя переменной> -строка из латинских символов или цифр, начинается с букв. Имя переменной не должно совпадать со служебными словами. Имя переменной не должно объявляться несколько раз в одном модуле, будь то локальная или глобальная переменная.
<Выражение соответствующего типа> - объявление переменной можно совместить с оператором присвоения. В выражении, значение которого присваивается переменной, не должна использоваться объявляемая переменная.
Помимо декларации отдельных переменных, можно объявить переменные – массивы из значений любого типа. Объявление выглядит так:
<тип> <имя>”[ ]” [<=выражение типа массив>]
Отличие от обычного объявления только в том, что после имени нужно указать квадратные скобки.
Индексация массива начинается от 0. Массивы являются динамическими. Их размер можно задать во время исполнения программы (явным или неявным образом).
<Имя переменной> = <выражение соответствующего типа>
В качестве самостоятельной переменной, которой присваивается значение выражения, может выступать координата вектора, которая обозначается так: v.x, v.y, v.z. Такое обозначение можно использовать во всех конструкциях языка, за исключением объявления (объявить координату вектора отдельно нельзя, только вектор целиком).
Пример:
start {
gint i=0
}
dbl a
a=i*10
vec v=(0,-1,0)
v.x =v.y-a
chr c="@"
log b=(a=0)
Пример неправильного объявления:
start {
dbl d
}
vec v=v+v
dbl a.x=d
Примечание:
- Переменные объявленные в модуле относятся только к своему модулю. Вложенные модули могут содержать переменные, в т.ч. глобальные, у которых такие же имена.
- В качестве переменной, в которую можно присвоить значение может выступать массив целиком, отдельный элемент массива любого типа. При обращении к элементу массива, после имени массива в квадратных скобках указывается индекс элемента. Если при обращении к элементу указан индекс выходящий за пределы массива, компилятор выдает ошибку. Если при присвоении значения элементу массива указан индекс выходящий за пределы массива, то компилятор автоматически выделяет необходимый объем памяти (с копированием)
Пример:
dbl a[ ] = (0.5, 1.5, 2.5) | // объявление и инициализация массива значениями3мя |
a[3] = 3.5 | // присвоение в 3-й элемент массива значения, длина увеличится сама! |
vec b[] = ( (a[0],a[1],a[2]), (-1,0,0) ) | // объявление и инициализация массива 2мя значениями |
b[0].x=b[1].y +0.5 | // присвоение значения координате вектора 0-го элемента массива |
a=a+b+5 | // настройка длины массива |
chr ca[]="super3d" | // присвоение значений в массив символов - (строковый тип) |
Примечание:
Обратите внимание, что указание имени массива без квадратных скобок в выражении означает длину массива. Если с левой стороны оператора присвоения указано только имя массива (без []), то это означает настройку длины массива, при этом происходит перевыделение памяти, сопровождающееся копированием данных из прежнего массива.
Выражения представляют собой комбинацию операций с переменными или непосредственными значениями. Тип выражения должен быть таким же, что и переменная которой присваивается значение выражения. Исключение – выражение типа int и dbl, их значения можно присвоить как целой, так и вещественной переменной. Присваивая значение целой переменной, дробная часть значения выражения удаляется.
В выражениях численных типов (int, dbl) используются следующие операции:
+ , -, *, / - сложение, вычитание, умножение, деление. Причем умножение и деление имеет высший приоритет перед сложением и вычитанием, изменить приоритет можно с помощью скобок, например (a+b)*c = a*c + b*c, a+b*c = a+b*c, в качестве операндов могут выступать значения, переменные,функции, другие выражения.
Эти операции также допустимы с обозначениями длины массивов.
В выражениях векторного типа используются следующие операции:
+,-,* или / - сложение, вычитание и масштабирование. В качестве операндов могут выступать векторные значения, векторные переменные, векторные выражения, векторные функции.
Исключение составляет масштабирование, в котором первый операнд имеет векторный тип, а второй, третий и т.д – вещественный тип.
Пример:
vec a = (0,1,0)
vec b = (1,0,1)
a=a+b*|a|/|b|
В последнем выражении к вектору a прибавляется векторное выражени,в котором вектор b масштабируется (умножается на длину вектора a и делится на длину вектора b)
В логических выражениях используются следующие операции:
<,>,<=,>=,=,<> - для сравнения численных выражений
=,<> - для сравнения векторных выражений
+, -, * - операции OR, XOR, AND, операндами которых являются выражения логического типа, причем операция + имеет низший приоритет по сравнению с – или *
Примечание:
Операции сравнения имеют низший приоритет по сравнению с другими операциями, поэтому сравниваемые выражения рекомендуется брать в скобки, например:
log l=( (5+a)=(10-b) ) * (a=b)
Массивы и символы пока участвовать в сравнениях не могут
В выражениях типа массив, кроме символьного, можно использовать:
- изображения массива (в круглых скобках указывается через запятую значения элементов массива соответствующего типа)
- переменные типа массив соответствующего типа (указывается имя массива и квадратные скобки)
- операцию объединения “+” массивов
Пример:
vec a[ ] = ((0,1,2), (2,1,0)) | // создает массив из двух элементов векторного типа |
vec b[ ] = (a[0], (a[1].z, a[1].y, a[1].x) ) + a[ ] | // получится массив из 4-х элементов |
Примечание:
скобки в выражениях типа массив использовать можно только для обозначения списка элементов массива. Для изменения приоритета операции их использовать нельзя, да и бессмысленно, так как операция всего одна - объединение.
В выражениях типа символьный массив, можно использовать:
- Изображение символьного массива - строка символов в двойных кавычках.
- Переменные типа символьный массив и типа символ
- Строковые и символьные функции
- Операцию объединения “+” массивов
Пример:
chr threed[]="3d"
chr plus="+"
chr c[]="super"+threed+plus+chr(33)
Результат: c[]="super3d+!"
If <логическое выражение> then {
<языковые конструкции, выполняемые в случае выполнения условия>
}
[else {
<языковые конструкции, выполняемые в случае не выполнения условия>
}]
Условие представляет собой логическое выражение, принимающее утвердительное или отрицательное значение.
Блок else можно опустить, если он не нужен.
Оператор FOR:
for <переменная целого типа> = <начальное значение> to или downto <конечное значение> {
<операторы в теле цикла>
}
<начальное значение> и <конечное значение> - численные выражения, в процессе выполнения цикла <переменная целого типа> принимает значения в этом диапазоне.
Если после <начального значения> указано служебное слово ‘to’ то переменная цикла увеличивается в конце итерации, если же указано ‘downto’, то переменная уменьшается.
Если переменная цикла не объявлена явным образом, то она объявляется автоматически как локальное целое.
Оператор Repeat:
repeat {
<операторы в теле цикла>
} until <логическое выражение>
Цикл будет повторяться до тех пор пока <логическое выражение> не примет утвердительное значение. Поэтому цикл выполнится по крайней мере один раз.
Оператор While:
while <логическое выражение> {
<операторы в теле цикла>
}
Цикл будет выполняться если <логическое выражение> принимает утвердительное значение.
Цикл может не выполниться ни разу.
Операторы досрочного окончания итерации и выхода в цикле
В языке предусмотрены два оператора: continue и break, результатом их выполнения становится досрочное завершение итерации цикла, однако оператор break также прекращает выполнение цикла, внутри которого этот оператор использовался.
Функции, константы и специальные операции
В языке предусмотрена всего одна константа – это число пи, его обозначение ‘pi’, используйте его чтобы перевести градусы в радианы.
В языке существуют специальные переменные, которые можно только считывать: ‘nobjects’, ‘nmodels’ – обозначают текущее число описанных объектов и моделей. Значения этих переменных меняются во время интерпритации. Нельзя забывать, что вначале модуля они могут быть больше 0 (если данный модуль включается в другой модуль).
Численные функции:
rnd(целое) – генерация случайного целого числа в пределах указанного диапазона-1
sin(), cos() – синус и косинус, параметрами которого выступают вещественные (в радианах)
atan() – арктангенс, параметр - вещественное, результат в радианах (-pi/2 до pi/2)
exp(), ln(), sqrt() – экспонирование, натуральный логарифм, квадратный корень (при использованиии этих функций следует помнить о требованиях к параметрам функций)
sqr() – возведение в квадрат значения параметра
abs() - положительное значение вещественного аргумента
Аргументами функций могут выступать выражения численного типа.
Векторные функции и операции:
‘-‘ - унарное отрицание - инверсия направления вектора.
|вектор| - взятие модуля вектора – длина вектора
|вектор|^ - взятие квадрата модуля вектора – квадрат длины вектора (вычисляется быстрее чем ||)
(вектор1, вектор2) – скалярное произведение векторов, результатом этой операции является вещественное значение
[вектор 1, вектор2] – векторное произведение векторов, результатом этой операции является векторное значение.
Аргументами функций и операций могут выступать выражения векторного типа.
Символьные и строковые функции:
chr(int) - возвращает символ по ascii коду, результат функции можно присвоить символу или массиву символов
itos(int) - возвращает строковое изображение целого числа, если аргумент вещественный, то он округляется
localtime - возвращает дату-время "число-месяц-год час:минута:секунда:миллисекунда"
Из тела подпрограммы видны только:
1.спец. переменная result
2.параметры
3.глобальные переменные
4.переменные, созданные в теле подпрограммы
Дополнения к языку описания (использование переменных)
1. В изображении вектора (x,y,z) можно использовать не только вещественные числа, но и переменные с указанием унарных операций – и +. Однако выражения в качестве координат использовать пока нельзя. (Это относится как к описанию фигур, так и моделей)Особенности программирования и типичные ошибки
В теле программы можно почти везде использовать коментарии, которые указываются после символов ‘//’ или ‘#’, после этих символов интерпретатор не обрабатывает строку.
В языке программирования предусмотрены простейшие средства отладки – точки останова: для того чтобы остановить интерпретацию перед выполнением определенной строки кода, поставьте в начало этой строки тильду “ ` ” (где буква Ё), в окне отладки будут выведены значения всех переменных и список сформированных объектов/моделей на данный момент.
Пример:
Чтобы продолжить выполнение программы, нажмите Ctrl-F9 (пункт “продолжить” в меню “Выполнить”).
Также возможно досрочно остановить выполнение кода.
При запуске анимации (редеринге) интерпретатор считывает код прямо из окна основного модуля, а не из файла.
Однако, включаемые модули, если оказались окне редактора в результате ошибки,
следует обязательно сохранять перед запуском, так их интерпретатор считывает только из файла.