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 :) |