QB64 Phoenix Edition
PieSlice - Printable Version

+- QB64 Phoenix Edition (https://qb64phoenix.com/forum)
+-- Forum: QB64 Rising (https://qb64phoenix.com/forum/forumdisplay.php?fid=1)
+--- Forum: Code and Stuff (https://qb64phoenix.com/forum/forumdisplay.php?fid=3)
+---- Forum: Works in Progress (https://qb64phoenix.com/forum/forumdisplay.php?fid=9)
+---- Thread: PieSlice (/showthread.php?tid=3119)

Pages: 1 2


RE: PieSlice - bplus - 10-13-2024

Yep! I definitely like Steve's coding method for PieSlice.

It is very easy to adapt to different Compass Systems, here is my CW version to Steve's CCW
Code: (Select All)
_Title "PieSlice Tests with Steve coding" ' bplus 2024-10-13
$Color:32
Screen _NewImage(1200, 600, 32)
_ScreenMove 40, 60
Dim degree10, xc1, xc, yc, xc2, r, a, x1, y1, at, sa$, xoff, yoff, x2, y2
degree10 = _Pi(2 / 36) ' like hours on clock
xc1 = 300: xc2 = 900: yc = 300: r = 200
_PrintString (xc1 - _PrintWidth("CW  Regular East = 0 Deg/Rads Calcs") / 2, 292), "CW  Regular East = 0 Deg/Rads Calcs"
_PrintString (xc2 - _PrintWidth("CCW Steve's East = 0 Deg/Rads Calcs") / 2, 292), "CCW Steve's East = 0 Deg/Rads Calcs"

For a = 0 To _Pi(1.999) Step degree10

    ' Regular East = 0 calcs
    x1 = xc1 + r * Cos(a)
    y1 = yc + r * Sin(a)
    at = Int(_R2D(_Atan2(y1 - yc, x1 - xc1)) + .0001)
    If at < 0 Then at = at + 360
    sa$ = _Trim$(Str$(at))
    xoff = _PrintWidth(sa$) / 2
    yoff = 16 / 2
    _PrintString (x1 - xoff, y1 - yoff), sa$

    ' East = 0 calcs but Counter Clockwise
    x2 = xc2 + r * Sin(a + _Pi / 2)
    y2 = yc + r * Cos(a + _Pi / 2)
    at = Int(AtanSteve(xc2, yc, x2, y2))
    sa$ = _Trim$(Str$(at))
    xoff = _PrintWidth(sa$) / 2
    yoff = 16 / 2
    _PrintString (x2 - xoff, y2 - yoff), sa$

    _Limit 10
Next

PieSliceFill 80, 90, 80, _D2R(45), 0, Red
PieSliceFill 200, 200, 50, _D2R(270), _D2R(120), Green
PieSliceFill 400, 400, 50, _D2R(120), _D2R(270), Gold
PieSliceSteve 620, 90, 80, 45, 0, Red
PieSliceSteve 800, 200, 50, 270, 120, Green
PieSliceSteve 1000, 400, 50, 120, 270, Gold
Locate 33, 1: Print "pieSliceFill 80, 90, 80, _D2R(45), 0, Red";
Locate 34, 1: Print "pieSliceFill 200, 200, 50, _D2R(270), _D2R(120), Green";
Locate 35, 1: Print "pieSliceFill 400, 400, 50, _D2R(120), _D2R(270), Gold";
Locate 33, 76: Print "PieSliceSteve 620, 90, 80, 45, 0, Red";
Locate 34, 76: Print "PieSliceSteve 800, 200, 50, 270, 120, Green";
Locate 35, 76: Print "PieSliceSteve 1000, 400, 50, 120, 270, Gold";


Sub PieSliceSteve (cx As Long, cy As Long, r As Long, startAngle As Long, endAngle As Long, c As _Unsigned Long)
    Dim As Long x, y, x1, y1
    If startAngle > endAngle Then endAngle = endAngle + 360
    x1 = Sin(_D2R(startAngle + 90)) * r
    y1 = Cos(_D2R(startAngle + 90)) * r
    Line (cx, cy)-Step(x1, y1), c
    For i = startAngle To endAngle Step Sgn(endAngle - startAngle)
        x = Sin(_D2R(i + 90)) * r
        y = Cos(_D2R(i + 90)) * r
        Line -(cx + x, cy + y), c ' <<< bplus fixed cy + y not cx + y !!!!
        If x <> x1 And y <> y1 And xt = 0 Then 'chose a point inside the arc to fill
            xt = Sin(_D2R(i + 90)) * r / 2
            yt = Cos(_D2R(i + 90)) * r / 2
        End If
    Next
    Line -(cx, cy), c
    Paint (cx + xt, cy + yt), c
End Sub

Function AtanSteve (x1, y1, x2, y2)
    AtanSteve = (360 - _R2D(_Atan2(y2 - y1, x2 - x1))) Mod 360
End Function

' mod to Steve way of coding 2024-10-13
Sub PieSliceFill (cx, cy, r, startAngle, endAngle, c As _Unsigned Long)
    Dim As Long x, y, x1, y1
    If startAngle > endAngle Then endAngle = endAngle + _Pi * 2
    x1 = Cos(startAngle) * r
    y1 = Sin(startAngle) * r
    Line (cx, cy)-Step(x1, y1), c
    For i = startAngle To endAngle Step _D2R(Sgn(endAngle - startAngle))
        x = Cos(i) * r
        y = Sin(i) * r
        Line -(cx + x, cy + y), c
        If x <> x1 And y <> y1 And xt = 0 Then 'chose a point inside the arc to fill
            xt = Cos(i) * r / 2
            yt = Sin(i) * r / 2
        End If
    Next
    Line -(cx, cy), c
    Paint (cx + xt, cy + yt), c
    'Circle (cx + xt, cy + yt), c
End Sub
   


And here is PieSlice for @TerryRitchie North = 0 Clockwise
Code: (Select All)
_Title "PieSlice test Normal East = 0 and North = 0" ' bplus 2024-10-13
$Color:32
Screen _NewImage(1200, 600, 32)
_ScreenMove 40, 60
Dim degree10, xc1, xc, yc, xc2, r, a, x1, y1, at, sa$, xoff, yoff, x2, y2
degree10 = _Pi(2 / 36) ' like hours on clock
xc1 = 300: xc2 = 900: yc = 300: r = 200
_PrintString (xc1 - _PrintWidth("CW Regular East = 0 Deg/Rads Calcs") / 2, 292), "CW Regular East = 0 Deg/Rads Calcs"
_PrintString (xc2 - _PrintWidth("CW Terry's North = 0 Deg/Rads Calcs") / 2, 292), "CW Terry's North = 0 Deg/Rads Calcs"

For a = 0 To _Pi(1.999) Step degree10

    ' Regular East = 0 calcs
    x1 = xc1 + r * Cos(a)
    y1 = yc + r * Sin(a)
    at = Int(_R2D(_Atan2(y1 - yc, x1 - xc1)) + .0001)
    If at < 0 Then at = at + 360
    sa$ = _Trim$(Str$(at))
    xoff = _PrintWidth(sa$) / 2
    yoff = 16 / 2
    _PrintString (x1 - xoff, y1 - yoff), sa$

    ' North = 0 calcs
    x2 = xc2 + r * Sin(a)
    y2 = yc + r * -Cos(a)
    at = Int(_R2D(ATan4North0(y2 - yc, x2 - xc2)) + .0001)
    If at < 0 Then at = at + 360
    sa$ = _Trim$(Str$(at))
    xoff = _PrintWidth(sa$) / 2
    yoff = 16 / 2
    _PrintString (x2 - xoff, y2 - yoff), sa$

    _Limit 10
Next

PieSliceFill 80, 90, 80, _D2R(45), 0, Red
PieSliceFill 200, 200, 50, _D2R(270), _D2R(120), Green
PieSliceFill 400, 400, 50, _D2R(120), _D2R(270), Gold
PieSliceTerry 620, 90, 80, 45, 0, Red
PieSliceTerry 800, 200, 50, 270, 120, Green
PieSliceTerry 1000, 400, 50, 120, 270, Gold
Locate 33, 1: Print "pieSliceFill 80, 90, 80, _D2R(45), 0, Red";
Locate 34, 1: Print "pieSliceFill 200, 200, 50, _D2R(270), _D2R(120), Green";
Locate 35, 1: Print "pieSliceFill 400, 400, 50, _D2R(120), _D2R(270), Gold";
Locate 33, 76: Print "PieSliceTerry 620, 90, 80, 45, 0, Red";
Locate 34, 76: Print "PieSliceTerry 800, 200, 50, 270, 120, Green";
Locate 35, 76: Print "PieSliceTerry 1000, 400, 50, 120, 270, Gold";


Sub PieSliceTerry (cx As Long, cy As Long, r As Long, startAngle As Long, endAngle As Long, c As _Unsigned Long)
    Dim As Long x, y, x1, y1
    If startAngle > endAngle Then endAngle = endAngle + 360
    x1 = Sin(_D2R(startAngle)) * r
    y1 = -Cos(_D2R(startAngle)) * r
    Line (cx, cy)-Step(x1, y1), c
    For i = startAngle To endAngle Step Sgn(endAngle - startAngle)
        x = Sin(_D2R(i)) * r
        y = -Cos(_D2R(i)) * r
        Line -(cx + x, cy + y), c ' <<< bplus fixed cy + y not cx + y !!!!
        If x <> x1 And y <> y1 And xt = 0 Then 'chose a point inside the arc to fill
            xt = Sin(_D2R(i)) * r / 2
            yt = -Cos(_D2R(i)) * r / 2
        End If
    Next
    Line -(cx, cy), c
    Paint (cx + xt, cy + yt), c
    'Circle (cx + xt, cy + yt), c
End Sub


Function ATan4North0 (dy, dx)
    ATan4North0 = _Pi - _Atan2(dx, dy) ' this was totally unexpected!
End Function

' mod to Steve way of coding 2024-10-13
Sub PieSliceFill (cx, cy, r, startAngle, endAngle, c As _Unsigned Long)
    Dim As Long x, y, x1, y1
    If startAngle > endAngle Then endAngle = endAngle + _Pi * 2
    x1 = Cos(startAngle) * r
    y1 = Sin(startAngle) * r
    Line (cx, cy)-Step(x1, y1), c
    For i = startAngle To endAngle Step _D2R(Sgn(endAngle - startAngle))
        x = Cos(i) * r
        y = Sin(i) * r
        Line -(cx + x, cy + y), c
        If x <> x1 And y <> y1 And xt = 0 Then 'chose a point inside the arc to fill
            xt = Cos(i) * r / 2
            yt = Sin(i) * r / 2
        End If
    Next
    Line -(cx, cy), c
    Paint (cx + xt, cy + yt), c
    'Circle (cx + xt, cy + yt), c
End Sub
   


RE: PieSlice - CharlieJV - 10-13-2024

For whatever strange reason, I'm enjoying this thread of discussion.

The Wikipedia article on radians makes for a nice related reading.

Myself, I'm much too accustomed to 0 degrees is east, 90 degrees is north (matching the way radians work: counter clockwise) to change my way of thinking.


RE: PieSlice - SMcNeill - 10-13-2024

(10-13-2024, 04:34 PM)bplus Wrote: Yep! I definitely like Steve's coding method for PieSlice.

It is very easy to adapt to different Compass Systems, here is my CW version to Steve's CCW

Usually, it shouldn't be too hard to ever adapt various compass systems. At the heart of the day, they're all basically just rotated or mirrored in some form. Like with the Atan function I shared, unless you're doing something *really* weird, in the end, you should be able to convert and toggle from one to the other without too much trouble. Just rotate/invert your angles until they fit the coordinate system you're using. After all, at the end of a day, a circle is still a circle, no matter how you plot it. Wink

(10-13-2024, 05:14 PM)CharlieJV Wrote: For whatever strange reason, I'm enjoying this thread of discussion.

The Wikipedia article on radians makes for a nice related reading.

Myself, I'm much too accustomed to 0 degrees is east, 90 degrees is north (matching the way radians work: counter clockwise) to change my way of thinking.

I'm with you @CharlieJV 

It's the way we were taught to read and use angles in school, and it'll probably always be the way my brain will default when thinking of any angle.  It's why I wrote this little pieslice routine the way I did -- it works with the coordinates as you've described them.  

I'm glad to see I'm not the only person in the world who was taught to think in that direction.  Big Grin


RE: PieSlice - Pete - 10-13-2024

I'm a cake person; that way, I can have my code and eat it, too!

This reminds me of when TheBOB converted his White Cake Recipe to QB64 and a bug in the QB64 rendition of the CIRCLE statement had it bleeding frosting all over the screen. I'm sorry that bug got fixed. Licking my screen is far less satisfying now... Log onto what? Oh shut up, Steve!

Pete Big Grin


RE: PieSlice - bplus - 10-14-2024

(10-13-2024, 05:32 PM)SMcNeill Wrote:
(10-13-2024, 04:34 PM)bplus Wrote: Yep! I definitely like Steve's coding method for PieSlice.

It is very easy to adapt to different Compass Systems, here is my CW version to Steve's CCW

Usually, it shouldn't be too hard to ever adapt various compass systems. At the heart of the day, they're all basically just rotated or mirrored in some form. Like with the Atan function I shared, unless you're doing something *really* weird, in the end, you should be able to convert and toggle from one to the other without too much trouble. Just rotate/invert your angles until they fit the coordinate system you're using. After all, at the end of a day, a circle is still a circle, no matter how you plot it. Wink

(10-13-2024, 05:14 PM)CharlieJV Wrote: For whatever strange reason, I'm enjoying this thread of discussion.

The Wikipedia article on radians makes for a nice related reading.

Myself, I'm much too accustomed to 0 degrees is east, 90 degrees is north (matching the way radians work: counter clockwise) to change my way of thinking.

I'm with you @CharlieJV 

It's the way we were taught to read and use angles in school, and it'll probably always be the way my brain will default when thinking of any angle.  It's why I wrote this little pieslice routine the way I did -- it works with the coordinates as you've described them.  

I'm glad to see I'm not the only person in the world who was taught to think in that direction.  Big Grin

The Fundemental difference between the math graphs we were taught in school and Basic Screens coordinate system (x, y) point locations is:

The values on the Y axis increase going down screen in Basic coordinates whereas in Math class the Y axis ascended in value going up.

This is the reason Radians or Degrees go Counter Clockwise in math class and go Clockwise in Basic screens (and as _ATan2 works in Basic without monkey business Smile ).

This is the Quadrant System of a Math Graph:
   

In Basic because the Y axis increases in values going down, the Basic screen is all Quadrant 1, both x and y are positive. If we were to continue labeling Quadrants they would go Clockwise (CW) around because Y increases going down screen.
So Quadrant 2 would left of Quadrant 1, where all x's are neg and all y's are positive.
going CW, Quardrant 3 is above 2 because y's are negative and x's are negative
going CW, Quadrant 4 is to right of 3 above 1 because all x's are positive and all y's are negative.

Q3(-,-) Q4(+,-)
Q2(-,+) Q1(+,+) = Basic screen
The Quadrants go CW

also in math all x stuff is associated with Cos and all y stuff with Sin that still holds with the Y axis flipped on Basic screen.
This is why a vector x component should be calculated with Cos and y component with Sin.