Help needed regarding Lesson 17 - RhoSigma - 10-08-2024
Hi Terry,
there's a lost soul at Discord. He/she obviously got lots of informations from your Tutorial Lesson 17 (Movement and Rotation).
From a quick visit to that lesson I see for your teachings you use (for whatever reason) a modified version of the standard math coordinate system, which assumes 0° as north direction and then counts the angles clockwise.
Now, this guy/girl is trying to calculate the angle from one point to another one using the _ATAN2 function and wonders about the results, mayby you could have a look: https://discord.com/channels/975381912350752819/975383819848912926/1292989790559666196
Steve and me tried to help, but as his/her thinking is obviously compromised by your coordinate modell, we probably made it even worse than better.
RE: Help needed regarding Lesson 17 - TerryRitchie - 10-08-2024
(10-08-2024, 10:39 AM)RhoSigma Wrote: Hi Terry,
there's a lost soul at Discord. He/she obviously got lots of informations from your Tutorial Lesson 17 (Movement and Rotation).
From a quick visit to that lesson I see for your teachings you use (for whatever reason) a modified version of the standard math coordinate system, which assumes 0° as north direction and then counts the angles clockwise.
Now, this guy/girl is trying to calculate the angle from one point to another one using the _ATAN2 function and wonders about the results, mayby you could have a look: https://discord.com/channels/975381912350752819/975383819848912926/1292989790559666196
Steve and me tried to help, but as his/her thinking is obviously compromised by your coordinate modell, we probably made it even worse than better. SIgh
Yes, Lesson 17 has caused troubles for a few because of the way I orient the coordinate system. The reason I did that is because 99% of the people that visit the tutorial want nothing to do with the math and just want north, 0 degrees, to face up like the real world.
Those that understand the math understand what I've done here. Those that want to learn the math (which is surprisingly few) get confused as the user you are pointing out.
What to do, what to do.
I need to update Lesson 17 with a section on how the coordinate actually looks and why it needs to be modified for screen use. I'll log into discord and try to explain. Thank you for bringing this to my attention.
UPDATE: OK, I can't log into Discord? I get a popup after putting my user name and password in asking me to verify I'm human but nothing to do to verify?
--------- Give the user my email address --> quickbasic64@gmail.com <-- and have them contact me directly please.
RE: Help needed regarding Lesson 17 - bplus - 10-08-2024
Quote:What to do, what to do.
Simply say 270 degrees or -90 degrees or _Pi(3/2) radians is "North" on a Basic Screen.
Likewise 0 degrees or radians is "East" on a Basic Screen
90 degrees is "South" or _PI(1/2) radians
180 degrees "West" or _PI radians
That way the direction name matches all the trig functions in Basic.
RE: Help needed regarding Lesson 17 - bplus - 10-08-2024
I suspect non mathematicians would be happy to be rid of Radians:
Code: (Select All) ' OK let's be rid on the confusion caused by Radians
' by using User Defined Funcions SinD and CosD that take Degrees 0 to 360 for whole circle,
' and having replaced _Atan2 by returning an angle in Degrees between 2 points: DAtan2(deltaY, deltaX)
_Title "Degrees for everything" 'b+ 2022-10-12
Screen _NewImage(800, 600, 32) ' standard screen size 800 wide, 600 height for quick QB64 Demos with full color potential (the 32)
_ScreenMove 250, 50
cx = _Width / 2 ' middle of the screen point center x
cy = _Height / 2 ' center y
radius = 250 ' max is 300 for height 600
ArrowTo cx, cy, 0, radius - 3, &HFFFFFFFF
For degrees = 0 To 359 Step 10 ' go around a full circle in degrees in steps of 10 degrees
' calculate and draw points around the center of the screen
x = cx + radius * CosD(degrees) ' use CosD for x dimensions
y = cy + radius * SinD(degrees) ' use SinD for y dimensions
Circle (x, y), 1 ' draw bigger points than single pixel
' labeling the degree angles before or after the point ?
If x < cx Then Xoffset = -10 * Len(_Trim$(Str$(degrees))): YOffset = 0
If x > cx Then Xoffset = 4 * Len(_Trim$(Str$(degrees))): YOffset = 0
If x = cx Then
Xoffset = -4 * Len(_Trim$(Str$(degrees)))
If y > cy Then YOffset = 20 Else YOffset = -20
End If
_PrintString (x + Xoffset, y - 8 + YOffset), _Trim$(Str$(degrees))
Next
' save our compass dial to image
dial& = _NewImage(_Width, _Height, 32)
_PutImage , 0, dial& ' screen to dial image stored
' Getting use to seeing angles mouse makes to center of screen
Do
Cls
_PutImage , dial&, 0
While _MouseInput: Wend ' this checks where mouse is right now!
mx = _MouseX: my = _MouseY: mb1 = _MouseButton(1) ' left mouse down ' saves mouse status to common variable names
'lets's the angle in degrees the mouse is to the center of the screen
dAngle = DAtan2(cx, cy, mx, my)
Print "The mouse pointer is "; _Trim$(Str$(dAngle)); " Degrees from the screen center." ' then center point is first the mouse point is second
ArrowTo cx, cy, dAngle, radius - 3, &HFFFFFF00
drawArc cx, cy, 70, 0, dAngle, &HFFFFFF00
_Display ' stop the blinking
_Limit 60 ' only loop 60 times per second
Loop Until _KeyDown(27)
' use angles in degrees units instead of radians (converted inside sub)
Function CosD (degrees)
' Note this function uses whatever the default type is, better not be some Integer Type.
CosD = Cos(_D2R(degrees))
End Function
' use angles in degrees units instead of radians (converted inside sub)
Function SinD (degrees)
' Note this function uses whatever the default type is, better not be some Integer Type.
SinD = Sin(_D2R(degrees))
End Function
' use angles in degrees units instead of radians (converted inside sub)
Function DAtan2 (x1, y1, x2, y2) ' The angle in degrees a 2nd point (x2, y2) makes to a first point (x1, y1)
' Note this function uses whatever the default type is, better not be some Integer Type.
' Delta means change between 1 measure and another for example x2 - x1
deltaX = x2 - x1
deltaY = y2 - y1
' To find the angle point(x2, y2) makes to (x1, y1) in Degrees
' Take DegreeAngle = DAtan2(y2 - y1, x2 - x1)
rtn = _R2D(_Atan2(deltaY, deltaX))
If rtn < 0 Then DAtan2 = rtn + 360 Else DAtan2 = rtn
End Function
' use angles in degrees units instead of radians (converted inside sub)
Sub ArrowTo (BaseX As Long, BaseY As Long, dAngle As Double, lngth As Long, colr As _Unsigned Long)
Dim As Long x1, y1, x2, y2, x3, y3
Dim As Double rAngle
rAngle = _D2R(dAngle)
x1 = BaseX + lngth * Cos(rAngle)
y1 = BaseY + lngth * Sin(rAngle)
x2 = BaseX + .8 * lngth * Cos(rAngle - _Pi(.05))
y2 = BaseY + .8 * lngth * Sin(rAngle - _Pi(.05))
x3 = BaseX + .8 * lngth * Cos(rAngle + _Pi(.05))
y3 = BaseY + .8 * lngth * Sin(rAngle + _Pi(.05))
Line (BaseX, BaseY)-(x1, y1), colr
Line (x1, y1)-(x2, y2), colr
Line (x1, y1)-(x3, y3), colr
End Sub
' use angles in degrees units instead of radians (converted inside sub)
Sub drawArc (xc, yc, radius, dStart, dMeasure, colr As _Unsigned Long)
' xc, yc Center for arc circle
' rStart is the Radian Start Angle, use _D2R for conversion from Degrees to Radians
' rMeasure is the measure of Arc in Radain units, use _D2R for conversion from Degrees to Radians
' Arc will start at rStart and go clockwise around for rMeasure Radians
Dim rStart, rMeasure, rEnd, stepper, a, x, y
rStart = _D2R(dStart)
rMeasure = _D2R(dMeasure)
rEnd = rStart + rMeasure
stepper = 1 / radius ' the bigger the radius the smaller the steps
For a = rStart To rEnd Step stepper
x = xc + radius * Cos(a)
y = yc + radius * Sin(a)
If a > rStart Then Line -(x, y), colr Else PSet (x, y), colr
Next
End Sub
RE: Help needed regarding Lesson 17 - TerryRitchie - 10-08-2024
Thanks bplus. I was thinking of visuals along the same lines as you provided. I was wondering if explaining a sine wave first would help with understanding radians?
RE: Help needed regarding Lesson 17 - SMcNeill - 10-08-2024
Quote:I try to figure out how to count angle between two points. I based my attempt on Qb64tutorials lesson 17 and there is this Trig demo I based my poor knowledge. This is simplified attempt I try to figure out:
$Color:32
screen1 = _NewImage(1280, 720, 32)
Screen screen1
Const PI = 3.1415926
x1 = 622 + 8
y1 = 395 + 8
x2 = 636 + 4
y2 = 356 + 4
angle = _Atan2(x2 - x1, y2 - y1) * 180 / PI
If angle < 0 Then angle = angle + 360
Print angle
PSet (x1, y1), White
PSet (x2, y2), White
Maybe I misunderstand something totally. The angle should be around 190, give or take, right?
^ The issue as reported on Discord, in case you can sort out what the solution might be for what they're looking for here.
RE: Help needed regarding Lesson 17 - bplus - 10-08-2024
Oh thanks Steve, he almost got it right but y's over x's or Y's come first for _Atan2 then x's in 2nd argument:
fixed: his line is just over 270 degrees or 283 something:
Code: (Select All) screen1 = _NewImage(1280, 720, 32)
Screen screen1
Const PI = 3.1415926
x1 = 622 + 8
y1 = 395 + 8
Circle (x1, y1), 1, &HFFFFFF00 ' yellow
x2 = 636 + 4
y2 = 356 + 4
Circle (x2, y2), 1, &HFFFFFFFF ' white
Line (x1, y1)-(x2, y2), &HFF0000FF ' blue
'angle = _Atan2(x2 - x1, y2 - y1) * 180 / PI
angle = _Atan2(y2 - y1, x2 - x1) * 180 / PI ' y's first, x's 2nd for Atan2
If angle < 0 Then angle = angle + 360
Print angle
And the angle from point 2 (x2, y2) to point 1 (x1, y1) would be 283 - 180 = 103 degrees just past 90 clockwise.
RE: Help needed regarding Lesson 17 - TerryRitchie - 10-08-2024
bplus beat me to it. Yep, xs and ys reversed.
RE: Help needed regarding Lesson 17 - SMcNeill - 10-08-2024
Quote: Pouli: So
angle = _Atan2(y2 - y1, x2 - x1) * 180 / PI ?
The result is still off
Feel free to pop into Discord and chat with the guy.
It may be simply a case of him getting the proper result and then needing to rotate/flip it until it fits into the coordinate system Terry is using in his tutorial. I dunno. All I know is he's saying it's not working, even after the Y and X swap as you (and Rho) both pointed out for him.
Quote:Maybe I misunderstand something totally. The angle should be around 190, give or take, right?
RE: Help needed regarding Lesson 17 - bplus - 10-08-2024
@TerryRitchie here is another visual:
Code: (Select All) Option _Explicit
_Title "orbit demo" 'b+ 2024-05-10
'============================== Main
Const Xmax = 1000, Ymax = 700
Const Thick = 2
Const Arc_Radius = 100
Const Sin_color = _RGB32(0, 0, 255)
Const Cos_color = _RGB32(0, 128, 0)
Const Radius_color = _RGB32(255, 0, 0)
Const Ang_color = _RGB32(255, 255, 0)
Const White = _RGB32(255, 255, 255)
Const Origin_color = _RGB32(255, 128, 0)
Dim cx, cy, mx, my, stepX, stepY, Radius, dAng, xOut, yOut, x, y
cx = Xmax / 2: cy = Ymax / 2
Screen _NewImage(Xmax, Ymax, 32)
_ScreenMove 60, 0
_PrintMode _KeepBackground
_MouseMove cx + 100, cy + 100 ' get ball rolling
While 1
Cls
Color White
Locate 2, 18
Print "Move your mouse clockwise starting at 0 due East to see Basics Angle in Degrees increase."
Locate 5, 68
Print "Orbit ";
Color Origin_color
Print "X_Origin, Y_Origin,";
Color Ang_color
Print " Degrees,";
Color Radius_color
Print " Radius,";
Color White
Print " xOut, yOut"
'draw horizontal through center of screen
Line (70, cy)-(Xmax - 70, cy), Cos_color
' draw vertical line through center of screen
Line (cx, 70)-(cx, Ymax - 70), Sin_color
'poll mouse
While _MouseInput: Wend ' updates all mouse stuff except wheel
mx = _MouseX: my = _MouseY 'get mouse location
'draw our Color Coded Trig Triangle
ThickLine cx, cy, mx, cy, 1, Cos_color
ThickLine mx, cy, mx, my, 1, Sin_color
ThickLine cx, cy, mx, my, Thick, Radius_color
stepX = mx - cx: stepY = my - cy
Radius = (stepX ^ 2 + stepY ^ 2) ^ .5
'to draw angle need to do some math
'dAng = mouse angle to 0 Degrees due East
dAng = _R2D(_Atan2(my - cy, mx - cx))
If dAng < 0 Then dAng = dAng + 360
Color Ang_color
ThickArc cx, cy, Radius, 0, dAng, Thick
'report all numbers color coded
Color Ang_color
Locate 5, 3: Print "Yellow Angle (in Degrees) ~ "; dAng \ 1
Color Radius_color
Locate 7, 7: Print " Length red Radius ~ "; Radius \ 1
Color Sin_color
Locate 9, 7: Print " Length blue Opp side ~ "; Abs(stepY) \ 1
Color Cos_color
Locate 8, 7: Print "Length green Adj side ~ "; Abs(stepX) \ 1
Color White
Locate 11, 1: Print " Ratios: (if no division by 0)"
If Radius <> 0 Then
Color Cos_color
Locate 12, 8: Print "COS = Adj ";
Color Radius_color
Print "/ Radius ";
Color White
Print "~ "; Left$(Str$(stepX / Radius), 6) '; Cos(_D2R(dAng)) ' double check
Color Sin_color
Locate 13, 8: Print "SIN = Opp ";
Color Radius_color
Print "/ Radius ";
Color White
Print "~ "; Left$(Str$(stepY / Radius), 6) '; Sin(_D2R(dAng)) ' double check
End If
Color White
orbit cx, cy, dAng, Radius, xOut, yOut ' mouse here
orbit cx, cy, dAng, Radius + 50, x, y ' set label here
label x, y, "(xOut, yOut) = (" + _Trim$(Str$(xOut \ 1)) + "," + Str$(yOut \ 1) + ")"
Color Origin_color
label cx, cy - 10, "(X_Origin, Y_Origin) = (" + _Trim$(Str$(cx)) + "," + Str$(cy) + ")"
_Display
_Limit 60
Wend
' !!!!!! featuring the use of this SUB routine !!!!
Sub orbit (X_Origin, Y_Origin, Degrees, Radius, xOut, yOut) ' all default single should be ok
xOut = X_Origin + Radius * Cos(_D2R(Degrees))
yOut = Y_Origin + Radius * Sin(_D2R(Degrees))
End Sub
Sub label (xc, yc, text$)
Dim th2, pw2
th2 = _FontHeight / 2
pw2 = _PrintWidth(text$) / 2
_PrintString (xc - pw2 + 1.25, yc - th2 + .5), text$
End Sub
Sub ThickArc (xCenter, yCenter, arcRadius, dAngleStart, dAngleEnd, rThick)
Dim rAngle, rAngleStart, rAngleEnd, x1, y1, Stepper
'draws an Arc with center at xCenter, yCenter, Radius from center is arcRadius
'for SmallBASIC angle 0 Degrees is due East and angle increases clockwise towards South
'THIS SUB IS SETUP TO DRAW AN ARC IN CLOCKWISE DIRECTION
'dAngleStart is where to start Angle in Degrees
' so make the dAngleStart the first ray clockwise from 0 Degrees that starts angle drawing clockwise
'dAngleEnd is where the arc ends going clockwise with positive Degrees
' so if the arc end goes past 0 Degrees clockwise from dAngleStart
' express the end angle as 360 + angle
'rThick is the Radius of the many,many tiny circles this will draw to make the arc thick
' so if rThick = 2 the circles will have a Radius of 2 pixels and arc will be 4 pixels thick
If arcRadius < 1 Then PSet (xCenter, yCenter): Exit Sub
rAngleStart = _D2R(dAngleStart): rAngleEnd = _D2R(dAngleEnd)
If Int(rThick) = 0 Then Stepper = 1 / (arcRadius * _Pi) Else Stepper = rThick / (arcRadius * _Pi / 2)
For rAngle = rAngleStart To rAngleEnd Step Stepper
x1 = arcRadius * Cos(rAngle): y1 = arcRadius * Sin(rAngle)
If Int(rThick) < 1 Then
PSet (xCenter + x1, yCenter + y1)
Else
fcirc xCenter + x1, yCenter + y1, rThick, Ang_color
End If
Next
End Sub
Sub ThickLine (x1, y1, x2, y2, rThick, K As _Unsigned Long)
Dim length, stepx, stepy, dx, dy, i
'x1,y1 is one endpoint of line
'x2,y2 is the other endpoint of the line
'rThick is the Radius of the tiny circles that will be drawn
' from one end point to the other to create the thick line
'Yes, the line will then extend beyond the endpoints with circular ends.
stepx = x2 - x1
stepy = y2 - y1
length = (stepx ^ 2 + stepy ^ 2) ^ .5
If length Then
dx = stepx / length: dy = stepy / length
For i = 0 To length
fcirc x1 + dx * i, y1 + dy * i, rThick, K
Next
End If
End Sub
Sub fcirc (CX As Long, CY As Long, R As Long, C As _Unsigned Long)
Dim Radius As Long, RadiusError As Long
Dim X As Long, Y As Long
Radius = Abs(R): RadiusError = -Radius: X = Radius: Y = 0
If Radius = 0 Then PSet (CX, CY), C: Exit Sub
Line (CX - X, CY)-(CX + X, CY), C, BF
While X > Y
RadiusError = RadiusError + Y * 2 + 1
If RadiusError >= 0 Then
If X <> Y + 1 Then
Line (CX - Y, CY - X)-(CX + Y, CY - X), C, BF
Line (CX - Y, CY + X)-(CX + Y, CY + X), C, BF
End If
X = X - 1
RadiusError = RadiusError - X * 2
End If
Y = Y + 1
Line (CX - X, CY - Y)-(CX + X, CY - Y), C, BF
Line (CX - X, CY + Y)-(CX + X, CY + Y), C, BF
Wend
End Sub
the featured Sub Orbit calculates a point (xOut, yOut) from (Xorigin, Yorigin) a given degrees out and at a given radius length away.
The ThickArc routine works better than trying to draw arcs with built in Circle Sub (IMHO)
|