"Альтернативные" решения

Вам нравятся такие пузыри? Рисуются они очень просто. Генерируются произвольным образом 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-графика ][ Главная (фреймы) ]




Hosted by uCoz