Circle/Arc drawing to pixmap

Tweet blitzmax graphics code-archives algorithms
(Posted 2 years ago)

This code will draw circles and arcs onto pixmaps. Just use Circle(Pixmap:TPixmap, xoff:int, yoff:int, radius:int, color:int, arcbegin:float = 0, arcend:float = 360, steps:int = 6)
Pixmap is the pixmap in which you will be drawing the circle
xoff, yoff will be the center of the circle
color is in the format ARGB
arcbegin, arcend is the beginning angle and ending angle of the arc you wish to draw.
steps is the angle added each step. A higher value will give a more polygon look, a lower value will give a smoother arc look.

The Line function is a modified version of Besenham's LineDraw routine (integer math only) by ImaginaryHuman

``````'This functiom uses the Bresenham algorithm for drawing a line.  The code below is a
' slightly modified version of [codearc 1465] by ImaginaryHuman
Function line(pixmap:TPixmap,x1:Int,y1:Int,x2:Int,y2:Int,color:Int)
'Draws a line of individual pixels from X1,Y1 to X2,Y2 at any angle
Local Steep:Int=Abs(Y2-Y1) > Abs(X2-X1)         'Boolean
If Steep
Local Temp:Int=X1; X1=Y1; Y1=Temp       'Swap X1,Y1
Temp=X2; X2=Y2; Y2=Temp     'Swap X2,Y2
EndIf
Local DeltaX:Int=Abs(X2-X1)     'X Difference
Local DeltaY:Int=Abs(Y2-Y1)     'Y Difference
Local Error:Int=0       'Overflow counter
Local X:Int=X1      'Start at X1,Y1
Local Y:Int=Y1
Local XStep:Int
Local YStep:Int
If X1<X2 Then XStep=1 Else XStep=-1 'Direction
If Y1<Y2 Then YStep=1 Else YStep=-1 'Direction
If Steep Then WritePixelSafe(pixmap,Y,X,color) Else WritePixelSafe(pixmap,X,Y,color)        'Draw
While X<>X2
X:+XStep        'Move in X
If (Error Shl 1)>DeltaX     'Would it overflow?
Y:+YStep        'Move in Y
Error=Error-DeltaX      'Overflow/wrap the counter
EndIf
If Steep Then WritePixelSafe(pixmap,Y,X,color) Else WritePixelSafe(pixmap,X,Y,color)        'Draw
Wend
End Function

'This function writes pixel color to the pixmap while also doing bounds checks
Function WritePixelSafe(pixmap:TPixmap,x:Int,y:Int,color:Int)
If x < 0 Or x >= pixmap.Width Or y < 0 Or y >= pixmap.Height Then Return
WritePixel(pixmap,x,y,color)
End Function

'This function will draw a circle or an arc.
'pixmap is the pixmap that you will be drawing to
'xoff, yoff are the offsets for the center of the circle.  to center the circle on the pixmap, you
'   would use something like xoff = pixmap.width/2 : yoff = pixmap.height/2
'color is the color you wish to plot in the format ARGB
'arcbegin, arcend are the beginning and ending of the arc. 0 is alligned to the positive x axis and
'   angle increases clockwise.
'step is the number of degrees the renderer should advance each step.  The higher the number, the more polygonal
'   the arc will look.  Using 90 will give you a square, using 120 will give you an equilateral triangle
Local first:Int = True
Local ox:Int, oy:Int, x:Int, y:Int
While arcend < arcbegin
arcend :+ 360
Wend
Local a:Float = arcbegin
While a < arcend
If Not first
line(pixmap,ox,oy,x,y,color)
Else
first = False
End If
ox = x
oy = y
a :+ steps
Wend
line(pixmap,ox,oy,x,y,color)
End Function

'example of usage
Graphics 400,400
Local pixmap:TPixmap = CreatePixmap(400,400,PF_RGBA8888)
pixmap.ClearPixels(\$FFFFFFFF) 'fill the pixmap with white

Circle(pixmap,100,100,100,\$FF000000) 'draw a black circle in the upper right corner
Circle(pixmap,200,200,200,\$FFFF0000,270,90) 'draw a red arc om the right
circle(pixmap,300,300,50,\$FF00FF00,0,360,72) 'draw a green pentagon

Cls
DrawPixmap pixmap,0,0 'render the pixmap to the screen
Flip

WaitKey() 'wait for a key to be pressed``````