You may already know Metaballs from other popular Demos. I just tried this in DBP. 3D was a bit to slow, but I'm working on it, so im made it in 2D. It's based on the Marching Cube Algorithm.
The Code is not optimized and the Demo a bit monochrome, I know.
I hope you like it though.
Set window off : Sync on : Sync rate 0 : Sync : Set display mode 800, 600, 32 : Randomize Timer() : Global MBCount = 6 : Dim Grid(80, 60) As float : Dim TLT(15, 8) As integer : Dim Metaballs(MBCount - 1, 2) As float : Dim Path(MBCount - 1, 9, 3) As float : pf As Float : pi As integer : For i = 0 To MBCount - 1 : Metaballs(i, 0) = Rnd(800)/10.0 : Metaballs(i, 1) = Rnd(600)/10.0 : Metaballs(i, 2) = 1.5 : Next : For i = 1 To 5 : null = Make vector2(i) : Next
For i = 0 To MBCount - 1 : For j = 0 To 9 : v# = Rnd(3600)*0.1 : Path(i, j, 0) = Rnd(800)/10.0 : Path(i, j, 1) = Rnd(600)/10.0 : Path(i, j, 2) = Cos(v#) : Path(i, j, 3) = Sin(v#) : Next : Path(i, 9, 0) = Path(i, 0, 0) : Path(i, 9, 1) = Path(i, 0, 1) : Path(i, 9, 2) = Path(i, 0, 2) : Path(i, 9, 3) = Path(i, 0, 3) : Next : For i = 0 To 15 : For j = 0 To 8 : Read TLT(i, j) : Next : Next
Ink 0, 0 : Do : Cls 0xA0A0A0 : For i = 0 To MBCount - 1 : Inc pf, 0.002 : If pf > 1 : Inc pi : pf = 0 : Endif : If pi = 9 : pi = 0 : Endif : Set vector2 1, Path(i, pi, 0), Path(i, pi, 1) : Set vector2 2, Path(i, pi, 2), Path(i, pi, 3) : Set vector2 3, Path(i, pi + 1, 0), Path(i, pi + 1, 1) : Set vector2 4, Path(i, pi + 1, 2), Path(i, pi + 1, 3) : Hermite vector2 5, 1, 2, 3, 4, pf : Metaballs(i, 0) = X vector2(5) : Metaballs(i, 1) = Y vector2(5) : Next
For y = 0 To 60 : For x = 0 To 80 : Grid(x, y) = SumMB(x, y) : Next : Next : Lock pixels : For y = 1 To 58 : For x = 1 To 78 : Dot x*10, y*10 : Index = 0 : If Grid(x + 0, y + 0) > 1 : Inc Index, 1 : Endif : If Grid(x + 1, y + 0) > 1 : Inc Index, 2 : Endif : If Grid(x + 1, y + 1) > 1 : Inc Index, 4 : Endif : If Grid(x + 0, y + 1) > 1 : Inc Index, 8 : Endif : i = 0 : b = 0 : While TLT(Index, i) > -1 : Select TLT(Index, i)
Case 1 : xn# = x + (1 - Grid(x + 0, y + 0))/(Grid(x + 1, y + 0) - Grid(x + 0, y + 0)) : yn# = y : Endcase : Case 2 : xn# = x + 1 : yn# = y + (1 - Grid(x + 1, y + 0))/(Grid(x + 1, y + 1) - Grid(x + 1, y + 0)) : Endcase : Case 3 : xn# = x + (1 - Grid(x + 0, y + 1))/(Grid(x + 1, y + 1) - Grid(x + 0, y + 1)) : yn# = y + 1 : C = 0xFF00 : Endcase : Case 4 : xn# = x : yn# = y + (1 - Grid(x + 0, y + 0))/(Grid(x + 0, y + 1) - Grid(x + 0, y + 0)) : Endcase : Endselect
If b = 0 : xt# = xn# : yt# = yn# : b = 1 : Else : Line xt#*10, yt#*10, xn#*10, yn#*10 : Line xt#*10 + 1, yt#*10, xn#*10 + 1, yn#*10 : Line xt#*10, yt#*10 + 1, xn#*10, yn#*10 + 1 : b = 0 : Endif : Inc i : Endwhile : Next : Next : Unlock pixels : Sync : Loop
Function SumMB(x As float, y As float)
For i = 0 To MBCount - 1 : Inc v#, Sqrt(Metaballs(i, 2)^2/((x - Metaballs(i, 0))^2 + (y - Metaballs(i, 1))^2)) : Next
Endfunction v#
Data -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 4, -1, -1, -1, -1, -1, -1, -1, 1, 2, -1, -1, -1, -1, -1, -1, -1, 2, 4, -1, -1, -1, -1, -1, -1, -1, 2, 3, -1, -1, -1, -1, -1, -1, -1, 1, 2, 2, 3, 3, 4, 4, 1, -1, 3, 1, -1, -1, -1, -1, -1, -1, -1, 3, 4, -1, -1, -1, -1, -1, -1, -1, 3, 4, -1, -1, -1, -1, -1, -1, -1, 3, 1, -1, -1, -1, -1, -1, -1, -1, 1, 2, 2, 3, 3, 4, 4, 1, -1, 2, 3, -1, -1, -1, -1, -1, -1, -1, 2, 4, -1, -1, -1, -1, -1, -1, -1, 1, 2, -1, -1, -1, -1, -1, -1, -1, 1, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
I may improve this the next time. I have the space.
Oh, and here the uncompressed Code:
Set window off
Sync on : Sync rate 0 : Sync
Set display mode 800, 600, 32
Randomize Timer()
Type TMB
x As float
y As float
r As float
Endtype
Type TP
px As float
py As float
tx As float
ty As float
Endtype
MBCount = 6
Dim Grid(80, 60) As float
Dim TLT(15, 8) As integer
Dim Metaballs(MBCount - 1) As TMB
Dim Path(MBCount - 1, 9) As TP
pf As Float
pi As integer
For i = 0 To Array count(Metaballs(0))
Metaballs(i).x = Rnd(800)/10.0
Metaballs(i).y = Rnd(600)/10.0
Metaballs(i).r = 1.5
Next
For i = 1 To 5
null = Make vector2(i)
Next
For i = 0 To Array count(Metaballs(0))
For j = 0 To 9
v# = Rnd(3600)*0.1
Path(i, j).px = Rnd(800)/10.0
Path(i, j).py = Rnd(600)/10.0
Path(i, j).tx = Cos(v#)
Path(i, j).ty = Sin(v#)
Next
Path(i, 9) = Path(i, 0)
Next
For i = 0 To 15 : For j = 0 To 8 : Read TLT(i, j) : Next : Next
Ink 0, 0
Do
Cls 0xA0A0A0
For i = 0 To Array count(Metaballs(0))
Inc pf, 0.002
If pf > 1 : Inc pi : pf = 0 : Endif
If pi = 9 Then pi = 0
Set vector2 1, Path(i, pi).px, Path(i, pi).py
Set vector2 2, Path(i, pi).tx, Path(i, pi).ty
Set vector2 3, Path(i, pi + 1).px, Path(i, pi + 1).py
Set vector2 4, Path(i, pi + 1).tx, Path(i, pi + 1).ty
Hermite vector2 5, 1, 2, 3, 4, pf
Metaballs(i).x = X vector2(5)
Metaballs(i).y = Y vector2(5)
Next
For y = 0 To 60
For x = 0 To 80
Grid(x, y) = SumMB(x, y)
Next
Next
Lock pixels
For y = 1 To 58
For x = 1 To 78
Dot x*10, y*10
Index = 0
If Grid(x + 0, y + 0) > 1 Then Inc Index, 1
If Grid(x + 1, y + 0) > 1 Then Inc Index, 2
If Grid(x + 1, y + 1) > 1 Then Inc Index, 4
If Grid(x + 0, y + 1) > 1 Then Inc Index, 8
i = 0
b = 0
While TLT(Index, i) > -1
Select TLT(Index, i)
Case 1
xn# = x + (1 - Grid(x + 0, y + 0))/(Grid(x + 1, y + 0) - Grid(x + 0, y + 0))
yn# = y
Endcase
Case 2
xn# = x + 1
yn# = y + (1 - Grid(x + 1, y + 0))/(Grid(x + 1, y + 1) - Grid(x + 1, y + 0))
Endcase
Case 3
xn# = x + (1 - Grid(x + 0, y + 1))/(Grid(x + 1, y + 1) - Grid(x + 0, y + 1))
yn# = y + 1
C = 0xFF00
Endcase
Case 4
xn# = x
yn# = y + (1 - Grid(x + 0, y + 0))/(Grid(x + 0, y + 1) - Grid(x + 0, y + 0))
Endcase
Endselect
If b = 0
xt# = xn#
yt# = yn#
b = 1
Else
Line xt#*10, yt#*10, xn#*10, yn#*10
Line xt#*10 + 1, yt#*10, xn#*10 + 1, yn#*10
Line xt#*10, yt#*10 + 1, xn#*10, yn#*10 + 1
b = 0
Endif
Inc i
Endwhile
Next
Next
Unlock pixels
Sync
Loop
Function SumMB(x As float, y As float)
For i = 0 To Array count(Metaballs(0))
Inc v#, Sqrt(Metaballs(i).r^2/((x - Metaballs(i).x)^2 + (y - Metaballs(i).y)^2))
Next
Endfunction v#
Data -1, -1, -1, -1, -1, -1, -1, -1, -1 `Case 0
Data 1, 4, -1, -1, -1, -1, -1, -1, -1 `Case 1
Data 1, 2, -1, -1, -1, -1, -1, -1, -1 `Case 2
Data 2, 4, -1, -1, -1, -1, -1, -1, -1 `Case 3
Data 2, 3, -1, -1, -1, -1, -1, -1, -1 `Case 4
Data 1, 2, 2, 3, 3, 4, 4, 1, -1 `Case 5
Data 3, 1, -1, -1, -1, -1, -1, -1, -1 `Case 6
Data 3, 4, -1, -1, -1, -1, -1, -1, -1 `Case 7
Data 3, 4, -1, -1, -1, -1, -1, -1, -1 `Case 8
Data 3, 1, -1, -1, -1, -1, -1, -1, -1 `Case 9
Data 1, 2, 2, 3, 3, 4, 4, 1, -1 `Case 10
Data 2, 3, -1, -1, -1, -1, -1, -1, -1 `Case 11
Data 2, 4, -1, -1, -1, -1, -1, -1, -1 `Case 12
Data 1, 2, -1, -1, -1, -1, -1, -1, -1 `Case 13
Data 1, 4, -1, -1, -1, -1, -1, -1, -1 `Case 14
Data -1, -1, -1, -1, -1, -1, -1, -1, -1 `Case 15
It's not identical, because I was using types before compressing :-(