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

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

Запись от The trick размещена 23.12.2013 в 04:40
Показов 7174 Комментарии 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 Кб, 444 просмотров)
Метки 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 вне форума
 
Новые блоги и статьи
попытка написать игровой сервер на C++
pyirrlicht 29.04.2026
попытка написать игровой сервер на плюсах с открытым бесконечным миром. возможно получится прикрутить интерпретатор питон для кастомизации игровой логики. что есть на текущий момент:. . .
Контроль уникальности выбранного документа-основания при изменении реквизита
Maks 28.04.2026
Алгоритм из решения ниже разработан на примере нетипового документа "ЗаявкаНаРемонтСпецтехники", разработанного в КА2. Задача: уведомлять пользователя, если указанная заявка (документ-основание). . .
Благородство как наказание
Maks 24.04.2026
У хорошего человека отношения с женщинами всегда складываются трудно. А я человек хороший. Заявляю без тени смущения, потому что гордиться тут нечем. От хорошего человека ждут соответствующего. . .
Валидация и контроль данных табличной части документа перед записью
Maks 22.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа, разработанного в КА2. Задача: контроль и валидация данных табличной части документа перед записью с учетом регламента компании. . .
Отчёт о затраченных материалах за определенный период с макетом печатной формы
Maks 21.04.2026
Отчёт из решения ниже размещён в конфигурации КА2. Задача: разработка отчёта по затраченным материалам за определённый период, с возможностью вывода печатной формы отчёта с шапкой и подвалом. В. . .
Отчёт о спецтехнике находящейся в ремонте
Maks 20.04.2026
Отчёт из решения ниже размещен в конфигурации КА2. Задача: отобразить спецтехнику, которая на данный момент находится в ремонте. Есть нетиповой документ "Заявка на ремонт спецтехники" который. . .
Памятка для бота и "визитка" для читателей "Semantic Universe Layer (Слой семантической вселенной)"
Hrethgir 19.04.2026
Сгенерировано для краткого описания по случаю сборки и компиляции скелета серверного приложения. И пусть после этого скажут, что статьи сгенерированные AI - туфта и не интересно. И это не реклама -. . .
Запрет удаления строк ТЧ документа при определённом условии
Maks 19.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "Аккумуляторы", разработанного в конфигурации КА2. У данного документа есть ТЧ, в которой в зависимости от прав доступа. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru