Skip to content

Instantly share code, notes, and snippets.

@moritzuehling
Last active June 16, 2017 22:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save moritzuehling/790e64ab14de0579c302a2d489233e1e to your computer and use it in GitHub Desktop.
Save moritzuehling/790e64ab14de0579c302a2d489233e1e to your computer and use it in GitHub Desktop.
; Invariant: LockBuffer has been called on the currently targeted buffer.
Function AACircle(x#, y#, radius#, r, g, b)
; Which area do I need to scan?
Local minX = Floor(x - radius#), maxX = Ceil(x + radius#)
Local minY = Floor(y - radius#), maxY = Ceil(y + radius#)
; The distance between the circles (on the x / y axis, and total)
Local dx#, dy#, distance#
; How many pixels do their radii overlap?
Local overlap#, invOverlap#
; To calculate the overlap
Local radiDistance# = .5 + radius#
Local tr, tg, tb
Local oldColor, oldR, oldB, oldG
; We pre-calculate this to save it later.
Local defaultColor = (r Shl 16) + (g Shl 8) + (b)
; This is used in distance calclulations to correctly align the compared pixel
Local mx# = x# - .5, my# = y# - .5
; What is the big idea?
; We decide for each pixel if it's inside or outside the circle
; or on the border.
; To do this we imagine each pixel is a small cirlce of the radius .5
; which is an okay-ish approximation.
; Then we calculate by how much they would overlap
; and use that to approximate the color
; it's an okay-ish measure, nothing fancy - but it works and
; looks good, without doing fancy math.
For px = minX To maxX
; In theory I could do some fancy math with sin / cos here to skip some pixels, but meh
; I think the one sqrt per pixel is faster than the two trigonometric functions per row
; for the small circles I draw. If you draw a big circle this changes, and you totally
; should fix this.
For py = minY To maxY
dx# = (px - mx#)
dy# = (py - my#)
distance# = Sqr(dx# * dx# + dy# * dy#)
overlap# = -(distance# - radiDistance#)
If (overlap > 0) Then
If (overlap >= 1) Then
WritePixelFast px, py, defaultColor
Else
oldColor = ReadPixelFast(px, py)
If (oldColor <> defaultColor) Then
oldB = oldColor And 255
oldG = (oldColor Shr 8) And 255
oldR = (oldColor Shr 16) And 255
invOverlap# = 1 - overlap
tr = r * overlap + oldR * invOverlap
tg = g * overlap + oldG * invOverlap
tb = b * overlap + oldB * invOverlap
End If
WritePixelFast px, py, (tr Shl 16) + (tg Shl 8) + (tb)
End If
End If
Next
Next
End Function
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment