A Tale of Two Clock Faces
BTW @TerryRitchie it took me forever to figure out why my Asteroids were upside down to yours.
You didn't follow your own rotation formula:
' for (x, y) around circle with center (xc, yc)
' x = xc + r * cos(a) BECOMES x = xc + sin(a) !!!!!!!!!!
' y = yc + r * sin(a) BECOMES y = yc + -cos(a) !!!!!!!!!!
You used a positive Cos eg, y = yc + r * cos(a)
Probably hacking the code because an unmodified _Atan2 was drawing it upside down with the minus sign.
In case someone doesn't have arial.ttf:
Code: (Select All)
_Title "Tale of Two Clock Faces" ' bplus 2024-10-11
' A tale of woe and miserable confusion between different coordinate systems.
' Well this tale can have a happy ending but everyone needs to understand what is happening.
Screen _NewImage(1200, 600, 32)
_ScreenMove 0, 60
_PrintMode _KeepBackground
a& = _LoadFont("arial.ttf", 32)
_Font a&
Do
Cls
clock_EastIsZero_Face 300, 300, 250
clock_NorthIsZero_Face 900, 300, 250
_Display
_Limit 60
Loop Until _KeyDown(27)
Sleep
Sub clock_EastIsZero_Face (x, y, r)
' x, y center r = radius
' for (x, y) around circle with center (xc, yc)
' if 0 degrees is East as it is for all Basic Trig Functions
' x = xc + r * cos(a)
' y = yc + r * sin(a)
' and hour starts at 3 o'clock for 0 Degrees
hour = 3 ' at a = 0 the first circle for hour will be drawn due East
For a = 0 To 359 Step 6 ' 360/6 = 60 tick for minutes
' mod 30 ? 360/30 = 12 ticks for every hour so make circle big enough to fit 2 digits 16x16
If a Mod 30 = 0 Then r1 = 0 Else r1 = 1 / 75 * r
' !!!!!!!!!!!!!!!!!!!! Regular Formula for x, y around circle center(x, y) !!!!!!!!!!!!!!!
circX = x + r * Cos(_D2R(a))
circY = y + r * Sin(_D2R(a))
' !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
If r1 Then Circle (circX, circY), r1, _RGB32(255, 255, 255)
If r1 Then Paint (circX, circY), _RGB32(255, 255, 255), _RGB32(255, 255, 255)
If a Mod 30 = 0 Then ' label hour
hourStr$ = _Trim$(Str$(hour))
xoffset = _PrintWidth(hourStr$) / 2
yoffset = 32 / 2
_PrintString (circX - xoffset, circY - yoffset), _Trim$(Str$(hour))
hour = hour + 1 ' get ready for next label
If hour > 12 Then hour = 1 ' cycle back to 1 after label 12
End If
Next
' the rest of this is based on regular East = 0 degrees
If Val(Left$(Time$, 2)) + (Val(Mid$(Time$, 4, 2)) / 60) >= 12 Then hrs = Val(Left$(Time$, 2)) + (Val(Mid$(Time$, 4, 2)) / 60) - 12 Else hrs = Val(Left$(Time$, 2)) + (Val(Mid$(Time$, 4, 2)) / 60)
ftri x + 1 / 15 * r * Cos(Val(Mid$(Time$, 4, 2)) * _Pi(1 / 30) - _Pi(1 / 2) + _Pi(1 / 2)), y + 1 / 15 * r * Sin(Val(Mid$(Time$, 4, 2)) * _Pi(1 / 30) - _Pi(1 / 2) + _Pi(1 / 2)), x + 1 / 15 * r * Cos(Val(Mid$(Time$, 4, 2)) * _Pi(1 / 30) - _Pi(1 / 2) - _Pi(1 / 2)), y + 1 / 15 * r * Sin(Val(Mid$(Time$, 4, 2)) * _Pi(1 / 30) - _Pi(1 / 2) - _Pi(1 / 2)), x + r * Cos(Val(Mid$(Time$, 4, 2)) * _Pi(1 / 30) - _Pi(1 / 2)), y + r * Sin(Val(Mid$(Time$, 4, 2)) * _Pi(1 / 30) - _Pi(1 / 2)), _RGB32(255, 0, 0)
ftri x + 1 / 10 * r * Cos(hrs * _Pi(1 / 6) - _Pi(1 / 2) + _Pi(1 / 2)), y + 1 / 10 * r * Sin(hrs * _Pi(1 / 6) - _Pi(1 / 2) + _Pi(1 / 2)), x + 1 / 10 * r * Cos(hrs * _Pi(1 / 6) - _Pi(1 / 2) - _Pi(1 / 2)), y + 1 / 10 * r * Sin(hrs * _Pi(1 / 6) - _Pi(1 / 2) - _Pi(1 / 2)), x + 2 / 3 * r * Cos(hrs * _Pi(1 / 6) - _Pi(1 / 2)), y + 2 / 3 * r * Sin(hrs * _Pi(1 / 6) - _Pi(1 / 2)), _RGB32(0, 0, 255)
Line (x, y)-(x + r * Cos(Val(Right$(Time$, 2)) * _Pi(1 / 30) - _Pi(1 / 2)), y + r * Sin(Val(Right$(Time$, 2)) * _Pi(1 / 30) - _Pi(1 / 2))), _RGB32(255, 255, 0)
Circle (x, y), 1 / 10 * r, _RGB32(255, 255, 255)
Paint (x + 1 / 75 * r, y + 1 / 75 * r), _RGB32(100, 100, 100), _RGB32(255, 255, 255)
Circle (x, y), 1 / 30 * r, _RGB32(0, 0, 0)
End Sub
Sub clock_NorthIsZero_Face (x, y, r)
' x, y center r = radius
' if 0 degrees is North then Rotate -90 degrees the angles
' for (x, y) around circle with center (xc, yc)
' x = xc + r * cos(a) BECOMES x = xc + sin(a) !!!!!!!!!!
' y = yc + r * sin(a) BECOMES y = yc + -cos(a) !!!!!!!!!!
' and hour starts at 12 o'clock for "0 degrees"
hour = 12 ' at a = 0 the first circle for hour will be drawn due East
For a = 0 To 359 Step 6 ' 360/6 = 60 tick for minutes
' mod 30 ? 360/30 = 12 ticks for every hour so make circle big enough to fit 2 digits 16x16
If a Mod 30 = 0 Then r1 = 0 Else r1 = 1 / 75 * r
' !!!!! Formula for (x, y) about circle center(x, y) !!!!!!!!!
circX = x + r * Sin(_D2R(a))
circY = y + r * -Cos(_D2R(a))
' !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
If r1 Then Circle (circX, circY), r1, _RGB32(255, 255, 255)
If r1 Then Paint (circX, circY), _RGB32(255, 255, 255), _RGB32(255, 255, 255)
If a Mod 30 = 0 Then ' label hour
hourStr$ = _Trim$(Str$(hour))
xoffset = _PrintWidth(hourStr$) / 2
yoffset = 32 / 2
_PrintString (circX - xoffset, circY - yoffset), _Trim$(Str$(hour))
hour = hour + 1 ' get ready for next label
If hour > 12 Then hour = 1 ' cycle back to 1 after label 12
End If
Next
' the rest of this is based on normal East = 0 degrees
If Val(Left$(Time$, 2)) + (Val(Mid$(Time$, 4, 2)) / 60) >= 12 Then hrs = Val(Left$(Time$, 2)) + (Val(Mid$(Time$, 4, 2)) / 60) - 12 Else hrs = Val(Left$(Time$, 2)) + (Val(Mid$(Time$, 4, 2)) / 60)
ftri x + 1 / 15 * r * Cos(Val(Mid$(Time$, 4, 2)) * _Pi(1 / 30) - _Pi(1 / 2) + _Pi(1 / 2)), y + 1 / 15 * r * Sin(Val(Mid$(Time$, 4, 2)) * _Pi(1 / 30) - _Pi(1 / 2) + _Pi(1 / 2)), x + 1 / 15 * r * Cos(Val(Mid$(Time$, 4, 2)) * _Pi(1 / 30) - _Pi(1 / 2) - _Pi(1 / 2)), y + 1 / 15 * r * Sin(Val(Mid$(Time$, 4, 2)) * _Pi(1 / 30) - _Pi(1 / 2) - _Pi(1 / 2)), x + r * Cos(Val(Mid$(Time$, 4, 2)) * _Pi(1 / 30) - _Pi(1 / 2)), y + r * Sin(Val(Mid$(Time$, 4, 2)) * _Pi(1 / 30) - _Pi(1 / 2)), _RGB32(255, 0, 0)
ftri x + 1 / 10 * r * Cos(hrs * _Pi(1 / 6) - _Pi(1 / 2) + _Pi(1 / 2)), y + 1 / 10 * r * Sin(hrs * _Pi(1 / 6) - _Pi(1 / 2) + _Pi(1 / 2)), x + 1 / 10 * r * Cos(hrs * _Pi(1 / 6) - _Pi(1 / 2) - _Pi(1 / 2)), y + 1 / 10 * r * Sin(hrs * _Pi(1 / 6) - _Pi(1 / 2) - _Pi(1 / 2)), x + 2 / 3 * r * Cos(hrs * _Pi(1 / 6) - _Pi(1 / 2)), y + 2 / 3 * r * Sin(hrs * _Pi(1 / 6) - _Pi(1 / 2)), _RGB32(0, 0, 255)
Line (x, y)-(x + r * Cos(Val(Right$(Time$, 2)) * _Pi(1 / 30) - _Pi(1 / 2)), y + r * Sin(Val(Right$(Time$, 2)) * _Pi(1 / 30) - _Pi(1 / 2))), _RGB32(255, 255, 0)
Circle (x, y), 1 / 10 * r, _RGB32(255, 255, 255)
Paint (x + 1 / 75 * r, y + 1 / 75 * r), _RGB32(100, 100, 100), _RGB32(255, 255, 255)
Circle (x, y), 1 / 30 * r, _RGB32(0, 0, 0)
End Sub
Sub ftri (x1, y1, x2, y2, x3, y3, K As _Unsigned Long)
a& = _NewImage(1, 1, 32)
_Dest a&
PSet (0, 0), K
_Dest 0
_MapTriangle _Seamless(0, 0)-(0, 0)-(0, 0), a& To(x1, y1)-(x2, y2)-(x3, y3)
_FreeImage a& '<<< this is important!
End Sub
BTW @TerryRitchie it took me forever to figure out why my Asteroids were upside down to yours.
You didn't follow your own rotation formula:
' for (x, y) around circle with center (xc, yc)
' x = xc + r * cos(a) BECOMES x = xc + sin(a) !!!!!!!!!!
' y = yc + r * sin(a) BECOMES y = yc + -cos(a) !!!!!!!!!!
You used a positive Cos eg, y = yc + r * cos(a)
Probably hacking the code because an unmodified _Atan2 was drawing it upside down with the minus sign.
In case someone doesn't have arial.ttf:
b = b + ...