Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Мультимедиа в Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 10.06.2009, 20:00   #11
sp.caster
Пользователь
 
Регистрация: 29.01.2009
Сообщений: 60
По умолчанию

Цитата:
Сообщение от DomiNick Посмотреть сообщение
Код:
Label1.Canvas.MoveTo(10, 20); // - переместить начальную точку (из которой будет рисоваться линия)
Label1.Canvas.LineTo(50, 40); // - нарисовать линию в точку (из начальной), причём после этого начальной точкой станет конечная точка линии

спасибо огромное)
sp.caster вне форума Ответить с цитированием
Старый 10.06.2009, 20:45   #12
Levsha100
Заблокирован
Старожил
 
Регистрация: 20.07.2008
Сообщений: 4,032
По умолчанию

Цитата:
В этой статье вы узнаете, как создавать реалистичные молнии и выводить их на экран. Выводить молнии на экран мы будем по массиву точек, полученных алгоритмом, который называется “Фрактализация отрезка”. Рендерить ее можно многими способами и я опишу все, которые дают приемлемую картинку.

Фрактализация отрезка

Этот метод заполняет массив (Array of TVector) точками, определяющими тело молнии. Вся сложность заключается в том, чтобы создать кривую, по форме похожую на реальную молнию. Метод фрактализации отрезка заключается в том, что кривая формируется рекурсивным делением отрезка и заменой на случайное колено. Для начала рассмотрим двумерный случай фрактализации. Допустим, нам даны две концевые точки A и B (это начало молнии и ее конец). Первым шагом мы заменяем отрезок AB двумя отрезками AC и CB, где точка C выбирается случайным образом вдоль срединного перпендикуляра отрезка AB, причем она может лежать по обе стороны отрезка. Далее мы рекурсивно делим отрезки AC и CB, получим уже 4 отрезка AD, DC, CE и EB, далее делим их и так делаем до получения желанной кривой.



Но как определить, что нужно остановить рекурсию? Глубину рекурсии можно контролировать по ее уровню (то есть когда уровень рекурсии достигнет какого то числа или по длине отрезка прямой. Если молния не будет занимать много пикселей на экране, тогда можно продолжать рекурсию, до предела разрешающей способности самого монитора. Но я использовал первый метод и вам советую, это дает хорошее управление глубиной фрактализации.



Теперь, о том, как формировать кривую в пространстве. Здесь точка C будет выбираться случайным образом из плоскости, перпендикулярной отрезку и лежащей на его середине. Для этого находим два вектора, допустим PlaneU и PlaneV, с помощью векторных произведений. Эти вектора и будут представлять нужную плоскость точек.

Кратко формулу получения точки C можно записать так:
Код:
 
C = 0.5 * (A+B) + factor * (PlaneU * RND + PlaneV * RND)
Здесь RND - дает случайное число от -0,5 до 0,5, а factor - это величина возмущения. То есть, чем больше factor, тем сильнее дергается молния. Нормальное значение factor от 0,1 до 0,4.

Код:
Dir := VectorSubtract(A, B);

PlaneU := VectorCrossProduct(Dir, YAxis);

PlaneV := VectorCrossProduct(PlaneU, Dir);

NormalizeVector(PlaneU);

NormalizeVector(PlaneV);

C[0] := 0.5*(A[0] + B[0]) + factor*(PlaneU[0]*(random-0.5) + PlaneV[0]*(random-0.5)); 

C[1] := 0.5*(A[1] + B[1]) + factor*(PlaneU[1]*(random-0.5) + PlaneV[1]*(random-0.5));

C[2] := 0.5*(A[2] + B[2]) + factor*(PlaneU[2]*(random-0.5) + PlaneV[2]*(random-0.5));
Теперь, когда мы получили точку C, нам нужно рекурсивно разделить полученные отрезки. Все полученные точки занесем в массив Points, чтобы потом вывести их на экран. Вот код этой процедуры:

Код:
procedure Fract(A, B : TVector; factor : Single; maxFracDepth, fracCount : Byte);

var

Dir, PlaneU, PlaneV, C : TVector;

begin

inc(fracCount); // Увеличим глубину рекурсии

if fracCount > maxFracDepth then // Если then глубина рекурсии больше заданной, тогда…

   begin

     inc(numPoints); 

     points[numPoints] := B; // Сохраним точку и выходим

     exit;

   end;

Dir := VectorSubtract(A, B);

PlaneU := VectorCrossProduct(Dir, YHmgVector);

PlaneV := VectorCrossProduct(PlaneU, Dir);

NormalizeVector(PlaneU);

NormalizeVector(PlaneV);

C[0] := 0.5*(A[0] + B[0]) + factor*(PlaneU[0]*(random-0.5) + PlaneV[0]*(random-0.5));

C[1] := 0.5*(A[1] + B[1]) + factor*(PlaneU[1]*(random-0.5) + PlaneV[1]*(random-0.5));

C[2] := 0.5*(A[2] + B[2]) + factor*(PlaneU[2]*(random-0.5) + PlaneV[2]*(random-0.5));

Fract(A, C, factor*fracDec, maxFracDepth, fracCount); // Рекурсивно делим отрезок AC

Fract(C, B, factor*fracDec, maxFracDepth, fracCount); // Рекурсивно делим отрезок CB

end;
Чтобы кривая выглядела правильно, нужно уменьшать уровень возмущения (factor) по мере увеличения глубины рекурсии. Для этого я ввел переменную fracDec, на которую умножается factor; она должна быть меньше единицы и больше нуля. Нормальное ее значение около 0.5 или 0.6.

Вот код процедуры, объединяющей все вышесказанное:

Код:
procedure DoFractalLightning(Src, Dst : TVector; 

                            factor{сила возмущения}, 

                            fracDec{коэффициент ослабления возмущения}: Single; 

                            maxFracDepth{максимальная глубина} : Byte; 

                            cR, cG, cB {цвет}: Single);

var i : Integer;

begin

numPoints := 0;

points[0] := Src; 

fracLev := fracLev * VectorDistance(Src, Dst); 

Fract(Src, Dst, factor, maxFracDepth, 0);

end;
С помощью параметров factor и fracDec можно управлять молнией. Немного изменяйте эти параметры, и вы поймете, как они влияют на генерацию молнии.

Александр Гарустович
http://www.mirgames.ru/
Взял из сборника Delphi_Full.
// Не посчитайте за рекламу)))
Levsha100 вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
МОНИТОР, БЛИН- издаёт писк+скрежет Viteef Компьютерное железо 26 10.02.2010 20:48
Сервисы, блин.... Баламут Win Api 6 28.12.2007 01:30
Opera блин Elm0 Свободное общение 9 21.06.2007 20:44