Форум программистов, компьютерный форум, киберфорум
The trick
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  

Многопоточность на примере фрактала Julia (VB6)

Запись от The trick размещена 23.12.2013 в 04:40
Показов 7283 Комментарии 4
Метки multithreading, vb



Мне очень нравятся фракталы и фрактальные множества. Написал несколько тестовых программ, где можно генерировать и менять параметры у разных фракталов. В этом примере можно генерировать множество Жюлиа а также менять все параметры генерации (в том числе загружать палитру из картинок). Чтобы программа не подвисала, я генерацию и отрисовку засунул в другой поток. Пример не работает в IDE, работает в скомпилированном виде.
Форма:
Visual Basic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
Option Explicit
 
' Многопоточность на примере фрактала Julia (Z^2+C)
' © Кривоус Анатолий Анатольевич (The trick), 2013
' Работает только в скомпилированном виде
 
Private Type OPENFILENAME
    lStructSize As Long
    hWndOwner As Long
    hInstance As Long
    lpstrFilter As String
    lpstrCustomFilter As String
    nMaxCustFilter As Long
    nFilterIndex As Long
    lpstrFile As String
    nMaxFile As Long
    lpstrFileTitle As String
    nMaxFileTitle As Long
    lpstrInitialDir As String
    lpstrTitle As String
    Flags As Long
    nFileOffset As Integer
    nFileExtension As Integer
    lpstrDefExt As String
    lCustData As Long
    lpfnHook As Long
    lpTemplateName As String
End Type
 
Private Declare Function GetOpenFileName Lib "comdlg32.dll" Alias "GetOpenFileNameA" (pOpenFilename As OPENFILENAME) As Long
Private Declare Function CreateFont Lib "gdi32" Alias "CreateFontA" (ByVal H As Long, ByVal W As Long, ByVal E As Long, ByVal O As Long, ByVal W As Long, ByVal i As Long, ByVal u As Long, ByVal S As Long, ByVal C As Long, ByVal OP As Long, ByVal CP As Long, ByVal Q As Long, ByVal PAF As Long, ByVal F As String) As Long
Private Declare Function SelectObject Lib "gdi32" (ByVal hdc As Long, ByVal hObject As Long) As Long
Private Declare Function DeleteObject Lib "gdi32" (ByVal hObject As Long) As Long
Private Declare Function CreateThread Lib "kernel32" (lpThreadAttributes As Any, ByVal dwStackSize As Long, ByVal lpStartAddress As Long, lpParameter As Any, ByVal dwCreationFlags As Long, lpThreadId As Long) As Long
Private Declare Function WaitForSingleObject Lib "kernel32" (ByVal hHandle As Long, ByVal dwMilliseconds As Long) As Long
Private Declare Function GetExitCodeThread Lib "kernel32" (ByVal hThread As Long, lpExitCode As Long) As Long
Private Declare Function CreateCompatibleDC Lib "gdi32" (ByVal hdc As Long) As Long
Private Declare Function GetPixel Lib "gdi32" (ByVal hdc As Long, ByVal X As Long, ByVal y As Long) As Long
Private Declare Function DeleteDC Lib "gdi32" (ByVal hdc As Long) As Long
 
Private Enum Sliders
    YOffset
    XOffset
    Scaling
    RealPart
    ImaginaryPart
End Enum
Private Enum Colors
    cBackground = 0
    cBorders = &H303030
    cSlider = &H202020
    cSelect = &H30FFFF
End Enum
Private Type Slider
    Orientation As Boolean  ' True = Вертикально
    Value As Double
    Scl As Double           ' Величина изменения
    Pos As Double
End Type
 
Private Const SliderSize As Long = 10
Private Const STILL_ACTIVE = &H103&
Private Const INFINITE = &HFFFFFFFF
Private Const x_MaxBuffer = 32768
Private Const OFN_ENABLESIZING = &H800000
Private Const OFN_EXPLORER = &H80000
 
Dim Slider(4) As Slider, IsAction As Boolean, Active As Long
Dim hFont As Long
Dim EnableUpdate As Boolean
Dim hThread As Long
Dim C As Canvas
 
Private Sub Form_Load()
    Dim i As Long
    Slider(Sliders.YOffset).Orientation = True
    Slider(Sliders.Scaling).Value = 1
    For i = 0 To UBound(Slider)
        Slider(i).Scl = 0.1
        Active = i
        DrawSlider i
    Next
    hFont = CreateFont((Me.FontSize * -20) / Screen.TwipsPerPixelY, 0, 2700, 0, Me.Font.Weight, 0, 0, 0, 204, 0, 0, 2, 0, Me.FontName)
    i = SelectObject(Me.hdc, hFont)
    Me.CurrentX = 530: Me.CurrentY = 150: Me.Print "Offset Y:"
    SelectObject Me.hdc, i
    Active = Sliders.Scaling: SliderEvent
    Active = Sliders.YOffset: SliderEvent
    EnableUpdate = True
    
    For i = 0 To 99
        modJulia.Palette(i) = RGB(i, i, i)
    Next
 
End Sub
Private Sub Form_Unload(cancel As Integer)
    ExitThread
    DeleteObject hFont
End Sub
Private Function ShowOpen() As String
    Dim N As Long
    Dim FileStruct As OPENFILENAME
    
    With FileStruct
        .hWndOwner = Me.hwnd
        .lpstrFile = String(x_MaxBuffer, 0)
        .nMaxFile = x_MaxBuffer - 1
        .lpstrFileTitle = .lpstrFile
        .nMaxFileTitle = x_MaxBuffer - 1
        .Flags = OFN_ENABLESIZING Or OFN_EXPLORER
        .lStructSize = Len(FileStruct)
        .lpstrFilter = "All supported image" & vbNullChar & "*.bmp;*.jpg;*.jpeg"
        If GetOpenFileName(FileStruct) Then
            N = InStr(1, .lpstrFile, vbNullChar)
            ShowOpen = Left$(.lpstrFile, N - 1)
        End If
    End With
End Function
Private Sub ExitThread()
    Dim Ret As Long
    If modJulia.Process Then
        modJulia.Process = False
        GetExitCodeThread hThread, Ret
        If Ret = STILL_ACTIVE Then
            WaitForSingleObject hThread, INFINITE
        End If
    End If
End Sub
Private Sub Update()
    Dim TID As Long
    
    ExitThread
    
    modJulia.iLeft = Slider(Sliders.XOffset).Value - 1 / Slider(Sliders.Scaling).Value
    modJulia.iRight = Slider(Sliders.XOffset).Value + 1 / Slider(Sliders.Scaling).Value
    modJulia.iTop = -Slider(Sliders.YOffset).Value - 1 / Slider(Sliders.Scaling).Value
    modJulia.iBottom = -Slider(Sliders.YOffset).Value + 1 / Slider(Sliders.Scaling).Value
    modJulia.Real = Slider(Sliders.RealPart).Value
    modJulia.Imaginary = Slider(Sliders.ImaginaryPart).Value
    C.hdc = picDisp.hdc
    C.Width = picDisp.ScaleWidth
    C.Height = picDisp.ScaleHeight
    
    If EnableUpdate Then
        hThread = CreateThread(ByVal 0, 0, AddressOf DrawJulia, C, 0, TID)
    End If
End Sub
Private Sub DrawSlider(ByVal Index As Sliders)
    Dim p As Long
    picSlider(Index).FillColor = Colors.cBackground
    picSlider(Index).Line (0, 0)-Step(picSlider(Index).ScaleWidth - 1, picSlider(Index).ScaleHeight - 1), Colors.cBorders, B
    If Slider(Index).Orientation Then
        p = Slider(Index).Pos * (picSlider(Index).ScaleHeight - SliderSize) \ 2 + picSlider(Index).ScaleHeight \ 2 - SliderSize \ 2
        picSlider(Index).FillColor = Colors.cSlider
        picSlider(Index).Line (3, p)-Step(picSlider(Index).ScaleWidth - 7, SliderSize), Colors.cBorders, B
    Else
        p = Slider(Index).Pos * (picSlider(Index).ScaleWidth - SliderSize) \ 2 + picSlider(Index).ScaleWidth \ 2 - SliderSize \ 2
        picSlider(Index).FillColor = Colors.cSlider
        picSlider(Index).Line (p, 3)-Step(SliderSize, picSlider(Index).ScaleHeight - 7), Colors.cBorders, B
    End If
End Sub
Private Sub lbLoadPalette_DblClick()
    Dim File As String, Img As StdPicture, DC As Long, obmp As Long, W As Long, X As Long, D As Single, i As Long, p As Long
    lbLoadPalette.ForeColor = cSelect
    File = ShowOpen()
    lbLoadPalette.ForeColor = Me.ForeColor
    If Len(File) Then
        On Error GoTo ErrorLoading
        Set Img = LoadPicture(File)
        On Error GoTo 0
        W = ScaleX(Img.Width, vbHimetric, vbPixels)
        DC = CreateCompatibleDC(Me.hdc)
        obmp = SelectObject(DC, Img.Handle)
        D = W / 100
        For i = 0 To 100
            X = i * D
            p = GetPixel(DC, X, 0)
            modJulia.Palette(i) = ((p \ &H10000) And &HFF&) Or (p And &HFF00&) Or ((p And &HFF) * &H10000)
        Next
        SelectObject DC, obmp
        DeleteDC DC
        Set Img = Nothing
        Update
    End If
    Exit Sub
ErrorLoading:
    MsgBox "Error loading image"
End Sub
 
Private Sub picDisp_Paint()
    Update
End Sub
Private Sub picSlider_MouseDown(Index As Integer, Button As Integer, Shift As Integer, X As Single, y As Single)
    Dim p As Double
    IsAction = True
    tmrSlider.Enabled = True
    Active = Index
    If Slider(Index).Orientation Then
        Slider(Index).Pos = y / (picSlider(Index).ScaleHeight - SliderSize) * 2 - 1
    Else
        Slider(Index).Pos = X / (picSlider(Index).ScaleWidth - SliderSize) * 2 - 1
    End If
    If Abs(Slider(Index).Pos) > 1 Then Slider(Index).Pos = Sgn(Slider(Index).Pos)
    Slider(Index).Value = Slider(Index).Value + Slider(Index).Pos * Slider(Index).Scl
    SliderEvent
    DrawSlider Index
End Sub
Private Sub picSlider_MouseMove(Index As Integer, Button As Integer, Shift As Integer, X As Single, y As Single)
    If Not IsAction Then Exit Sub
    If Slider(Index).Orientation Then
        Slider(Index).Pos = y / (picSlider(Index).ScaleHeight - SliderSize) * 2 - 1
    Else
        Slider(Index).Pos = X / (picSlider(Index).ScaleWidth - SliderSize) * 2 - 1
    End If
    If Abs(Slider(Index).Pos) > 1 Then Slider(Index).Pos = Sgn(Slider(Index).Pos)
    Slider(Index).Value = Slider(Index).Value + Slider(Index).Pos * Slider(Index).Scl
    SliderEvent
    DrawSlider Index
End Sub
Private Sub picSlider_MouseUp(Index As Integer, Button As Integer, Shift As Integer, X As Single, y As Single)
    If IsAction Then
        IsAction = False
        tmrSlider.Enabled = False
        Slider(Index).Pos = 0
        DrawSlider Index
        SliderEvent
    End If
End Sub
Private Sub SliderEvent()
    Dim i As Long
    Select Case Active
    Case Sliders.YOffset
        i = SelectObject(Me.hdc, hFont)
        Me.Line (530, 350)-Step(-40, 120), Me.BackColor, BF
        Me.CurrentX = 530: Me.CurrentY = 350: Me.Print Format(Slider(Active).Value, "#0.00000")
        SelectObject Me.hdc, i
    Case Sliders.Scaling
        If Slider(Scaling).Value <= 0 Then Slider(Scaling).Value = 0.00000000000001
        For i = 0 To UBound(Slider)
            Select Case i
            Case Sliders.XOffset, Sliders.YOffset
                Slider(i).Scl = 1 / Slider(Scaling).Value * 0.1
            Case Sliders.RealPart, Sliders.ImaginaryPart
                Slider(i).Scl = 1 / Slider(Scaling).Value * 0.02
            End Select
        Next
        lblValue(Active).Caption = Format(Slider(Active).Value, "#0.00000")
    Case Sliders.XOffset To Sliders.ImaginaryPart
        lblValue(Active).Caption = Format(Slider(Active).Value, "#0.00000")
    End Select
    Update
End Sub
Private Sub tmrSlider_Timer()
    Slider(Active).Value = Slider(Active).Value + Slider(Active).Pos * Slider(Active).Scl
    SliderEvent
End Sub
Модуль:
Visual Basic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
Option Explicit
 
' Генерация фрактала Julia (отдельный поток)
' © Кривоус Анатолий Анатольевич (The trick), 2013
 
Public Type Canvas
    hdc As Long
    Width As Long
    Height As Long
End Type
Public Type RGBQUAD
    rgbBlue As Byte
    rgbGreen As Byte
    rgbRed As Byte
    rgbReserved As Byte
End Type
Public Type BITMAPINFOHEADER
    biSize As Long
    biWidth As Long
    biHeight As Long
    biPlanes As Integer
    biBitCount As Integer
    biCompression As Long
    biSizeImage As Long
    biXPelsPerMeter As Long
    biYPelsPerMeter As Long
    biClrUsed As Long
    biClrImportant As Long
End Type
Public Type BITMAPINFO
    bmiHeader As BITMAPINFOHEADER
    bmiColors As RGBQUAD
End Type
 
Public Palette(99) As Long
Public Process As Boolean
Public iLeft As Double, iTop As Double, iRight As Double, iBottom As Double, Real As Double, Imaginary As Double
 
Public Function DrawJulia(C As Canvas) As Long
    Dim X As Double, y As Double, Sx As Double, Sy As Double
    Dim pt As Long, Bits() As Long, bi As BITMAPINFO
    Dim lx As Long, ly As Long
    
    Process = True
    
    ReDim Bits(C.Width * C.Height - 1)
    With bi.bmiHeader
        .biBitCount = 32
        .biHeight = -C.Height
        .biWidth = C.Width
        .biPlanes = 1
        .biSize = Len(bi.bmiHeader)
        .biSizeImage = C.Width * C.Height * 4
    End With
    
    Sx = (iRight - iLeft) / (C.Width - 1)
    Sy = (iRight - iLeft) / (C.Height - 1)
    X = iLeft: y = iTop
    Process = Not Not Process
    For ly = 0 To C.Height - 1: For lx = 0 To C.Width - 1
        X = X + Sx
        Bits(pt) = Palette(Julia(X, y))
        pt = pt + 1
        If Not Process Then GoTo cancel
    Next: y = y + Sy: X = iLeft: Next
cancel:
    SetDIBitsToDevice C.hdc, 0, 0, C.Width, ly, 0, 0, 0, ly, VarPtr(Bits(0)), VarPtr(bi), 0
    
    Process = False
End Function
Private Function Julia(X As Double, y As Double) As Single
    Dim Zr As Double, Zi As Double
    Dim Cr As Double, Ci As Double
    Dim tZr As Double
    Dim Count As Long
    Dim r As Single
    Count = 0
    Zr = X: Zi = y
    Cr = Real: Ci = Imaginary
    Do While Count < 99 And r < 10
        tZr = Zr
        Zr = Zr * Zr - Zi * Zi
        Zi = tZr * Zi + Zi * tZr
        Zr = Zr + Cr
        Zi = Zi + Ci
        r = Sqr(Zr * Zr + Zi * Zi)
        Count = Count + 1
    Loop
    Julia = Count
End Function
Видео
Вложения
Тип файла: rar JuliaMultithread.rar (41.2 Кб, 446 просмотров)
Метки multithreading, vb
Размещено в Без категории
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Всего комментариев 4
Комментарии
  1. Старый комментарий
    Аватар для Памирыч
    Круто замутил. Вот что значит приложить голову. Красотень же!)
    Запись от Памирыч размещена 23.12.2013 в 07:16 Памирыч вне форума
  2. Старый комментарий
    Цитата Сообщение от Памирыч
    Круто замутил. Вот что значит приложить голову. Красотень же!)
    Спасибо!
    Запись от The trick размещена 23.12.2013 в 11:09 The trick вне форума
  3. Старый комментарий
    Аватар для Pro_grammer
    Очень интересно получилось!
    Я тоже пару лет назад фракталами увлекался. Тоже написал программку на тему Julia. Правда всё управление было мышкой - водишь её и в зависимости от координат возникают различные фигуры, увлекает жутко!
    Запись от Pro_grammer размещена 23.12.2013 в 20:52 Pro_grammer вне форума
  4. Старый комментарий
    Цитата Сообщение от Pro_grammer
    Очень интересно получилось!
    Я тоже пару лет назад фракталами увлекался. Тоже написал программку на тему Julia. Правда всё управление было мышкой - водишь её и в зависимости от координат возникают различные фигуры, увлекает жутко!
    Спасибо! Я тоже до этой проги кучу писал прог для генерации фрактальных множеств, геометрических фракталов, L-систем. Бесило только то, что тормозит при отрисовке все это дело. Изначально эта программа, выполнялась в одном потоке, и скролы висли, а использовать DoEvents - это еще на несколько порядков снижать скорость отрисовки. Поэтому я переделал, сделав отрисовку в другом потоке, дабы убить миф о том что на VB6 нельзя писать многопоточные приложения, и сделать отрисовку без зависаний. Кстати скорость после этого не падает на многоядерных системах а используеться мощь всех ядер, поэтому мы ничего не теряем.
    Запись от The trick размещена 24.12.2013 в 00:38 The trick вне форума
 
Новые блоги и статьи
Часы электронные
Uhbif79 12.08.2026
Выкладываю программу часов. Программа позволяет: 1. Использовать системное время и дату, 2. Есть возможность вводить время и дату вручную. 3. Реализованы 2 будильника: начало и конец рабочего дня. . . .
Часы с будильником на основе класса QLCDNumber
Uhbif79 12.08.2026
Всем добрый день, выкладываю программу часов с будильником на основе класса QLCDNumber. Здесь я пробовал самостоятельно создавал классы, впервые столкнулся с видимостью переменной одного класса из. . .
Установка MinGW GCC 16.2 и CMake
8Observer8 10.08.2026
VK Видео: https:/ / vkvideo. ru/ video-240781534_456239017 YouTube: eY5-5PyI9NM Текстовая версия
Неделя из жизни имитационной модели склада: мои кривые руки растут, откуда надо
anaschu 10.08.2026
Неделя из жизни имитационной модели склада: как я почти написал неправильную логику и что с этим делать Работаю сейчас над учебно-рабочим проектом: строю в AnyLogic имитационную модель процессов. . .
Калькулятор для расчета родства
russiannick 07.08.2026
1. Задача: Создать калькулятор для расчета родства. Родственных связей существует 8 ступеней, такие как: p - отец P - мать q - муж Q - жена b - брат B - сестра s - сын S - дочь
Мир по моей воле
kumehtar 07.08.2026
Когда-то кажется, что всё просто. Ты весь такой светлый. Причиняешь добро. Борешься за справедливость в этом тёмном мире. Потом начинаешь замечать одну неприятную вещь. Почти каждый хороший. . .
Кредитный калькулятор
Maks 05.08.2026
Решение задачи по прикладной информатике средствами 1С. Задача: Напишите приложение-калькулятор, которое помогает рассчитывать параметры кредита для аннуитетного и дифференцированного видов. . .
У нас сейчас поговорку "Опять 25" нужно переделать на "Опять +35".
kumehtar 04.08.2026
С ностальгией вспоминаю времена моего детства, когда у нас и правда +25 - была максимальная температура летом. Раньше +25 °C реально казались вершиной жары, когда можно было весь день пропадать на. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru