Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
PieSlice
#1
As Terry pointed out elsewhere, CIRCLE has always been broken when it comes to doing arcs for us to fill.  I thought I'd give a quick shot at tossing something together to work for us, and here's what I came up with.  (Not tested extensively so may break with various angles/combos.  I hope not.)

Code: (Select All)
Screen _NewImage(1280, 720, 32)
$Color:32

PieSlice 100, 100, 100, 45, 0, Red
PieSlice 200, 200, 50, 270, 120, Green
PieSlice 300, 300, 50, 120, 270, Gold

Sub PieSlice (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
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
Reply
#2
I have posted PieSlice and a couple Arcs here:
https://qb64phoenix.com/forum/showthread...04#pid1204
b = b + ...
Reply
#3
Ah now I see where North = 0 probably started. I never messed around much with arcs from the Circle Sub.
b = b + ...
Reply
#4
@SMcNeill your code had a typo on line 17
Line -(cx + x, cx + y), c
should be cy + y

The error didn't show up because your test code used same x, y center point.

And I can't for the life of me figure out what compass you are using for start and finish angles???
It's not Terry's North = 0 nor my Basic East = 0

Code: (Select All)
$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("Regular East = 0 Deg/Rads Calcs") / 2, 292), "Regular East = 0 Deg/Rads Calcs"
_PrintString (xc2 - _PrintWidth("Terry's North = 0 Deg/Rads Calcs") / 2, 292), "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$
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 ATan4North0 (dy, dx)
    ATan4North0 = _Pi - _Atan2(dx, dy) ' this was totally unexpected!
End Function

Sub pieSlice (x, y, r, raStart, raStop, c As _Unsigned Long)
    Dim px As Single, py As Single
    arcC x, y, r, raStart, raStop, c ' this does check raStart and raStop
    px = x + r * Cos(raStart): py = y + r * Sin(raStart)
    Line (x, y)-(px, py), c
    px = x + r * Cos(raStop): py = y + r * Sin(raStop)
    Line (x, y)-(px, py), c
End Sub

Sub pieSliceFill (x, y, r, raStart, raStop, c As _Unsigned Long)
    Dim As Single px, py, raMid
    arcC x, y, r, raStart, raStop, c ' this does check raStart and raStop
    px = x + r * Cos(raStart): py = y + r * Sin(raStart)
    Line (x, y)-(px, py), c
    px = x + r * Cos(raStop): py = y + r * Sin(raStop)
    Line (x, y)-(px, py), c
    raMid = (raStop + raStart) / 2
    px = x + r * Cos(raMid): py = y + r * Sin(raMid)
    If Point(px, py) <> c Then
        raMid = raMid + _Pi
        px = x + r / 2 * Cos(raMid): py = y + r / 2 * Sin(raMid)
    Else
        px = x + r / 2 * Cos(raMid): py = y + r / 2 * Sin(raMid)
    End If
    Paint (px, py), c
End Sub

Sub arcC (x, y, r, raStart, raStop, c As _Unsigned Long) ' updated 2021-09-09  checks raBegin and raEnd
    ' raStart is first angle clockwise from due East = 0 degrees
    ' arc will start drawing there and clockwise until raStop angle reached
    'x, y origin, r = radius, c = color

    Dim p, p2 ' update 2021-09-09 save some time by doing _pi function once
    p = _Pi: p2 = p * 2

    Dim dStart, dStop, al, a

    ' Last time I tried to use this SUB it hung the program, possible causes:
    ' Make sure raStart and raStop are between 0 and 2pi.
    ' This sub does not have to be recursive, use GOSUB to do drawing to execute arc in one call.

    ' changing to equivalents
    While raStart < 0: raStart = raStart + p2: Wend
    While raStart >= p2: raStart = raStart - p2: Wend
    While raStop < 0: raStop = raStop + p2: Wend
    While raStop >= p2: raStop = raStop - p2: Wend

    If raStop < raStart Then
        dStart = raStart: dStop = p2 - .00001
        GoSub drawArc
        dStart = 0: dStop = raStop
        GoSub drawArc
    Else
        dStart = raStart: dStop = raStop
        GoSub drawArc
    End If
    Exit Sub
    drawArc:
    al = p * r * r * (dStop - dStart) / p2
    For a = dStart To dStop Step 1 / al
        PSet (x + r * Cos(a), y + r * Sin(a)), c
    Next
    Return
End Sub
   
b = b + ...
Reply
#5
You guys are weird.  Tongue

All I was ever taught in school was a simple circle with 0 = east, 90 = north, 180 = west, 270 = south.  As such:

[Image: 104-1043955_45-degree-angle-circle-hd-png-download.png]

Now, isn't this the same as what everyone else was taught in school?
X axis gets larger going from right to left.
Y axis gets larger going from bottom to top.
Reply
#6
west virginia curriculum in full effect
Reply
#7
So your East = 0 but you go Counter-Clockwise Yikes!

Like to see an Atan2 for that! LOL
b = b + ...
Reply
#8
As you can see from below, the red circle goes from 45 degrees to 0 degrees.
The green circle goes from 270 to 120 degrees.
And the gold circle goes from 120 to 270 degrees.  (to show that we can have either slice of the pie that we want.)

Compare the image below to the coordinate system above, and see if it doesn't make perfect sense.

   
Reply
#9
Yeah I can see it now that I know where 0 is and which way around you are going. Smile

We are getting similar figures just rotated different or mirror images on x-axis.
b = b + ...
Reply
#10
(10-13-2024, 03:11 AM)bplus Wrote: So your East = 0 but you go Counter-Clockwise Yikes!

Like to see an Atan2 for that! LOL

Your wish is my command.  It's just a little rotation of the result.  Tongue

Just use the Atan command packaged here so it gives results in Degrees as you'd normally want to see and work with. Wink


Code: (Select All)
Screen _NewImage(1280, 720, 32)
$Color:32



PieSlice 100, 100, 100, 45, 0, Red
PieSlice 200, 200, 50, 270, 120, Green
PieSlice 300, 300, 50, 120, 270, Gold

Print Atan(100, 100, 171, 29) '45 degree coordinates
Print Atan(100, 100, 100, 150) '270 degree coordinates
Print Atan(100, 100, 75, 57) '120 degree coordinates

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


Sub PieSlice (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
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
Reply




Users browsing this thread: 4 Guest(s)