You are not logged in or registered. Please login or register to use the full functionality of this board...
SIGN IN Join Our Community For FREE


Bresenham Like Ellipse Algo
05-27-2017, 12:35 PM
Post: #1
 (Print Post)
Bresenham Like Ellipse Algo
Here's the Bresenham like algo for ellipses. It's very fast can be used to roll your own ellipse() function.


The PDF with explanation and Pascal source code:
https://dai.fmph.uniba.sk/upload/0/01/Ellipse.pdf


Here's my implementation in BlitzPlus:
Code Snippet: [Select]
;Ellipse:
;Source:
;    http://homepage.smc.edu/kennedy_john/papers.htm
;    http://homepage.smc.edu/kennedy_john/belipse.pdf

;    A Fast Bresenham Type Algorithm For Drawing Ellipses
;    by
;    John Kennedy

;    Blitzplus/Blitz 3D port by Andy_A


AppTitle "Bresenham Ellipse"
Graphics 800,600,32,2
SetBuffer BackBuffer()


numRepeats% = 100
fill% = 1
LockBuffer GraphicsBuffer()

st = MilliSecs()
For i = 1 To numRepeats    
    Ellipse(400, 300, 390, 290,$FFE020, fill)
Next
et1# = MilliSecs()-st

st = MilliSecs()        ;NOTE: Blitz Filled OVAL will *NOT* draw on Locked Buffer
For i = 1 To numRepeats
    Oval 10, 10, 780, 580, fill
Next
et2# = MilliSecs()-st

UnlockBuffer

Text 5,    5,"Avg/Ellipse: "+(et1/Float(numRepeats))+"ms"
Text 5,20,"   Avg/Oval: "+(et2/Float(numRepeats))+"ms"


Flip
WaitMouse()
End

Function Ellipse(CX%, CY%, XRadius%, YRadius%, colr%, fill%=0)
    Local X%, Y%
    Local XChange%, YChange%
    Local EllipseError%
    Local TwoASquare%, TwoBSquare%
    Local StoppingX%, StoppingY%
    Color (colr And $FF0000) Shr 16, (colr And $FF00) Shr 8, colr And $FF

    TwoASquare = (XRadius*XRadius) Shl 1
    TwoBSquare = (YRadius*YRadius) Shl 1
    X = XRadius
    Y = 0
    XChange = YRadius*YRadius*(1-(XRadius Shl 1))
    YChange = XRadius*XRadius
    EllipseError = 0
    StoppingX = TwoBSquare*XRadius
    StoppingY = 0

    While StoppingX >= StoppingY                 ; do {1st set of points, y' > -1}

        If fill > 0 Then
            Line(CX-X, CY+Y, CX+X, CY+Y)        ; used calc'd points to draw scan
            Line(CX-X, CY-Y, CX+X, CY-Y)        ; lines from opposite quadrants
        Else
            WritePixelFast(CX+X, CY+Y, colr)    ; {point in quadrant 1}
            WritePixelFast(CX-X, CY+Y, colr)    ; {point in quadrant 2}
            WritePixelFast(CX-X, CY-Y, colr)    ; {point in quadrant 3}
            WritePixelFast(CX+X, CY-Y, colr)    ; {point in quadrant 4}
        End If

        Y = Y + 1
        StoppingY = StoppingY + TwoASquare
        EllipseError = EllipseError + YChange
        YChange = YChange + TwoASquare

        If (EllipseError Shl 1) + XChange > 0 Then
            X = X - 1
            StoppingX = StoppingX - TwoBSquare
            EllipseError = EllipseError + XChange
            XChange = XChange + TwoBSquare
        End If
    Wend
    
    ;{ 1st set of points is done; start the 2nd set of points }
    X = 0
    Y = YRadius
    XChange = YRadius*YRadius
    YChange = XRadius*XRadius*(1 - (YRadius Shl 1))
    EllipseError = 0
    StoppingX = 0
    StoppingY = TwoASquare*YRadius

    While StoppingX <= StoppingY                 ;do {2nd set of points, y' < -1}

        If fill > 0 Then                    
            Line(CX-X, CY+Y, CX+X, CY+Y)        ; used calc'd points to draw scan
            Line(CX-X, CY-Y, CX+X, CY-Y)        ; lines from opposite quadrants
        Else
            WritePixelFast(CX+X, CY+Y, colr)    ; {point in quadrant 1}
            WritePixelFast(CX-X, CY+Y, colr)    ; {point in quadrant 2}
            WritePixelFast(CX-X, CY-Y, colr)    ; {point in quadrant 3}
            WritePixelFast(CX+X, CY-Y, colr)    ; {point in quadrant 4}
        End If

        X = X + 1
        StoppingX = StoppingX + TwoBSquare
        EllipseError = EllipseError + XChange
        XChange = XChange + TwoBSquare

        If (EllipseError Shl 1) + YChange > 0 Then
            Y = Y - 1
            StoppingY = StoppingY - TwoASquare
            EllipseError = EllipseError + YChange
            YChange = YChange + TwoASquare
        End If
    Wend
End Function
Find all posts by this user
Like Post



Forum Jump:


User(s) browsing this thread: 1 Guest(s)




QB64 Member Project - Martin Fractals version two
QB64 Member Project - Bowditch curve
QB64 Member Project - Color Rotating Text
QB64 Member Project - Score 4
QB64 Member Project - Dreamy Clock
QB64 Member Project - Othello
QB64 Member Project - Quarto
QB64 Member Project - Splatter
QB64 Member Project - Blokus
QB64 Member Project - Foursight
QB64 Member Project - Martin Fractals version four
QB64 Member Project - Kobolts Monopoly
QB64 Member Project - Isolation
QB64 Member Project - ARB Checkers
QB64 Member Project - Touche
QB64 Member Project - Exit
QB64 Member Project - Line Thickness
QB64 Member Project - RGB Color Wheel
QB64 Member Project - OpenGL Triangles
QB64 Member Project - Rotating Background
QB64 Member Project - Sabotage
QB64 Member Project - Pivot version two
QB64 Member Project - Overboard
QB64 Member Project - Connect Four
QB64 Member Project - Input
QB64 Member Project - Algeria Weather
QB64 Member Project - Domain
QB64 Member Project - Swirl
QB64 Member Project - Dakapo
QB64 Member Project - STxAxTIC 3D World
QB64 Member Project - Qubic
QB64 Member Project - Kings Valley verion one
QB64 Member Project - Spiro Roses
QB64 Member Project - Martin Fractals version one
QB64 Member Project - MAPTRIANGLE
QB64 Member Project - Spinning Color Wheel
QB64 Member Project - Kings Vallery version two
QB64 Member Project - 9 Board
QB64 Member Project - Rubix's Magic
QB64 Member Project - Color Triangles
QB64 Member Project - Inside Moves
QB64 Member Project - Martin Fractals version three
QB64 Member Project - Full Color LED Sign
QB64 Member Project - Point Blank
QB64 Member Project - Pivet version one
QB64 Member Project - Amazon
QB64 Member Project - Kings Court
QB64 Member Project - Basic Dithering
QB64 Member Project - Red Scrolling LED Sign