&НаКлиенте
Процедура ПриОткрытии(Отказ)
НарисоватьРамку(ТабДок1, 2, 2, 200, 150);
НарисоватьРамку(ТабДок1, 4, 4, 196, 146);
НарисоватьПтицу(ТабДок1, 30, 30, 2, 0);
НарисоватьПтицу(ТабДок1, 100, 30, 1.5, 45);
НарисоватьПтицу(ТабДок1, 160, 30, 1, -60);
НарисоватьЗвезду(ТабДок1, 30, 70, 3, 1, 45);
НарисоватьЗвезду(ТабДок1, 100, 70, 2, 2, 0);
НарисоватьЗвезду(ТабДок1, 170, 70, 1.5, 1, -60);
НарисоватьРыбу(ТабДок1, 30, 110, 1,2, 45);
НарисоватьРыбу(ТабДок1, 100, 105, 1.5, 1.5, -30);
НарисоватьРыбу(ТабДок1, 160, 110, 2, 1, 0);
Для Счетчик = 1 по 10 Цикл
НарисоватьСтрелку(ТабДок1, 45 + Счетчик * 10, 145, Счетчик * 20-10, 125, Счетчик + 5, 8, Счетчик/2);
КонецЦикла;
КонецПроцедуры
#Область Пользовательские_функции
// Процедура - Нарисовать стрелку
//
// Параметры:
// ТабДок - ТабличныйДокумент -
// НачалоX - Число - X-координата начала
// НачалоY - Число - Y-координата начала
// КонецX - Число - X-координата конца
// КонецY - Число - Y-координата конца
// ДлинаНаконечника - Число - Длина наконечника
// ШиринаНаконечника - Число - Ширина наконечника
// Заострение - Число - Насколько края наконечника отведены назад
//
&НаКлиенте
Процедура НарисоватьСтрелку(ТабДок, НачалоX, НачалоY, КонецX, КонецY, ДлинаНаконечника, ШиринаНаконечника, Заострение = 0)
Начало = СоздатьВектор(НачалоX, НачалоY);
Конец = СоздатьВектор(КонецX, КонецY);
// Найдем точку основания наконечника
ВекторСтрелки = РазницаВекторов(Конец, Начало);
Длина = ДлинаВектора(ВекторСтрелки);
ТочкаОснованияНаконечника = ВекторLerp(Конец, Начало, ДлинаНаконечника/Длина); // Основание наконечника
// Наконечник
ПространствоНаконечника = СоздатьПространствоПоВекторам(ТочкаОснованияНаконечника, РазницаВекторов(Конец, ТочкаОснованияНаконечника));
// В данном пространстве единица по обеим координатам соответствует длине наконечника
КоэффициентШирины = ШиринаНаконечника/ДлинаНаконечника;
КоэффициентЗаострения = Заострение/ДлинаНаконечника;
ТочкиНаконечника = Новый Массив;
ТочкиНаконечника.Добавить(СоздатьВектор(-0.5 * КоэффициентШирины, -КоэффициентЗаострения));
ТочкиНаконечника.Добавить(СоздатьВектор(0, 1));
ТочкиНаконечника.Добавить(СоздатьВектор(0.5* КоэффициентШирины, -КоэффициентЗаострения));
ТочкиНаконечника.Добавить(СоздатьВектор(0,0));
Ломанная(ТабДок, ТочкиНаконечника, Истина, ПространствоНаконечника );
// Линия
ПространствоЛинии = СоздатьПространствоПоВекторам(Начало, РазницаВекторов(ТочкаОснованияНаконечника, Начало));
Линия(ТабДок, СоздатьВектор(0,0), СоздатьВектор(0, 1), ПространствоЛинии);
КонецПроцедуры
// Процедура - Нарисовать прямоугольник
//
// Параметры:
// ТабДок - ТабличныйДокумент -
// ЦентрX - Число - X-Координата центра
// ЦентрY - Число - Y-Координата центра
// Ширина - Число -
// Высота - Число -
// Поворот - Число - Угол поворота в градусах
//
&НаКлиенте
Процедура НарисоватьПрямоугольник(ТабДок, ЦентрX, ЦентрY, Ширина, Высота, Поворот)
Пространство = СоздатьПространствоПоУглу(СоздатьВектор(ЦентрX, ЦентрY), Ширина, Высота, Поворот);
Точки = Новый Массив;
Точки.Добавить(СоздатьВектор(-0.5,-0.5));
Точки.Добавить(СоздатьВектор(-0.5,0.5));
Точки.Добавить(СоздатьВектор(0.5,0.5));
Точки.Добавить(СоздатьВектор(0.5,-0.5));
Ломанная(ТабДок, Точки, Истина, Пространство);
КонецПроцедуры
// Процедура - Нарисовать рамку
//
// Параметры:
// ТабДок - Табличный документ -
// Лево - число
// Верх - число
// Ширина - число
// Высота - число
//
&НаКлиенте
Процедура НарисоватьРамку(ТабДок, Лево, Верх, Ширина, Высота)
Пространство = СоздатьПространствоПоВекторам(СоздатьВектор(Лево, Верх), СоздатьВектор(0, Высота), СоздатьВектор(Ширина, 0));
Точки = ТочкиИзСтроки("0.1; 0; 0.9; 0; 0.94; 0.06; 1; 0.1; 1; 0.9; 0.94; 0.94 ; 0.9; 1; 0.1; 1; 0.06; 0.94; 0; 0.9; 0; 0.1; 0.06; 0.06");
Ломанная(ТабДок, Точки, Истина, Пространство);
КонецПроцедуры
// Процедура - Нарисовать птицу
//
// Параметры:
// ТабДок - ТабличныйДокумент -
// ЦентрX - Число - Координата X центра рисунка
// ЦентрY - Число - Координата Y центра рисунка
// Размер - Число - Размер рисунка (относительно базового)
// Поворот - Число - Поворот в градусах
//
&НаКлиенте
Процедура НарисоватьПтицу(ТабДок, ЦентрX, ЦентрY, Размер, Поворот)
Пространство = СоздатьПространствоПоУглу(СоздатьВектор(ЦентрX, ЦентрY), Размер, -Размер, Поворот);
Точки = ТочкиИзСтроки("-4;8;-5;7;-5;6;-6;5;-5;5;-5;4;-7;0;-5;-5;-1;-7;3;-7;9;-2;13;-2;14;-1;6;1;8;4;15;7;3;8;2;7;0;3;-1;3;-2;4;-1;6;-2;8;");
Ломанная(ТабДок, Точки, Истина, Пространство);
КонецПроцедуры
// Процедура - Нарисовать звезду
//
// Параметры:
// ТабДок - Табличный документ -
// ЦентрX - Число
// ЦентрY - Число
// Ширина - Ширина рисунка (относительно базового) - число
// Высота - Высота рисунка (относительно базового) - число
// Поворот - Поворот в градусах - Число
//
&НаКлиенте
Процедура НарисоватьЗвезду(ТабДок, ЦентрX, ЦентрY, Ширина, Высота, Поворот)
Пространство = СоздатьПространствоПоУглу(СоздатьВектор(ЦентрX, ЦентрY), Ширина, -Высота, Поворот);
Точки = ТочкиИзСтроки("-9; 2; -3; 3; 0; 8; 3; 3; 9; 2; 5; -3; 6; -9; 0; -7; -6; -9; -5; -3; -9; 2");
Ломанная(ТабДок, Точки, Ложь, Пространство);
КонецПроцедуры
// Процедура - Нарисовать рыбу
//
// Параметры:
// ТабДок - ТабличныйДокумент -
// ЦентрX - Число - Координата X центра рисунка
// ЦентрY - Число - Координата Y центра рисунка
// Ширина - Ширина рисунка (относительно базового) - число
// Высота - Высота рисунка (относительно базового) - число
// Поворот - Число - Поворот в градусах
//
&НаКлиенте
Процедура НарисоватьРыбу(ТабДок, ЦентрX, ЦентрY, Ширина, Высота, Поворот)
Пространство = СоздатьПространствоПоУглу(СоздатьВектор(ЦентрX, ЦентрY), Ширина * 5, -Высота*5, Поворот);
// Тело и жабры
Безье(ТабДок, ТочкиИзСтроки("-2; 0; -1; 1; 1; 1; 2; 0"), 10, Пространство);
Безье(ТабДок, ТочкиИзСтроки("-2; 0; -1; -1; 1; -1; 2; 0"), 10, Пространство);
Безье(ТабДок, ТочкиИзСтроки("1; 0.6; 0.4; 0; 0.4; 0; 1; -0.6"), 4, Пространство);
// Хвост и плавник
Ломанная(ТабДок, ТочкиИзСтроки("-2; 0; -3; 1; -2.5; 0; -3; -1"), Истина, Пространство);
Ломанная(ТабДок, ТочкиИзСтроки("-1; 0.6; -1.5; 1.5; 1; 0.6"), Ложь, Пространство);
// Глаз
Окружность(ТабДок, СоздатьВектор(1.4, 0), 0.1, Пространство);
КонецПроцедуры
#КонецОбласти
#Область Примитивы_для_рисования_в_пространстве
// Процедура - Линия
//
// Параметры:
// ТабДок - ТабличныйДокумент -
// Начало - Вектор - (см. СоздатьВектор(..))
// Конец - Вектор - (см. СоздатьВектор(..))
// Пространство - Матрица - (см. СоздатьМатрицу()) Матрица пространства, если не задана, рисует в координатах табличного документа -
//
&НаКлиенте
Процедура Линия(ТабДок, Начало, Конец, Пространство = Неопределено)
Если Пространство = Неопределено Тогда
прНачало = Начало;
прКонец = Конец;
Иначе
прНачало = УмножитьВекторНаМатрицу(Начало, Пространство);
прКонец = УмножитьВекторНаМатрицу(Конец, Пространство);
КонецЕсли;
Рисунок = ТабДок.Рисунки.Добавить(ТипРисункаТабличногоДокумента.Прямая);
Рисунок.Лево = прНачало[0];
Рисунок.Верх = прНачало[1];
Рисунок.Ширина = прКонец[0] - прНачало[0];
Рисунок.Высота = прКонец[1] - прНачало[1];
Рисунок.Линия = Новый Линия(ТипЛинииРисункаТабличногоДокумента.Сплошная, 2);
КонецПроцедуры
// Процедура - Ломанная
//
// Параметры:
// ТабДок - ТабличныйДокумент -
// Точки - Массив - Массив точек типа "вектор"
// Замкнуть - Булево - Соединить первую и последнюю точки
// Пространство - Матрица - (см. СоздатьМатрицу()) Матрица пространства, если не задана, рисует в координатах табличного документа
//
&НаКлиенте
Процедура Ломанная(ТабДок, Точки, Замкнуть, Пространство = Неопределено)
Для НомерТочки = 0 по Точки.Количество()-2 Цикл
Линия(ТабДок, Точки[НомерТочки], Точки[НомерТочки+1], Пространство);
КонецЦикла;
Если Замкнуть Тогда
Линия(ТабДок, Точки[Точки.Количество()-1], Точки[0], Пространство);
КонецЕсли;
КонецПроцедуры
// Процедура - Окружность
//
// Параметры:
// ТабДок - ТабличныйДокумент -
// Центр - Вектор - (см. СоздатьВектор(..)) Центр окружности
// Радиус - Число - Радиус окружности
// Пространство - Матрица - (см. СоздатьМатрицу()) Матрица пространства, если не задана, рисует в координатах табличного документа -
//
&НаКлиенте
Процедура Окружность(ТабДок, Центр, Радиус, Пространство = Неопределено)
Pi = 3.1415926535897932;
Для Счетчик = 1 по 12 Цикл
Угол1 = (Счетчик-1)/6 * Pi;
Угол2 = (Счетчик)/6 * Pi;
Точка1 = СуммаВекторов(Центр,СоздатьВектор(Cos(Угол1) * Радиус, Sin(Угол1) * Радиус));
Точка2 = СуммаВекторов(Центр,СоздатьВектор(Cos(Угол2) * Радиус, Sin(Угол2) * Радиус));
Линия(ТабДок, Точка1, Точка2, Пространство);
КонецЦикла;
КонецПроцедуры
// Процедура - Безье
// Рисует кривую безье отрезками по заданным 4 точкам.
// Параметры:
// ТабДок - ТабличныйДокумент -
// Точки - Массив - Массив точек типа вектор (см. СоздатьВектор(..)). Должен содержать 4 элемента
// КоличествоОтрезков - Число - Количество отрезков для рисования кривой
// Пространство - Матрица - (см. СоздатьМатрицу()) Матрица пространства, если не задана, рисует в координатах табличного документа -
//
&НаКлиенте
Процедура Безье(ТабДок, Точки, КоличествоОтрезков, Пространство = Неопределено)
Если Точки.Количество() <> 4 Тогда
ВызватьИсключение "Для безье нужно 4 точки";
КонецЕсли;
Если Пространство = Неопределено Тогда
p0 = Точки[0];
p1 = Точки[1];
p2 = Точки[2];
p3 = Точки[3];
Иначе
p0 = УмножитьВекторНаМатрицу(Точки[0], Пространство);
p1 = УмножитьВекторНаМатрицу(Точки[1], Пространство);
p2 = УмножитьВекторНаМатрицу(Точки[2], Пространство);
p3 = УмножитьВекторНаМатрицу(Точки[3], Пространство);
КонецЕсли;
Для Отрезок = 1 по КоличествоОтрезков Цикл
Дельта1 = (Отрезок-1)/КоличествоОтрезков;
Дельта2 = Отрезок/КоличествоОтрезков;
ТД1 = ТочкаБезье(p0, p1, p2, p3, Дельта1);
ТД2 = ТочкаБезье(p0, p1, p2, p3, Дельта2);
Рисунок = ТабДок.Рисунки.Добавить(ТипРисункаТабличногоДокумента.Прямая);
Рисунок.Лево = ТД1[0];
Рисунок.Верх = ТД1[1];
Рисунок.Ширина = ТД2[0] - ТД1[0];
Рисунок.Высота = ТД2[1] - ТД1[1];
Рисунок.Линия = Новый Линия(ТипЛинииРисункаТабличногоДокумента.Сплошная, 2);
КонецЦикла;
КонецПроцедуры
#КонецОбласти
#Область Служебные
// Функция - Создать вектор
//
// Параметры:
// x - Число -
// y - Число -
//
// Возвращаемое значение:
// Вектор - [x,y,1] - массив
//
&НаКлиенте
Функция СоздатьВектор(x=0, y=0)
Результат = Новый Массив(3);
Результат[0] = x;
Результат[1] = y;
Результат[2] = 1;
Возврат Результат;
КонецФункции
// Функция - Создать матрицу
//
// Возвращаемое значение:
// - Массив 3х3 вида:
// [1, 0, 0]
// [0, 1, 0]
// [0, 0, 1]
&НаКлиенте
Функция СоздатьМатрицу()
Результат = Новый Массив(3,3);
Для y = 0 По 2 Цикл
Для x = 0 По 2 Цикл
Результат[y][x] = ?(y = x, 1, 0);
КонецЦикла;
КонецЦикла;
Возврат Результат;
КонецФункции
// Функция - Создать пространство по векторам
//
// Параметры:
// Смещение - Вектор -
// БазисВерх - Вектор -
// БазисПраво - Вектор -
//
// Возвращаемое значение:
// - Матрица пространства
//
&НаКлиенте
Функция СоздатьПространствоПоВекторам(Смещение = Неопределено, БазисВерх = Неопределено, БазисПраво = Неопределено)
Результат = СоздатьМатрицу();
Если Смещение <> Неопределено Тогда
Результат[2][0] = Смещение[0];
Результат[2][1] = Смещение[1];
КонецЕсли;
Если БазисВерх <> Неопределено Тогда
Результат[1][0] = БазисВерх[0];
Результат[1][1] = БазисВерх[1];
Если БазисПраво <> Неопределено Тогда
Результат[0][0] = БазисПраво[0];
Результат[0][1] = БазисПраво[1];
Иначе
Результат[0][0] = БазисВерх[1];
Результат[0][1] = -БазисВерх[0];
КонецЕсли;
Иначе
Если БазисПраво <> Неопределено Тогда
Результат[0][0] = БазисПраво[0];
Результат[0][1] = БазисПраво[1];
Результат[1][0] = -БазисПраво[1];
Результат[1][1] = БазисПраво[0];
КонецЕсли;
КонецЕсли;
Возврат Результат;
КонецФункции
// Функция - Создать пространство по углу
//
// Параметры:
// Смещение - Вектор -
// Ширина - Число -
// Высота - Число -
// УголГрадусов - Число -
//
// Возвращаемое значение:
// - Матрица пространства
//
&НаКлиенте
Функция СоздатьПространствоПоУглу(Смещение = Неопределено, Ширина = 1, Высота = 1, УголГрадусов = 0)
Pi = 3.1415926535897932;
УголРадианов = УголГрадусов/180 * Pi;
cos = Cos(УголРадианов);
sin = Sin(УголРадианов);
БазисВерх = СоздатьВектор(-sin * Высота, cos * высота);
БазисПраво = СоздатьВектор(cos * Ширина, sin * Ширина);
Возврат СоздатьПространствоПоВекторам(Смещение, БазисВерх, БазисПраво);
КонецФункции // ()
// Функция - Умножить вектор на матрицу
//
// Параметры:
// Вектор - Вектор -
// Матрица - Матрица -
//
// Возвращаемое значение:
// - Вектор. Результат умножения.
//
&НаКлиенте
Функция УмножитьВекторНаМатрицу(Вектор, Матрица)
Результат = СоздатьВектор();
Для i = 0 по 2 Цикл
Для j = 0 по 2 Цикл
Результат[i] = Результат[i] + Вектор[j] * Матрица[j][i];
КонецЦикла;
КонецЦикла;
Возврат Результат;
КонецФункции
// Функция - Длина вектора
//
// Параметры:
// Вектор - Вектор -
//
// Возвращаемое значение:
// - Число. Длина вектора.
//
&НаКлиенте
Функция ДлинаВектора(Вектор)
Возврат Sqrt(Вектор[0] * Вектор[0] + Вектор[1] * Вектор[1]);
КонецФункции
// Функция - Вектор lerp
// Интерполирует значение между векторами
// Параметры:
// Вектор1 - Вектор -
// Вектор2 - Вектор -
// t - Число - (0<=t<=1)
//
// Возвращаемое значение:
// - Вектор между Вектор1 и Вектор2 на точке t=0-1
//
&НаКлиенте
Функция ВекторLerp(Вектор1, Вектор2, t)
Возврат СоздатьВектор(Вектор1[0] + (Вектор2[0]-Вектор1[0]) * t,Вектор1[1] + (Вектор2[1]-Вектор1[1]) * t);
КонецФункции // ()
// Функция - Разница векторов
//
// Параметры:
// Вектор1 - Вектор - Уменьшаемый вектор
// Вектор2 - Вектор - Вычитаемый вектор
//
// Возвращаемое значение:
// - Вектор. Разница векторов
//
&НаКлиенте
Функция РазницаВекторов(Вектор1, Вектор2)
Возврат СоздатьВектор(Вектор1[0]-Вектор2[0], Вектор1[1]-Вектор2[1]);
КонецФункции // ()
// Функция - Сумма векторов
//
// Параметры:
// Вектор1 - Вектор -
// Вектор2 - Вектор -
//
// Возвращаемое значение:
// - Вектор. Сумма векторов.
//
&НаКлиенте
Функция СуммаВекторов(Вектор1, Вектор2)
Возврат СоздатьВектор(Вектор1[0]+Вектор2[0], Вектор1[1]+Вектор2[1]);
КонецФункции // ()
// Функция - Точка безье
//
// Параметры:
// p0 - Вектор - точка для построения кривой безье
// p1 - Вектор - точка для построения кривой безье
// p2 - Вектор - точка для построения кривой безье
// p3 - Вектор - точка для построения кривой безье
// t - Число - (0<=t<=1)
//
// Возвращаемое значение:
// - Вектор. Точка на кривой безье соответсвующая значению t.
//
&НаКлиенте
Функция ТочкаБезье(p0, p1, p2, p3, t)
q = 1 - t;
Возврат СоздатьВектор(q * q * q * p0[0] + 3 * q * q * t * p1[0] + 3 * q * t * t * p2[0] + t * t * t * p3[0],
q * q * q * p0[1] + 3 * q * q * t * p1[1] + 3 * q * t * t * p2[1] + t * t * t * p3[1]);
КонецФункции
// Функция - Точки из строки
//
// Параметры:
// ИсходнаяСтрока - Строка - Строка чисел разделенных знаком ";", чисел должно быть четное количество
//
// Возвращаемое значение:
// - массив - Массив векторов
//
&НаКлиенте
Функция ТочкиИзСтроки(ИсходнаяСтрока)
Результат = Новый Массив;
РабочаяСтрока = СтрЗаменить(ИсходнаяСтрока, ";", Символы.ПС);
Для Сч = 1 по СтрЧислоСтрок(РабочаяСтрока)/2 Цикл
Результат.Добавить(СоздатьВектор(Число(СтрПолучитьСтроку(РабочаяСтрока, Сч*2 - 1 )), Число(СтрПолучитьСтроку(РабочаяСтрока, Сч * 2))));
Конеццикла;
Возврат Результат;
КонецФункции
#КонецОбласти