"Альтернативные"
решения
Вам нравятся такие
пузыри? Рисуются они очень просто. Генерируются произвольным образом N
точек, а затем вокруг этих точек наращиваются окружности, яркость
которых с радиусом уменьшается. Если же, при построении окружности, необходимо
поставить пиксель на непустое место, то выбирается цвет с наибольшей
яркостью. Впрочем, смотрите алгоритм ниже. Если возможно, установите у
окна свойство AutoRedraw=True
Алгоритм 1. Пузыри |
Type Bubble
X As Integer 'X,Y - координаты центра
Y As Integer
Radius As Integer 'Максимальный радиус
CurrentR As Integer 'Текущий радиус
CurColor As Long 'Текущий цвет
End Type
Dim Points(300) as Bubble
'Точки, в данном случае их 300
Dim Screen() as Long 'Копия
окна
Public Sub DrawBubble()
Static i, j, MaxX, MaxY, MaxR As Integer
MaxX = picOut.ScaleWidth 'размеры окна
MaxY = picOut.ScaleHeight
MaxR = 100 ' максимальный радиус пузырей
ReDim Screen(MaxX, MaxY)
Erase Points
For i = 0 To 300
With Points(i)
.X = Int(Rnd * MaxX)
.Y = Int(Rnd * MaxY)
.Radius = Int(Rnd * MaxR + 10)
.CurrentR = 0
.CurColor = RGB(255, 255, 255)
Screen(.X, .Y) = .CurColor
End With
Next
Do While DoesALLZero
For i = 0 To 300
With Points(i)
If .CurColor > 0 Then
.CurrentR = .CurrentR + 1 'Увеличиваем радиус
.CurColor = RGB(255 - (.CurrentR / .Radius) *
255, 255 - (.CurrentR / .Radius) * 255, 255 - (.CurrentR / .Radius) * 255)
'Уменьшаем яркость
fCircle .X, .Y, .CurrentR, .CurColor 'Рисуем
окружность
End If
End With
Next
Loop
DrawScreen 'Вырисовываем окно
End Sub
Private Function DoesALLZero() As Boolean
Static i, j As Integer
'Проверяем у всех ли пузырей яркость=0
j = 0
For i = 0 To 300
If Points(i).CurColor <= 0 Then j = j + 1
Next
If j >= 300 Then
DoesALLZero = False
Else: DoesALLZero = True
End If
End Function
Private Sub fCircle(ByVal X As Integer, ByVal Y As Integer, ByVal
Radius As Integer, ByVal Color As Long)
'Процедура рисует окружность с центром (X,Y) радиусом R
и цветом Color
Static i, j As Integer
Static N, M As Double
For i = 0 To 410 'Чем больше число - тем "качественней"
окружность (тем дольше она рисуется)
N = (X + Cos(i) * Radius)
M = (Y - Sin(i) * Radius)
If (Abs(N) < UBound(Screen, 1)) And (Abs(M) < UBound(Screen,
2)) Then
If Screen(Abs(N), Abs(M)) < Color Then Screen(Abs(N),
Abs(M)) = Color
End If
Next
End Sub
Private Sub DrawScreen()
'Рисует Screen
Static i, j As Integer
For i = 0 To UBound(Screen, 1)
For j = 0 To UBound(Screen, 2)
SetPixelV picOut.hdc, i, j, Screen(i, j)
Next j
Next i
End Sub
|
Можно сделать пузыри цветными,
для этого измените строку .CurColor=RGB(R,G,B) по своему усмотрению. Например,
RGB(0,255-(.CurrentR/.Radius)*255,255-(.CurrentR/.Radius)*255) позволяет
рисовать пузыри приятно голубого цвета.
Для увеличения скорости прорисовки
пузырей можно воспользоваться библиотекой
fCircle.dll
, которая рассчитана на максимальное поле 1024x768. Ниже описаны три
ее процедуры:
Declare Sub fCircle lib
"fCircle.dll" (ByVal x As Long,ByVal y As Long, ByVal color As Long, ByVal
radius As Long, ByVal Level As Integer)
- Абсолютно аналогична процедуре fCircle алгоритма, изложенного
выше, Level - количество проходов по окружности (см. комментарий выше).
Declare Sub DrawScreen lib
"fCircle.dll" (ByVal hDC As Long, ByVal Width As Long, ByVal Height As
Long) - Тоже самое, что и DrawScreen в
нашем алгоритме, только необходимо указать дескриптор окна и его размеры
в пикселах.
Declare Sub ClearScreen lib
"fCircle.dll" () - Очищает внутренний
массив, содержащий копию окна. Перед очередной прорисовкой желательно
вызывать эту функцию.
С помощью этой библиотеки быстродействие
значительно увеличится. Так, например, если вышеизложенный алгоритм
рисует 150 пузырей на поле 368x264 при количестве проходов 770 за 120,0625
секунд, то с теми же параметрами, но, используя библиотеку, время
составило 17,3125 секунд.
Все вопросы и предложения:
NickSoft@Netscape.net
[
Programming
][Фракталы
][Turtle-графика
][
Главная (фреймы)
]
|