Mod'ing a classic- partial circle fill
#2
Thumbs Up 
I liked this routine so much I did 3 more Demos for the Old Moses feature routine.

The first just tests rectangles instead of square: 
Code: (Select All)
_Title "Demo 2 Circle Part with rectangle"
'OldMoses' mod of Steve's circle fill
'drawing only those portions that fit the bounding box

'e% = 128
xsz% = 200
ysz% = 50
ls% = 200
rs% = 600
t% = 100
b% = 200
Screen _NewImage(1024, 512, 32)
Do
    While _MouseInput
        osz% = wsz%
        wsz% = Sgn(_MouseWheel) * 3
        If (t% - wsz%) < (b% + wsz%) Then
            If osz% <> xsz% Then
                ls% = ls% - wsz%: rs% = rs% + wsz%
                t% = t% - wsz%: b% = b% + wsz%
                xsz% = xsz% + wsz%
                ysz% = ysz% + wsz%
            End If
        End If
    Wend
    If _MouseButton(1) Then
        ls% = _MouseX - xsz%: rs% = _MouseX + xsz%
        t% = _MouseY - ysz%: b% = _MouseY + ysz%
    End If

    Cls
    'LINE (512 - e%, 256 - e%)-(512 + e%, 256 + e%)
    'LINE (512 + e%, 256 - e%)-(512 - e%, 256 + e%)
    Line (ls%, t%)-(rs%, b%), , B '                             Bounding box

    'CIRCLE (512, 256), 128, &H7FFF0000
    FCirc 512, 256, 128, &H7FFF0000 '                           Steve's unmodified circle fill
    FCircPart 512, 256, 128, &H7F00FF00, ls%, rs%, t%, b% '     modified partial circle fill

    _Limit 30
    _Display
Loop Until _KeyDown(27)
End



Sub FCircPart (CX As Long, CY As Long, RR As Long, C As _Unsigned Long, lt As Long, rt As Long, t As Long, b As Long) 'modified circle fill
    If rt < CX - RR Or lt > CX + RR Or t > CY + RR Or b < CY - RR Then Exit Sub 'leave if box not intersecting circle
    Dim As Long R, RError, X, Y
    R = Abs(RR) '                                               radius value along positive x
    RError = -R '                                               opposite side of circle? negative x
    X = R '                                                     point along positive x position
    Y = 0 '                                                     starting at the equator
    If R = 0 Then PSet (CX, CY), C: Exit Sub '                  zero radius is point, not circle
    If CY >= t And CY <= b Then Line (MinOf&(CX - X, lt), CY)-(MaxOf&(CX + X, rt), CY), C, BF 'draw equatorial line if applicable
    While X > Y
        RError = RError + Y * 2 + 1 '
        If RError >= 0 Then
            If X <> Y + 1 Then
                If CY - X >= t And CY - X <= b And CX - Y <= rt And CX + Y >= lt Then
                    Line (MinOf&(CX - Y, lt), CY - X)-(MaxOf&(CX + Y, rt), CY - X), C, BF ' draw lines for south polar latitudes
                End If
                If CY + X <= b And CY + X >= t And CX - Y <= rt And CX + Y >= lt Then
                    Line (MinOf&(CX - Y, lt), CY + X)-(MaxOf&(CX + Y, rt), CY + X), C, BF ' draw lines for north polar latitudes
                End If
            End If
            X = X - 1
            RError = RError - X * 2
        End If
        Y = Y + 1
        If CY - Y >= t And CY - Y <= b And CX - X <= rt And CX + X >= lt Then
            Line (MinOf&(CX - X, lt), CY - Y)-(MaxOf&(CX + X, rt), CY - Y), C, BF '         draw lines north equatorial latitudes
        End If
        If CY + Y <= b And CY + Y >= t And CX - X <= rt And CX + X >= lt Then
            Line (MinOf&(CX - X, lt), CY + Y)-(MaxOf&(CX + X, rt), CY + Y), C, BF '         draw lines south equatorial latitudes
        End If
    Wend
End Sub 'FCircPart


Sub FCirc (CX As Long, CY As Long, RR As Long, C As _Unsigned Long) 'Steve's circle fill unmodified
    Dim As Long R, RError, X, Y
    R = Abs(RR) '                                               radius value along positive x
    RError = -R '                                               opposite side of circle? negative x
    X = R '                                                     point along positive x position
    Y = 0 '                                                     starting at the equator
    If R = 0 Then PSet (CX, CY), C: Exit Sub '                  zero radius is point, not circle
    Line (CX - X, CY)-(CX + X, CY), C, BF '                     draw equatorial line
    While X > Y
        RError = RError + Y * 2 + 1 '
        If RError >= 0 Then
            If X <> Y + 1 Then
                Line (CX - Y, CY - X)-(CX + Y, CY - X), C, BF ' draw lines for south polar latitudes
                Line (CX - Y, CY + X)-(CX + Y, CY + X), C, BF ' draw lines for north polar latitudes
            End If
            X = X - 1
            RError = RError - X * 2
        End If
        Y = Y + 1
        Line (CX - X, CY - Y)-(CX + X, CY - Y), C, BF '         draw lines north equatorial latitudes
        Line (CX - X, CY + Y)-(CX + X, CY + Y), C, BF '         draw lines south equatorial latitudes
    Wend
End Sub 'FCirc


Function MaxOf& (value As Long, max As Long)
    MaxOf& = -value * (value <= max) - max * (value > max)
End Function 'MaxOf%

Function MinOf& (value As Integer, minimum As Integer)
    MinOf& = -value * (value >= minimum) - minimum * (value < minimum)
End Function 'MinOf%


2nd Demo the mouse is the center of circle moved around screen, use wheel for expanding it's radius:
Code: (Select All)
_Title "Demo 3 Circle Part with Circle" ' b+ mod Old Moses 2023-01-16
'OldMoses' mod of Steve's circle fill
'drawing only those portions that fit the bounding box

rsz% = 50
ls% = 412
rs% = 512
t% = 100
b% = 300
Screen _NewImage(1024, 512, 32)
Do

    While _MouseInput
        osz% = wsz%
        wsz% = Sgn(_MouseWheel) * 3
        If osz% <> rsz% Then
            rsz% = rsz% + wsz%
        End If
    Wend

    mx = _MouseX
    my = _MouseY


    Cls
    Line (ls%, t%)-(rs%, b%), &HFFFFFFFF, BF
    FCirc mx, my, rsz%, &HFFFF0000 '                             Bounding box

    'CIRCLE (512, 256), 128, &H7FFF0000
    'FCirc 512, 256, 128, &H7FFF0000 '                           Steve's unmodified circle fill
    FCircPart mx, my, rsz%, &H7F00FF00, ls%, rs%, t%, b% '     modified partial circle fill

    _Limit 30
    _Display
Loop Until _KeyDown(27)
End



Sub FCircPart (CX As Long, CY As Long, RR As Long, C As _Unsigned Long, lt As Long, rt As Long, t As Long, b As Long) 'modified circle fill
    If rt < CX - RR Or lt > CX + RR Or t > CY + RR Or b < CY - RR Then Exit Sub 'leave if box not intersecting circle
    Dim As Long R, RError, X, Y
    R = Abs(RR) '                                               radius value along positive x
    RError = -R '                                               opposite side of circle? negative x
    X = R '                                                     point along positive x position
    Y = 0 '                                                     starting at the equator
    If R = 0 Then PSet (CX, CY), C: Exit Sub '                  zero radius is point, not circle
    If CY >= t And CY <= b Then Line (MinOf&(CX - X, lt), CY)-(MaxOf&(CX + X, rt), CY), C, BF 'draw equatorial line if applicable
    While X > Y
        RError = RError + Y * 2 + 1 '
        If RError >= 0 Then
            If X <> Y + 1 Then
                If CY - X >= t And CY - X <= b And CX - Y <= rt And CX + Y >= lt Then
                    Line (MinOf&(CX - Y, lt), CY - X)-(MaxOf&(CX + Y, rt), CY - X), C, BF ' draw lines for south polar latitudes
                End If
                If CY + X <= b And CY + X >= t And CX - Y <= rt And CX + Y >= lt Then
                    Line (MinOf&(CX - Y, lt), CY + X)-(MaxOf&(CX + Y, rt), CY + X), C, BF ' draw lines for north polar latitudes
                End If
            End If
            X = X - 1
            RError = RError - X * 2
        End If
        Y = Y + 1
        If CY - Y >= t And CY - Y <= b And CX - X <= rt And CX + X >= lt Then
            Line (MinOf&(CX - X, lt), CY - Y)-(MaxOf&(CX + X, rt), CY - Y), C, BF '         draw lines north equatorial latitudes
        End If
        If CY + Y <= b And CY + Y >= t And CX - X <= rt And CX + X >= lt Then
            Line (MinOf&(CX - X, lt), CY + Y)-(MaxOf&(CX + X, rt), CY + Y), C, BF '         draw lines south equatorial latitudes
        End If
    Wend
End Sub 'FCircPart


Sub FCirc (CX As Long, CY As Long, RR As Long, C As _Unsigned Long) 'Steve's circle fill unmodified
    Dim As Long R, RError, X, Y
    R = Abs(RR) '                                               radius value along positive x
    RError = -R '                                               opposite side of circle? negative x
    X = R '                                                     point along positive x position
    Y = 0 '                                                     starting at the equator
    If R = 0 Then PSet (CX, CY), C: Exit Sub '                  zero radius is point, not circle
    Line (CX - X, CY)-(CX + X, CY), C, BF '                     draw equatorial line
    While X > Y
        RError = RError + Y * 2 + 1 '
        If RError >= 0 Then
            If X <> Y + 1 Then
                Line (CX - Y, CY - X)-(CX + Y, CY - X), C, BF ' draw lines for south polar latitudes
                Line (CX - Y, CY + X)-(CX + Y, CY + X), C, BF ' draw lines for north polar latitudes
            End If
            X = X - 1
            RError = RError - X * 2
        End If
        Y = Y + 1
        Line (CX - X, CY - Y)-(CX + X, CY - Y), C, BF '         draw lines north equatorial latitudes
        Line (CX - X, CY + Y)-(CX + X, CY + Y), C, BF '         draw lines south equatorial latitudes
    Wend
End Sub 'FCirc


Function MaxOf& (value As Long, max As Long)
    MaxOf& = -value * (value <= max) - max * (value > max)
End Function 'MaxOf%

Function MinOf& (value As Integer, minimum As Integer)
    MinOf& = -value * (value >= minimum) - minimum * (value < minimum)
End Function 'MinOf%


And now for the fun! Demo 4 is Bouncing balls that can only be seen in rectangle glass panes of different color!
Actually they look more like search lights hitting different colored panes.
Code: (Select All)
_Title "Demo 4 Circle Part Random" ' b+ mod Old Moses 2023-01-16
'OldMoses' mod of Steve's circle fill
'drawing only those portions that fit the bounding box
Randomize Timer
Type bx
    As Single x, y, w, h
    As _Unsigned Long c
End Type
Type circ
    As Single x, y, dx, dy, r
    As _Unsigned Long c
End Type

Screen _NewImage(1024, 512, 32)
Dim b(1 To 200) As bx
For i = 1 To 200
    b(i).w = Rnd * 100 + 10
    b(i).x = Rnd * (_Width - b(i).w)
    b(i).h = Rnd * 100 + 10
    b(i).y = Rnd * (_Height - b(i).h)
    b(i).c = _RGB32(Rnd * 255, Rnd * 255, Rnd * 255, Rnd * 240 + 15)
Next
Dim c(1 To 50) As circ
For i = 1 To 50
    c(i).r = Rnd * 50 + 10
    c(i).x = Rnd * (_Width - 2 * c(i).r) + c(i).r
    c(i).y = Rnd * (_Height - 2 * c(i).r) + c(i).r
    c(i).dx = Rnd * 5
    If Rnd < .5 Then c(i).dx = -c(i).dx
    c(i).dy = Rnd * 5
    If Rnd < .5 Then c(i).dy = -c(i).dy
Next
Do
    Cls
    For j = 1 To 50
        For i = 1 To 200
            FCircPart c(j).x, c(j).y, c(j).r, b(i).c, b(i).x, b(i).x + b(i).w, b(i).y, b(i).y + b(i).h '     modified partial circle fill
        Next
        c(j).x = c(j).x + c(j).dx
        If c(j).x - c(j).r < 0 Then c(j).dx = -c(j).dx: c(j).x = c(j).r
        If c(j).x + c(j).r > _Width Then c(j).dx = -c(j).dx: c(j).x = _Width - c(j).r

        c(j).y = c(j).y + c(j).dy
        If c(j).y - c(j).r < 0 Then c(j).dy = -c(j).dy: c(j).y = c(j).r
        If c(j).y + c(j).r > _Height Then c(j).dy = -c(j).dy: c(j).y = _Height - c(j).r

    Next
    _Display
    _Limit 30
Loop Until _KeyDown(27)
End

Sub FCircPart (CX As Long, CY As Long, RR As Long, C As _Unsigned Long, lt As Long, rt As Long, t As Long, b As Long) 'modified circle fill
    If rt < CX - RR Or lt > CX + RR Or t > CY + RR Or b < CY - RR Then Exit Sub 'leave if box not intersecting circle
    Dim As Long R, RError, X, Y
    R = Abs(RR) '                                               radius value along positive x
    RError = -R '                                               opposite side of circle? negative x
    X = R '                                                     point along positive x position
    Y = 0 '                                                     starting at the equator
    If R = 0 Then PSet (CX, CY), C: Exit Sub '                  zero radius is point, not circle
    If CY >= t And CY <= b Then Line (MinOf&(CX - X, lt), CY)-(MaxOf&(CX + X, rt), CY), C, BF 'draw equatorial line if applicable
    While X > Y
        RError = RError + Y * 2 + 1 '
        If RError >= 0 Then
            If X <> Y + 1 Then
                If CY - X >= t And CY - X <= b And CX - Y <= rt And CX + Y >= lt Then
                    Line (MinOf&(CX - Y, lt), CY - X)-(MaxOf&(CX + Y, rt), CY - X), C, BF ' draw lines for south polar latitudes
                End If
                If CY + X <= b And CY + X >= t And CX - Y <= rt And CX + Y >= lt Then
                    Line (MinOf&(CX - Y, lt), CY + X)-(MaxOf&(CX + Y, rt), CY + X), C, BF ' draw lines for north polar latitudes
                End If
            End If
            X = X - 1
            RError = RError - X * 2
        End If
        Y = Y + 1
        If CY - Y >= t And CY - Y <= b And CX - X <= rt And CX + X >= lt Then
            Line (MinOf&(CX - X, lt), CY - Y)-(MaxOf&(CX + X, rt), CY - Y), C, BF '         draw lines north equatorial latitudes
        End If
        If CY + Y <= b And CY + Y >= t And CX - X <= rt And CX + X >= lt Then
            Line (MinOf&(CX - X, lt), CY + Y)-(MaxOf&(CX + X, rt), CY + Y), C, BF '         draw lines south equatorial latitudes
        End If
    Wend
End Sub 'FCircPart

Sub FCirc (CX As Long, CY As Long, RR As Long, C As _Unsigned Long) 'Steve's circle fill unmodified
    Dim As Long R, RError, X, Y
    R = Abs(RR) '                                               radius value along positive x
    RError = -R '                                               opposite side of circle? negative x
    X = R '                                                     point along positive x position
    Y = 0 '                                                     starting at the equator
    If R = 0 Then PSet (CX, CY), C: Exit Sub '                  zero radius is point, not circle
    Line (CX - X, CY)-(CX + X, CY), C, BF '                     draw equatorial line
    While X > Y
        RError = RError + Y * 2 + 1 '
        If RError >= 0 Then
            If X <> Y + 1 Then
                Line (CX - Y, CY - X)-(CX + Y, CY - X), C, BF ' draw lines for south polar latitudes
                Line (CX - Y, CY + X)-(CX + Y, CY + X), C, BF ' draw lines for north polar latitudes
            End If
            X = X - 1
            RError = RError - X * 2
        End If
        Y = Y + 1
        Line (CX - X, CY - Y)-(CX + X, CY - Y), C, BF '         draw lines north equatorial latitudes
        Line (CX - X, CY + Y)-(CX + X, CY + Y), C, BF '         draw lines south equatorial latitudes
    Wend
End Sub 'FCirc


Function MaxOf& (value As Long, max As Long)
    MaxOf& = -value * (value <= max) - max * (value > max)
End Function 'MaxOf%

Function MinOf& (value As Integer, minimum As Integer)
    MinOf& = -value * (value >= minimum) - minimum * (value < minimum)
End Function 'MinOf%

   
b = b + ...
Reply


Messages In This Thread
RE: Mod'ing a classic- partial circle fill - by bplus - 01-17-2023, 03:19 AM



Users browsing this thread: 1 Guest(s)