Black hole (B+)

Miscellaneous Forums/Blitz Showcase/Black hole (B+)

Here's a little example of a black hole:
Graphics 800, 600, 32, 2
SetBuffer BackBuffer()
HidePointer

path$ = RequestFile("", "jpg")
Global image% = LoadImage(path$)
ResizeImage image%, GraphicsWidth(), GraphicsHeight()

While Not KeyHit(1)
	Cls
	DrawImage image%, 0, 0
	
	x% = MouseX()
	y% = MouseY()
	
	LightBreak(x%, y%, 100)
	Color 0, 0, 0
	Oval x% - 20, y% - 20, 40, 40
	Flip
Wend

Function LightBreak(x%, y%, r%)
	Local col%
	Local grab% = CreateImage(r% * 2, r% * 2)
	GrabImage(grab%, x% - r%, y% - r%)
	
	LockBuffer ImageBuffer(grab%)
	LockBuffer GraphicsBuffer()
	For yy% = 0 To r% * 2 - 1
		For xx% = 0 To r% * 2 - 1
			rr% = Sqr((x% - (x% + xx% - r%))^2 + (y% - (y% + yy% - r%))^2)
			aa% = GetAngle(r%, r%, xx%,yy%)
			If rr% < r% Then
				xxx% = r% + Cos(aa%) * (r% * Cos(90.0 * (Float rr% / r%)))
				yyy% = r% + Sin(aa%) * (r% * Cos(90.0 * (Float rr% / r%)))
				If  x% + r% * 2 - xx% - r% > 0 And  x% + r% * 2 - xx% - r% < GraphicsWidth() And y% + r% * 2 - yy% - r% > 0 And y% + r% * 2 - yy% - r% < GraphicsHeight()
					WritePixelFast x% + r% * 2 - xx% - r%, y% + r% * 2 - yy% - r%, ReadPixelFast(xxx%, yyy%, ImageBuffer(grab%))
				EndIf
			EndIf
		Next
	Next
	UnlockBuffer GraphicsBuffer()
	UnlockBuffer ImageBuffer(grab%)
	
	FreeImage grab%
End Function

Function GetAngle(x, y, targetx, targety)
	If targety < y Then
		If targetx < x Then
			Return Abs(ATan2(targetx - x,targety - y)) + 90
		Else
			Return 270+(180-Abs(ATan2(targetx - x,targety - y)))
		EndIf
	Else If targety => y Then
		Return Abs(ATan2(targetx - x,targety - y) - 90)
	EndIf
End Function


That's quite an interesting effect

Looks like an "inverted" fisheye effect, cool. :)

This one has alpha edges:
path$ = RequestFile("", "jpg")

Graphics 800, 600, 32, 2
SetBuffer BackBuffer()
HidePointer

Global image% = LoadImage(path$)
ResizeImage image%, GraphicsWidth(), GraphicsHeight()

While Not KeyHit(1)
	Cls
	DrawImage image%, 0, 0
	
	x% = MouseX()
	y% = MouseY()
	
	LightBreak(x%, y%, 100)
	Color 0, 0, 0
	Oval x% - 20, y% - 20, 40, 40
	Flip
Wend

Function LightBreak(x%, y%, r%, ar% = -1)
	If ar% = -1 Then ar% = r% * .4
	Local col%, red#, green#, blue#
	Local grab% = CreateImage(r% * 2, r% * 2)
	GrabImage(grab%, x% - r%, y% - r%)
	
	LockBuffer ImageBuffer(grab%)
	LockBuffer GraphicsBuffer()
	For yy% = 0 To r% * 2 - 1
		For xx% = 0 To r% * 2 - 1
			rr% = Sqr((x% - (x% + xx% - r%))^2 + (y% - (y% + yy% - r%))^2)
			aa% = GetAngle(r%, r%, xx%,yy%)
			If rr% < r% Then
				xxx% = r% + Cos(aa%) * (r% * Cos(90.0 * (Float rr% / r%)))
				yyy% = r% + Sin(aa%) * (r% * Cos(90.0 * (Float rr% / r%)))
				If  x% + r% * 2 - xx% - r% > 0 And  x% + r% * 2 - xx% - r% < GraphicsWidth() And y% + r% * 2 - yy% - r% > 0 And y% + r% * 2 - yy% - r% < GraphicsHeight()
					argb% = ReadPixelFast(xxx%, yyy%, ImageBuffer(grab%))
						red = (argb Shr 16) And $FF
						green = (argb Shr 8) And $FF
						blue = argb And $FF
					If rr% > r% - ar%
						argb% = ReadPixelFast(x% + r% * 2 - xx% - r%, y% + r% * 2 - yy% - r%, GraphicsBuffer())
							DebugLog (Float (r% - rr%) / ar%)
							red = red + (Float ((argb Shr 16) And $FF) - red) * (1.0 - Float (r% - rr%) / ar%)
							green = green + (Float ((argb Shr 8) And $FF) - green) * (1.0 - Float (r% - rr%) / ar%)
							blue = blue + (Float (argb And $FF) - blue) * (1.0 - Float (r% - rr%) / ar%)
					EndIf
					WritePixelFast x% + r% * 2 - xx% - r%, y% + r% * 2 - yy% - r%, (blue Or (green Shl 8) Or (red Shl 16) Or ($FF000000))
				EndIf
			EndIf
		Next
	Next
	UnlockBuffer GraphicsBuffer()
	UnlockBuffer ImageBuffer(grab%)
	
	FreeImage grab%
End Function

Function GetAngle(x, y, targetx, targety)
	If targety < y Then
		If targetx < x Then
			Return Abs(ATan2(targetx - x,targety - y)) + 90
		Else
			Return 270+(180-Abs(ATan2(targetx - x,targety - y)))
		EndIf
	Else If targety => y Then
		Return Abs(ATan2(targetx - x,targety - y) - 90)
	EndIf
End Function


A little slower refresh rate than the first example, but worth it. Nice.