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:
2nd Demo the mouse is the center of circle moved around screen, use wheel for expanding it's radius:
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.
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 + ...