Need 2d functions

Blitz3D Forums/Blitz3D Programming/Need 2d functions

_33(Posted 2008) [#1]
I'm specially interested in the line function. for some reason I can't figure it out! Just a function that plots pixel by pixel to make a line, to help me out in my project.

I just need simple functions to plot 2D things like:
- Line x1,y1,x2,y2
- circle x,y,radius
- box x1,y1,x2,y2

What I'll use this for is in banks, that is why I can't use internal drawing functions. It's for my character based engine.


_33(Posted 2008) [#2]
Found this bit of code already: http://www.blitzbasic.com/codearcs/codearcs.php?code=227

But to make circles, it's gonna be hard for my brain!


Panno(Posted 2008) [#3]
Graphics 800,600,32,3
SetBuffer FrontBuffer()
midx = 300
midy = 300
sizex = 200
sizey = 200
Color 222,222,222
For a= 1 To 360 Step 1
Rect midx+sizex*Sin(a),midy+sizey*Cos(a) ,2,2
Next
WaitKey()


circle , and ellypse routine for easy use


_33(Posted 2008) [#4]
Can't use Rect, sorry Panno. But, I'll probably go with something similar.

Allright, got the line drawing figured out. Not antialiased, but I don,t need that anyway. I took the Antialiased lines code and tailored it for my needs. Finally I will take the code and adapt it to work with banks.
Graphics 320,240,32,2

For i=0 To 360 Step 5
	dx = 180*Sin(i)
	dy = 160*Cos(i)
	Line2(160+dx,120+dy,160-dx,120-dy)
Next
WaitKey()
End

Function Line2(x1%, y1%, x2%, y2%)
	Local xd#
	Local yd#

	If (x1 > x2) Or (y1 > y2) Then
		tmp = x1: x1 = x2: x2 = tmp
		tmp = y1: y1 = y2: y2 = tmp
	EndIf
	xd = x2-x1
	yd = y2-y1
	If (Abs(xd) >= Abs(yd)) Then
		grad# = yd*65536/xd
		yf = y1*65536
		For x=x1 To x2
			y = yf Sar 16
			If (x Mod 320) = Fast_ABS(x) And (y Mod 240) = Fast_ABS(y) Then
				Plot x ,y
			EndIf
			yf = yf + grad		
		Next
	Else
		grad# = xd*65536/yd
		xf = x1*65536
		For y=y1 To y2
			x = xf Sar 16
			If (x Mod 320) = Fast_ABS(x) And (y Mod 240) = Fast_ABS(y) Then
				Plot x,y
			EndIf
			xf = xf + grad		
		Next
	EndIf
End Function

Function Fast_ABS%(value%)
	Return value And $7FFFFFFF
End Function



Panno(Posted 2008) [#5]
plot maybe or the use the line command ?

a gimmick for u


Graphics 800,600,32,3
midx = 300
midy = 300
sizex = 200
sizey = 200
Color 222,222,222
Const abst = 90
;20,40,60,90,120
For a= 0 To 359 Step abst
xo = midx+sizex*Sin(a-abst)
yo =midy+sizey*Cos(a-abst)
Line midx+sizex*Sin(a),midy+sizey*Cos(a) ,xo,yo
Next
Flip
WaitKey()


_33(Posted 2008) [#6]
Can't use Lines, Rect, only Plot... Since the routine will be modified to work with banks.


Terry B.(Posted 2008) [#7]
circle? Like this?
Graphics 640,480,0,2
Radius=10
Midx=320:Midy=240
For a=0 To 359
	Plot Sin(a)*Radius+midx,Cos(a)*radius+midy
Next 
WaitKey()
End 





_33(Posted 2008) [#8]
It's good for a small radius, but as soon as you make a circle bigger than say a radius of 50, you start missing some pixels. But I think I have a good idea with stepping relative to the radius.

I'm basically trying to build a small 2D graphics library using the plot command (easier to translate when using PokeByte (later on).

EDIT: This flood fill routine might come in handy :)
http://www.blitzbasic.com/codearcs/codearcs.php?code=50


Ross C(Posted 2008) [#9]
Wouldn't WritePixelFast be far quicker? Or even just WritePixel?


_33(Posted 2008) [#10]
Ross C. It doesn't matter if it's writePixel fast with a LockBuffer, or if it's Plot. The code is migrated into new functions here, where I use PokeByte instead.

EDIT: And the Disc :)
Graphics 800,600,0,2
SetBuffer FrontBuffer()
draw_disc(400, 300, 100, 200)
WaitKey()

Function draw_disc(midx, midy, sizex, sizey)
	Local inc# = 36.0 / Float sizex
	Local angle# = 0
	old_col_rad = 0
	While angle <= 180.99
		col_rad = sizex*Cos(angle)
		row_rad = sizey*Sin(angle)
	
		col = midx + col_rad
		row1 = midy - row_rad
		row2 = midy + row_rad
		If col_rad <> old_col_rad
			For row = row1 To row2
				Plot col,row ; replaced by a PokeByte for use with a bank
			Next
			old_col_rad = col_rad
			VWait ; just to see how it is drawn
		EndIf
		angle = angle + inc
	Wend
End Function



Yan(Posted 2008) [#11]
Bresenham's circle algorithm


_33(Posted 2008) [#12]
OK, I got:
- Line Draw
- Box outline
- Box filled
- Elipse
- Disc

What I need now is the FLOOD FILL implemented. I found one in the archive, but it is rather complex for me. I'll try to get my head wrapped around it another day.

EDIT: Thanks Yan for the link, good article. Don't know if I have the patience to learn this method thoe but maybe I'll try to implement it some day.
http://www.blitzbasic.com/codearcs/codearcs.php?code=2157

EDIT2: Here's my pimped up FloodFill, ready to be transformed for usage with banks :)
Graphics 800,600,0,2
Global Image = LoadImage("apple_logo_640x480.jpg") ; <---- put image filename here
SetBuffer BackBuffer()
SeedRnd MilliSecs()
While Not KeyDown(1)
	Cls
	If MouseHit(1) Then FloodFill(Image,MouseX(),MouseY(),Rand(255),Rand(255),Rand(255))
	DrawImage Image,0,0
	Color 255,255,255
	Plot MouseX(),MouseY()
	Flip
Wend
End


Type Pixel
	Field X,Y
End Type

Function FloodFill(FillImage, Fill_X, Fill_Y, FR, FG, FB)
	Local width% = ImageWidth(FillImage)
	Local height% = ImageHeight(FillImage)

	If Fill_X < 0 Or Fill_X > width - 1 Or Fill_Y < 0 Or Fill_Y > height - 1
		Return ; Coords ouside image boundaries
	EndIf

	Local CurrentBuffer = GraphicsBuffer()
	SetBuffer ImageBuffer(FillImage)
	LockBuffer

	Local Current_RGB% = ReadPixelFast(Fill_X, Fill_Y)

	Local RGB% = FB + FG Shl 8 + FR Shl 16
	Pixel.Pixel = New Pixel
	Pixel\X = Fill_X
	Pixel\Y = Fill_Y
	WritePixelFast Pixel\X,Pixel\Y,RGB

	Repeat
		Local PixelsRemaining = False
		For Pixel.Pixel = Each Pixel
			PixelX = Pixel\X
			PixelY = Pixel\Y
			PixelLeft = False
			PixelAbove = False
			PixelRight = False
			PixelBelow = False
			If Pixel\X > 0;check left
				If Current_RGB = ReadPixelFast(Pixel\X - 1,Pixel\Y) Then
					PixelLeft = True
					PixelsRemaining = True
				EndIf
			EndIf
			If Pixel\Y > 0;check above
				If Current_RGB = ReadPixelFast(Pixel\X,Pixel\Y - 1) Then
					PixelAbove = True
					PixelsRemaining = True
				EndIf
			EndIf
			If Pixel\X < width - 1;check right
				If Current_RGB = ReadPixelFast(Pixel\X + 1,Pixel\Y) Then
					PixelRight = True
					PixelsRemaining = True
				EndIf
			EndIf
			If Pixel\Y < height - 1;check below
				If Current_RGB = ReadPixelFast(Pixel\X,Pixel\Y + 1) Then
					PixelBelow = True
					PixelsRemaining = True
				EndIf
			EndIf
			Delete Pixel
			If PixelLeft = True
				Pixel.Pixel = New Pixel
				Pixel\X = PixelX - 1
				Pixel\Y = PixelY
				PixelLeft = False
				WritePixelFast Pixel\X,Pixel\Y,RGB
			EndIf
			If PixelAbove = True
				Pixel.Pixel = New Pixel
				Pixel\X = PixelX
				Pixel\Y = PixelY - 1
				PixelAbove = False
				WritePixelFast Pixel\X,Pixel\Y,RGB
			EndIf
			If PixelRight = True
				Pixel.Pixel = New Pixel
				Pixel\X = PixelX + 1
				Pixel\Y = PixelY
				PixelRight = False
				WritePixelFast Pixel\X,Pixel\Y,RGB
			EndIf
			If PixelBelow = True
				Pixel.Pixel = New Pixel
				Pixel\X = PixelX
				Pixel\Y = PixelY + 1
				PixelBelow = False
				WritePixelFast Pixel\X,Pixel\Y,RGB
			EndIf
		Next
	Until PixelsRemaining = False
	UnlockBuffer
	SetBuffer CurrentBuffer
End Function



Ross C(Posted 2008) [#13]
So, your drawing directly to the screen buffer, using poke byte?


_33(Posted 2008) [#14]
I'm implementing 2D doodle type functions to work inside Grid terminal. The functions will give extra control on creating fancy art on text screens. Since Grid Terminal has about 25 layers of address space for each page, all of the doodle functions will have access to them. So, for example, if I want to create a rainbow color for the text background, all I have to do is make a bunch of elipses of different color indexes on layer 2 (which is background).

The FloodFill is the last one I'm implementing now :)

I've opened a thead about Grid Terminal here, if you want to check it out:
http://www.blitzbasic.com/Community/posts.php?topic=79214


Ross C(Posted 2008) [#15]
Ah, very interesting. Sorry for mentioning the writepixel stuff, i didn't realise what you were up to :o)


_33(Posted 2008) [#16]
I've opened up the source code for this project right here: http://www.blitzbasic.com/Community/posts.php?topic=79214

Anyhow thanks for the help for the 2D stuff guys :)