Oh I had it right!
Testing a mod to _ATan2 that will treat North as 0 Dgerees or Radians and go Clockwise around ascending angle value.
See now it fixes a couple mixups in Lesson 17 Asteroid Demo
BTW I dislike this immensely:
So much easier and straight forward to use East = 0 degrees and not have to modify _ATan2.
Then
' Vx = Cos(angle)
' Vy = Sin(angle)
Since sin(a)^2 + cos(a)^2 = 1, you have your Normal Vector
(x, y) around the point (xcenter, ycenter)
x = xcenter + radius*Cos(angle)
y = ycenter + radius*Sin(angle)
x is always associated with Cos
y is always associated with Sin.
But it appears Terry has invested heavily in that formula for Vx, Vy from Lesson 17.
Testing a mod to _ATan2 that will treat North as 0 Dgerees or Radians and go Clockwise around ascending angle value.
Code: (Select All)
Option _Explicit
_Title "Atan4North0 test" ' bplus 2024-10-11
' testing an ATan function that would return 0 for North AND increase going Clockwise around
Screen _NewImage(1200, 600, 32)
_ScreenMove 40, 60
Dim degree30, xc1, xc, yc, xc2, r, a, x1, y1, at, sa$, xoff, yoff, x2, y2
degree30 = _Pi(2 / 12) ' 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 degree30
' 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 1
Next
Function ATan4North0 (dy, dx)
ATan4North0 = _Pi - _Atan2(dx, dy) ' this was totally unexpected!
End Function
See now it fixes a couple mixups in Lesson 17 Asteroid Demo
Code: (Select All)
_Title "** Asteroid demo using radians fix" ' bplus 2024-10-11
' fix -COS and alternate _ATAN2 for North = 0 calcs using ATan4North0
' From Lesson 17
' Vx! = Sin(_D2R(Degree!)) ' calculate the x vector quantity
' Vy! = -Cos(_D2R(Degree!)) ' calculate the y vector quantity
' Notice the negative sign next to Cos.
' This is a rotation of the coordinate system so _Atan2 is not going to return
' correct radian angle to match North = 0
' I added a modified ATan4North function to use in place of _Atan2 for Asteroid Demo
' to work as Terry intended using those Vx Vy forumlas.
Const FALSE = 0, TRUE = Not FALSE ' truth detectors
Const PI = 3.1415926, PI2 = 2 * PI ' useful PI values
Const SPINRATE = PI2 / 360 ' asteroid spin rate
Const SWIDTH = 640, SHEIGHT = 480 ' screen dimensions
Const MAXASTEROIDS = 20 ' number of asteroids on screen
Type XYPAIR ' 2D point location definition
x As Single ' x coordinate
y As Single ' y coordinate
End Type
Type OBJECT ' object definition (points that make up an object)
Radian As Single ' direction of point
Radius As Single ' distance to point from center
End Type
Type ASTEROID ' asteroid definition
Loc As XYPAIR ' asteroid location
Dir As Single ' asteroid radian direction
Speed As Integer ' asteroid speed
Size As Integer ' asteroid size
End Type
Dim Object(10) As OBJECT ' object point data
Dim Asteroid(MAXASTEROIDS) As ASTEROID ' asteroids array
Dim Vector As XYPAIR ' vector calculations
Dim Obj As Integer ' object counter
Dim Ast As Integer ' asteroid counter
Dim P1 As XYPAIR ' first object point for PSET
Dim Np As XYPAIR ' next object point for LINE
Dim Spin As Integer ' TRUE to activate spin, FALSE otherwise
Randomize Timer ' seed RND generator
For Obj = 1 To 10 ' cycle through object points
Read Vector.x, Vector.y ' get object x,y vector point
Object(Obj).Radius = _Hypot(Vector.x, Vector.y) ' calculate radius from vector
' _Atan2 takes y's first , x's 2nd
' so modified ATan4North0(Vector.y, Vector.x)
' uses the same order
Object(Obj).Radian = ATan4North0(Vector.y, Vector.x) ' calculate direction from vector
Next Obj
For Ast = 1 To MAXASTEROIDS ' cycle through asteroids
Asteroid(Ast).Loc.x = Int(Rnd * (SWIDTH - 40)) + 20 ' random location
Asteroid(Ast).Loc.y = Int(Rnd * (SHEIGHT - 40)) + 20
Asteroid(Ast).Dir = Rnd * PI2 ' random direction
Asteroid(Ast).Speed = Int(Rnd * 6) + 2 ' random speed
Asteroid(Ast).Size = 2 ^ Int(Rnd * 3) ' random size
Next Ast
Screen _NewImage(SWIDTH, SHEIGHT, 32) ' graphics screen
Spin = FALSE ' no asteroid spin
Do ' begin main loop
Cls ' clear screen
_Limit 60 ' 60 frames per second
Locate 2, 19: Print "Press the spacebar to activate asteroid spin" ' print directions
If _KeyHit = 32 Then Spin = Not Spin ' flip spin flag if spacebar pressed
If Spin Then ' spin asteroids?
For Obj = 1 To 10 ' yes, cycle through object points
Object(Obj).Radian = Object(Obj).Radian + SPINRATE ' move radian location
If Object(Obj).Radian > PI2 Then Object(Obj).Radian = Object(Obj).Radian - PI2 ' keep within limits
Next Obj
End If
For Ast = 1 To MAXASTEROIDS ' cycle through asteroids
Vector.x = Sin(Object(1).Radian) ' calculate vector from 1st object point
Vector.y = -Cos(Object(1).Radian) ' <<< This should be -Cos
P1.x = Asteroid(Ast).Loc.x + Vector.x * Object(1).Radius * Asteroid(Ast).Size ' plot location on screen
P1.y = Asteroid(Ast).Loc.y + Vector.y * Object(1).Radius * Asteroid(Ast).Size
PSet (P1.x, P1.y) ' draw a pixel
For Obj = 2 To 10 ' cycle through remaining points
' these assume North = 0 so Vectors are rotated 90 degrees
Vector.x = Sin(Object(Obj).Radian) ' calculate vector from object point
Vector.y = -Cos(Object(Obj).Radian) ' <<<< this should be -Cos
Np.x = Asteroid(Ast).Loc.x + Vector.x * Object(Obj).Radius * Asteroid(Ast).Size ' plot location
Np.y = Asteroid(Ast).Loc.y + Vector.y * Object(Obj).Radius * Asteroid(Ast).Size ' on screen
Line -(Np.x, Np.y) ' draw line from previous point
Next Obj
Line -(P1.x, P1.y) ' draw final line back to start
Vector.x = Sin(Asteroid(Ast).Dir) ' get vector from asteroid radian
Vector.y = -Cos(Asteroid(Ast).Dir) ' <<< This should be -Cos
Asteroid(Ast).Loc.x = Asteroid(Ast).Loc.x + Vector.x * Asteroid(Ast).Speed ' plot location on screen
Asteroid(Ast).Loc.y = Asteroid(Ast).Loc.y + Vector.y * Asteroid(Ast).Speed
If Asteroid(Ast).Loc.x < -19 Then Asteroid(Ast).Loc.x = SWIDTH + 19 ' keep asteroids on screen
If Asteroid(Ast).Loc.x > SWIDTH + 19 Then Asteroid(Ast).Loc.x = -19
If Asteroid(Ast).Loc.y < -19 Then Asteroid(Ast).Loc.y = SHEIGHT + 19
If Asteroid(Ast).Loc.y > SHEIGHT + 19 Then Asteroid(Ast).Loc.y = -19
Next Ast
_Display ' update screen with changes
Loop Until _KeyDown(27) ' leave when ESC pressed
System ' return to operating system
' Asteroid object data (10 coordinate vector points)
Data 0,-5,5,-10,10,-5,7,0,10,5,2,10,-5,10,-10,5,-10,-5,-5,-10
Function ATan4North0 (dy, dx)
ATan4North0 = _Pi - _Atan2(dx, dy) ' this was totally unexpected!
End Function
BTW I dislike this immensely:
Code: (Select All)
' From Lesson 17
' Vx! = Sin(_D2R(Degree!)) ' calculate the x vector quantity
' Vy! = -Cos(_D2R(Degree!)) ' calculate the y vector quantity
So much easier and straight forward to use East = 0 degrees and not have to modify _ATan2.
Then
' Vx = Cos(angle)
' Vy = Sin(angle)
Since sin(a)^2 + cos(a)^2 = 1, you have your Normal Vector
(x, y) around the point (xcenter, ycenter)
x = xcenter + radius*Cos(angle)
y = ycenter + radius*Sin(angle)
x is always associated with Cos
y is always associated with Sin.
But it appears Terry has invested heavily in that formula for Vx, Vy from Lesson 17.
b = b + ...