Построение геометрических фигур

 

В задаче из N уравнений всегда будет N+1 неизвестная.

Из законов Мэрфи

 

Рассмотрим задачу построения треугольника с известными длинами сторон AB, AC, BC. подобное построение вызывает большие трудности, поскольку непонятно, с чего же начать? Сделаем следующее. Зафиксируем на холсте одну вершину треугольника в точке с произвольными координатами a1,b1. Будем считать, что одна из сторон идет горизонтально, что сразу дает нам координаты второй точки (рис. 6).

 

 

Рис. 6 – Построение треугольника.

 

Осталось найти координаты точки С. Найдем косинус угла CAB по теореме косинусов: . Рассмотрим прямоугольный треугольник ACC1. В нем нам известны все углы и одна сторона. Тогда по теореме синусов , откуда находим dy. Аналогично вычисляем и dx.

 

Построение динамических изображений

 

Нет такой плохой ситуации, которая не могла бы стать еще хуже.

Из законов Мэрфи.

 

Было бы любопытно увидеть процесс постепенной отрисовки графика функции. График бы "полз", создавая иллюзию анимации. Попробуем поставить в цикл расчета функции команду задержки Sleep(100), останавливающую программу на 100мс:

. . .

WHILE Xmin<=Xmax DO

BEGIN

Sleep(100);

y:=sin(xmin);

. . .

Нажимаем F9 и… ничего не изменилось, только расчет стал выполняться медленнее, но график все равно отображается только в самом конце. Почему? Здесь мы столкнулись с одной важной особенностью программ на Delphi: при работе цикла никаких действий с элементами интерфейса не выполняется. Они как бы накапливаются и затем выполняются все сразу. Что же делать? Надо сказать Delphi, чтобы он не ленился и даже в цикле производил перерисовку нашего графика. Делается это просто – достаточно в теле цикла записать команду Application.ProcessMessages. Вот теперь все получилось, график красиво "ползет".

 

Анимация в Delphi

 

Вероятность того, что бутерброд упадет маслом вниз,

прямо пропорциональна стоимости ковра.

Из законов Мэрфи.

 

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

Сначала нарисуем небо. Положите на форму Image и кнопку. При нажатии кнопки будет выполняться следующий код:

 

procedure TForm1.Button1Click(Sender: TObject);

 

VAR i:WORD;

 

Begin

WITH Image1.Canvas DO

BEGIN

Brush.Color:=clBlack;

FillRect(Image1.ClientRect);

FOR i:=1 TO 500 DO

Pixels[RANDOM(Image1.Width), RANDOM(Image1.Height)]:=clWhite

END

end;

 

Сначала весь холст заливается черным цветом, а затем на нем вы случайных местах отображаются 500 звезд. Для изображения отдельной точки можно использовать свойство объекта Canvas – массив Pixels[x,y], обеспечивающий прямой доступ к цвету точки с координатами x,y.

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

 

procedure TForm1.Button1Click(Sender: TObject);

 

PROCEDUREUfo(x,y:INTEGER);

 

BEGIN

WITH Image1.Canvas DO

BEGIN

Pen.Color:=clBlue;

Pen.Width:=3;

Ellipse(x,y,x+20,y+10)

END

END;

 

VAR i:WORD;

...

Обратите внимание, что процедура Ufo должна находиться внутри процедуры TForm1.Button1Click потому, что иначе она не будет иметь доступа к экранной форме Form1. Из-за особенностей работы с анимацией цвет летающей тарелки на экране будет вовсе не синим. Тарелка изобразится цветом, получающимся в результате выполнения операции "логическое ИЛИ" над цветом фона и изображения. В данном случае тарелка окажется желтого цвета, что вполне приемлемо.

Осталось организовать движение тарелки по экрану. Делается это примерно так:

 

Pen.Mode:=pmNOTXOR;

FOR i:=0 TO Image1.Width DO

BEGIN

Ufo(i, i DIV 2);

Application.ProcessMessages;

Sleep(10);

Ufo(i, i DIV 2)

END

END;

 

Самая важная строчка в этом фрагменте - Pen.Mode:=pmNOTXOR. Она устанавливает режим вывода графики "исключающее ИЛИ". При таком режиме вывод одной и той же картинки дважды в одно и то же место изображения приводит к автоматическому восстановлению фона под картинкой. В цикле картинка выводится первый раз (вызов процедуры Ufo), затем выполняется команда Application.ProcessMessages, обеспечивающая немедленное отображение НЛО на экране и делается задержка на 10мс, чтобы мы успели увидеть, что получилось. Далее НЛО выводится в то же самое место еще раз, при этом изображение тарелки пропадет, а под ней автоматически восстановится фон.

Координаты тарелки меняются и по Х, и по Y, поэтому она поедет по экрану вправо вниз.

Запускаем… Красиво? Нет! Экран безобразно мерцает. Что делать? Спокойно, это просто еще один фокус Delphi. Чтобы динамическое изображение на форме не мерцало, в начало процедуры вывода анимации надо добавить строчку

 

Form1.DoubleBuffered:=TRUE;

 

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

 

Работа с таймером

 

Вы уже дошли до состояния, когда у вас нет времени, чтобы

разрешить те проблемы, которые отнимают у вас все время?

Из законов Мэрфи

 

Интересная возможность Delphi – создание процедур, автоматически выполняющихся через заданные промежутки времени. Для этого используется специальный объект Timer, находящийся на закладке System ( ). Этот объект – невизуальный, он не отображается на форме во время работы программы и его можно разместить в любом ее месте.

Главное свойство объекта Timer называется Interval и задает время в миллисекундах, по истечении которого таймер вызывает процедуру, присоединенную к его событию OnTimer. Свойство Enabled включает и выключает таймер. Когда таймер включен, он постоянно и незаметно для пользователя отсчитывает время и, как только пройдет заданный интервал, выполняет заданную процедуру, затем снова начинает отсчитывать время и т.д.

Простейший пример работы таймера – вывод в заголовке формы текущего времени. Настроим таймер так, чтобы он вызывал процедуру каждую секунду. Для этого свойство Interval нужно установить в 1000, а свойство Enabled – в True. На закладке Events инспектора объектов дважды щелкам мышью в единственном поле OnTimer пишем следующее:

 

procedureTForm1.Timer1Timer(Sender: TObject);

 

Begin

Form1.Caption:=TimeToStr(Now)

End;

Функция Now возвращает текущее время по часам компьютера в виде числа секунд, прошедшего с полуночи, а функция TimeToStr превращает ее в текстовую строку привычного нам вида вроде "15:25:18". Вот как просто решается на Delphi задача отображения часов на экране.