Need 2d functions
Blitz3D Forums/Blitz3D Programming/Need 2d functions| 
 | ||
| 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. | 
| 
 | ||
| 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! | 
| 
 | ||
| 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 | 
| 
 | ||
| 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 | 
| 
 | ||
| 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() | 
| 
 | ||
| Can't use Lines, Rect, only Plot...  Since the routine will be modified to work with banks. | 
| 
 | ||
| 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 | 
| 
 | ||
| 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 | 
| 
 | ||
| Wouldn't WritePixelFast be far quicker? Or even just WritePixel? | 
| 
 | ||
| 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 | 
| 
 | ||
| Bresenham's circle algorithm | 
| 
 | ||
| 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
 | 
| 
 | ||
| So, your drawing directly to the screen buffer, using poke byte? | 
| 
 | ||
| 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 | 
| 
 | ||
| Ah, very interesting. Sorry for mentioning the writepixel stuff, i didn't realise what you were up to :o) | 
| 
 | ||
| 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 :) |