Page 1 of 1

Marching Squares

Posted: Tue Feb 01, 2022 11:18 pm
by Mr.L
I couldn't find a marching squares example in this forum, so i decided to write one.
Wikipedia:
Marching squares is a computer graphics algorithm that generates contours for a two-dimensional scalar field (rectangular array of individual numerical values)

Code: Select all

EnableExplicit

Structure MetaBall
	x.f
	y.f
	xd.f
	yd.f
	f.f
EndStructure

#Wid = 600
#Hig = 600
#Res = 60
#Size =  #Wid / #Res
#Threshold = 1.0
#NrMetaBalls = 25

Global Dim Metaball.MetaBall(#NrMetaBalls)
Global Dim Field.f(#Res, #Res)

Procedure Initialize()
	Protected n
	
	OpenWindow(0, 0, 0, #Wid, #Hig, "Marching Squares")
	CanvasGadget(0, 0, 0, #Wid, #Hig)

	For n = 0 To #NrMetaBalls - 1
 		Metaball(n)\x = #Wid / 2
 		Metaball(n)\y = #Hig / 2
		Metaball(n)\f = (n + 1) * 750
	Next
EndProcedure

Procedure Update()
	Protected x, y, xb.f, yb.f, f.f
	Protected n, t.f = ElapsedMilliseconds() * 0.00002

	For n = 0 To #NrMetaBalls - 1
		With Metaball(n)
			\xd = Cos(t * (n + 1))
			\yd = Sin(t * (n + 1))
			\x + (#wid * 0.5 - \x) * 0.08 + Sin(\xd) * \yd * (n + 1)
			\y + (#hig * 0.5 - \y) * 0.08 + Cos(\yd) * \xd * (n + 1)
		EndWith
	Next
	
 	For y = 0 To #Res - 1
 		yb = y * #Size
 		For x = 0 To #Res - 1
 			xb = x * #Size
			f = 0
			For n = 0 To #NrMetaBalls - 1
				f + 1.0 / (Pow(Metaball(n)\x - xb, 2) + Pow(Metaball(n)\y - yb, 2) + 0.000000001) * Metaball(n)\f
			Next
			Field(x, y) = f  / #NrMetaBalls
		Next
	Next
EndProcedure

Macro I(a_, b_)
	((1 - f#b_) / (f#a_ - f#b_))
EndMacro

Procedure MarchingSquares()
	Protected x, y, corner
	Protected.f f0, f1, f2, f3
	
	StartVectorDrawing(CanvasVectorOutput(0))
	VectorSourceColor(RGBA(55,55,55,255))
	FillVectorOutput()

 	ScaleCoordinates(DesktopScaledX(#Size), DesktopScaledY(#Size))
 	VectorSourceColor(RGBA(255,255,255,255))
 	
	For y = 0 To #Res - 2
		For x = 0 To #Res - 2
			f0 = Field(x, y)
			f1 = Field(x + 1, y)
			f2 = Field(x, y + 1)
			f3 = Field(x + 1, y + 1)

			corner = 0
			If f0 > #Threshold
				corner | %1000
			EndIf
			If f1 > #Threshold
				corner | %0100
			EndIf
			If f2 > #Threshold
				corner | %0010
			EndIf
			If f3 > #Threshold
				corner | %0001
			EndIf
			
			If corner > %0000 And corner < %1111
				Select corner
					Case %0001
 						MovePathCursor(x + I(3,2), y + 1)
 						AddPathLine(x + 1, y + I(3,1))
  					Case %0010
 						MovePathCursor(x, y + I(2,0))
 						AddPathLine(x + I(3,2), y + 1)
					Case %0011
						MovePathCursor(x, y + I(2,0))
						AddPathLine(x + 1, y + I(3,1))
					Case %0100
						MovePathCursor(x + I(1,0), y)
						AddPathLine(x + 1, y + I(3,1))
 					Case %0101
						MovePathCursor(x + I(1,0), y)
						AddPathLine(x + I(3,2), y + 1)
					Case %0110
						MovePathCursor(x + I(1,0), y)
						AddPathLine(x + 1, y + I(3,1))
						MovePathCursor(x, y + I(2,0))
 						AddPathLine(x + I(3,2), y + 1)
					Case %0111
						MovePathCursor(x, y + I(2,0))
						AddPathLine(x + I(1,0), y)
					Case %1000
						MovePathCursor(x, y + I(2, 0))
						AddPathLine(x + I(1,0), y)
					Case %1001
						MovePathCursor(x, y + I(2, 0))
						AddPathLine(x + I(1,0), y)
						MovePathCursor(x + I(3,2), y + 1)
 						AddPathLine(x + 1, y + I(3,1))
					Case %1010
						MovePathCursor(x + I(1,0), y)
						AddPathLine(x + I(3,2), y + 1)
					Case %1011
						MovePathCursor(x + I(1,0), y)
						AddPathLine(x + 1, y + I(3,1))
					Case %1100
						MovePathCursor(x, y + I(2,0))
						AddPathLine(x + 1, y + I(3,1))
					Case %1101
						MovePathCursor(x, y + I(2,0))
						AddPathLine(x + I(3,2), y + 1)
					Case %1110
						MovePathCursor(x + I(3,2), y + 1)
 						AddPathLine(x + 1, y + I(3,1))
 				EndSelect
 			EndIf
 		Next
 	Next
 	
	StrokePath(0.35)
	StopVectorDrawing()
EndProcedure

Initialize()

Repeat
	Update()
	MarchingSquares()
 	Delay(25)
Until WindowEvent() = #PB_Event_CloseWindow

Re: Marching Squares

Posted: Tue Feb 01, 2022 11:31 pm
by STARGĂ…TE
Nice code dome.
I didn't know that so little code could create such an effect.

Pretty useful for a pixel engine.

Re: Marching Squares

Posted: Wed Feb 02, 2022 8:33 am
by Caronte3D
Yeah! 2D Metaballs! 8)
Thanks for sharing! :wink:

Re: Marching Squares

Posted: Thu Feb 03, 2022 7:30 pm
by Kwai chang caine
Nice !!!
Thanks for sharing 8)