Code archives/Graphics/Draw Filled Ellipse Row by Row with Integer Math
This code has been declared by its author to be Public Domain code.
Download source code
| |||||
Draws a filled ellipse using (mostly) integer math, one row at a time. It doesn't use any trigonometry and only has two lines where it needs to set things up using a floating point operation. The rows are filled individually with separate calls to DrawRect. In this example a filled ellipse is drawn at the same time as a hollow ellipse, so there is some overlap of the pixels. Comment out the Plot calls to see only the filled ellipse, or comment out the DrawRect calls to see only the hollow ellipse. | |||||
'Midpoint ellipse algorithm Strict Graphics 640,480,0 Local xCenter:Int=320 Local yCenter:Int=240 Local Rx,Ry:Int Local p,px,py,x,y,prevy:Int Local Rx2,Ry2,twoRx2,twoRy2:Int Local pFloat:Float Repeat Cls If MouseDown(1) xCenter=MouseX() yCenter=MouseY() EndIf Rx=Abs(xCenter-MouseX()) Ry=Abs(yCenter-MouseY()) DrawText String(Rx)+" x "+String(Ry),20,20 Rx2=Rx*Rx Ry2=Ry*Ry twoRx2=Rx2 Shl 1 twoRy2=Ry2 Shl 1 'Region 1 x=0 y=Ry SetColor $FF,$88,$00 DrawRect xCenter-Rx,yCenter,Rx Shl 1,1 SetColor $FF,$FF,$FF Plot xCenter+Rx,yCenter Plot xCenter-Rx,yCenter Plot xCenter,yCenter-Ry Plot xCenter,yCenter+Ry pFloat=(Ry2-(Rx2*Ry))+(0.25*Rx2) p=Int(pFloat + (Sgn(pFloat)*0.5)) px=0 py=twoRx2*y While px<py-1 prevy=y x:+1 px:+twoRy2 If p>=0 y:-1 py:-twoRx2 EndIf If p<0 Then p:+Ry2+px Else p:+Ry2+px-py If y<prevy And px<py-1 SetColor $FF,$88,$00 DrawRect xCenter-x,yCenter+y,x Shl 1,1 DrawRect xCenter-x,yCenter-y,x Shl 1,1 SetColor $FF,$FF,$FF Plot xCenter+x,yCenter+y Plot xCenter-x,yCenter+y Plot xCenter+x,yCenter-y Plot xCenter-x,yCenter-y EndIf Wend 'Region 2 pFloat=(Ry2*(x+0.5)*(x+0.5))+(Rx2*(y-1.0)*(y-1.0))-(Rx2*(Float(Ry2))) p=Int(pFloat + (Sgn(pFloat)*0.5)) y:+1 While y>1 y:-1 py:-twoRx2 If p<=0 x:+1 px:+twoRy2 EndIf If p>0 Then p:+Rx2-py Else p:+Rx2-py+px SetColor $FF,$88,$00 DrawRect xCenter-x,yCenter+y,x Shl 1,1 DrawRect xCenter-x,yCenter-y,x Shl 1,1 SetColor $FF,$FF,$FF Plot xCenter+x,yCenter+y Plot xCenter-x,yCenter+y Plot xCenter+x,yCenter-y Plot xCenter-x,yCenter-y Wend Flip Until KeyHit(KEY_ESCAPE) End |
Comments
| ||
I think it would have been more intelligent to have posted this as something like "Primitive Drawing Functions". On another note, if you're calling 'Plot' a lot in these functions (and it seems you are), you might end up with a lot of slowdown if the calling function is called a lot. |
| ||
well the buffer can be locked as per my fast circle post in the code archives. |
| ||
Oh yes, "Primitive Drawing Functions" is soooooo much more descriptive. :-) Edit: He's uisng PLOT? What's the point of even using integer math then? There's 90% of your slowdown there. Lock the buffer then use writepixelfast. Even if you lock the buffer before calling plot, it would still have to check to see if the buffer is locked. Also, I question whether integer math would actually speed things up on modern PC's. But it probably wouldn't be slower than float either. The main question is whether this function is faster than the internal Blitz functions for drawing those things? If it is, then Mark should be ashmed of himself! :-) Code would still be useful for those instances where you need to draw circles AND know where all the pixels go though. Like if you wanted to draw a circle in an array. Or if you wanted to draw a textured circle. |
| ||
He's uisng PLOT? What's the point of even using integer math then? There's 90% of your slowdown there. Lock the buffer then use writepixelfast. This is BMAX code! He just forgot to change the category. ;o) |
| ||
I didn't mean *just* lock the buffer, it implied using WritePixelFast, esp. if you check my fast circle post ... |
| ||
Hi guys. This is not meant to be in the .bb code section, it is a BlitzMax routine, sorry. Also since I am the one posting the code, I get to decide what it's called ;-) However, I've now edited and uploaded a modified version which only fills each row once, so it's faster and works with other blend modes properly. I do agree that Plot and DrawRect are not efficient ways of rendering the actual graphics. Those instructions are really irrelevant. You can use the data generated in whatever way you wish. I am using them with a custom bitmap type writing to main memory by writing Integers directly to memory pointers. I just put the plots etc in there to be friendly and to show that it works. |
| ||
Thanks to BRL for moving this to the BMX section. |
Code Archives Forum