Seite 1 von 1

Koordinaten AUF Kreis errechnen (Analoge Uhr)

Verfasst: 29.01.2011 10:41
von Bisonte
Hallo miteinander.

Ich habe gerade mal ein mathematisches Problem,
wo ich grade wie der Ochs vorm Berge stehe :

Ich möchte mit 2D Befehlen eine analoge Uhr zeichnen.
Das ist an sich nicht das Problem (ganz simpel ein Kreis).

Nun kommen die Zeiger... Wie berechne ich die Koordinaten auf
der Kreislinie für den Line() Befehl... ?
Und wie berechne ich die Unterteilungen (in Sekunden und Stunden),
also wohin der Zeiger z.B. bei 22 Sekunden zeigen muss.

Da ich grad nicht weiss wie man das mathematisch nennt hilft mir Google
leider auch nicht weiter ;)

P.S. Es gab mal einen Code für diese Uhr aus dem Film das Boot, nur wurde dort
mit Screen und Sprite3D gearbeitet und dort entdeckte ich nicht mal den Ansatz
irgendeiner Formel...

Re: Koordinaten AUF Kreis errechnen (Analoge Uhr)

Verfasst: 29.01.2011 11:43
von NicknameFJ
Hallo Bisonte,

hier ein Link zu einem Analoguhr Programm von Stargate

http://www.purebasic.fr/german/viewtopi ... r&start=10

Vielleicht kannst Du Dir hieraus die nötigen Anregungen ziehen.

Grüße

NicknameFJ

Re: Koordinaten AUF Kreis errechnen (Analoge Uhr)

Verfasst: 29.01.2011 12:59
von Bisonte
Vielen Dank ...

Das sieht vielversprechend aus.
Hätt ich mir ja denken können, dass was matheartiges von Stargate ist ;)
Aber durchwühl mal seine gefühlten 2 Mio. Posts nach dem Wort Uhr ....

Re: Koordinaten AUF Kreis errechnen (Analoge Uhr)

Verfasst: 29.01.2011 13:21
von STARGÅTE
Der Source ist dort aber etwas übertrieben.

Eigentlich brauchst du nur sowas hier:

Code: Alles auswählen

Procedure.f ClockX(Value.f)
  ProcedureReturn Sin(Value*#PI*2)
EndProcedure

Procedure.f ClockY(Value.f)
  ProcedureReturn -Cos(Value*#PI*2)
EndProcedure
welched dir X, und Y geben wenn du der Prozedure eine Normierte Zeit gibst (Stunde/12, Minute/60, Sekunde/60)

Code: Alles auswählen

Enumeration
 #Window
 #Timer
 #Gadget
 #Image
EndEnumeration


Procedure.f ClockX(Value.f)
  ProcedureReturn Sin(Value*#PI*2)
EndProcedure

Procedure.f ClockY(Value.f)
  ProcedureReturn -Cos(Value*#PI*2)
EndProcedure

Procedure UpdateImage()
  Protected Hour, Minute, x, y
  Protected Time = Date()
  StartDrawing(ImageOutput(#Image))
    DrawingMode(#PB_2DDrawing_AllChannels)
    Box(0, 0, 400, 400, $00000000)
    DrawingMode(#PB_2DDrawing_AlphaBlend|#PB_2DDrawing_Transparent)
    ; Uhrhintergrund
    ; Stunden
    For Hour = 1 To 12
      x = 200+ClockX(Hour/12)*180 - TextWidth(Str(Hour))/2
      y = 200+ClockY(Hour/12)*180 - TextHeight(Str(Hour))/2
      DrawText(x, y, Str(Hour), $FF000000)
    Next
    ; Minuten/Sekunden
    For Minute = 1 To 60
      x = 200+ClockX(Minute/60)*160
      y = 200+ClockY(Minute/60)*160
      If Minute%5=0
        Circle(x, y, 3, $FF000000)
      Else
        Circle(x, y, 2, $80000000)
      EndIf
    Next
    ; Zeiger
    ; Stunde (mit Minutendifferenz)
    x = 200+ClockX(Hour(Time)/12+Minute(Time)/60/12)*100
    y = 200+ClockY(Hour(Time)/12+Minute(Time)/60/12)*100
    LineXY(200, 200, x, y, $FF000000)
    ; Minuten
    x = 200+ClockX(Minute(Time)/60)*140
    y = 200+ClockY(Minute(Time)/60)*140
    LineXY(200, 200, x, y, $FF000000)
    ; Sekunden
    x = 200+ClockX(Second(Time)/60)*160
    y = 200+ClockY(Second(Time)/60)*160
    LineXY(200, 200, x, y, $FF000000)
  StopDrawing()
  SetGadgetState(#Gadget, ImageID(#Image))
EndProcedure


CreateImage(#Image, 400, 400, 32|#PB_Image_Transparent)

OpenWindow(#Window, 0, 0, 400, 400, "Analoge Uhr", #PB_Window_MinimizeGadget|#PB_Window_ScreenCentered)
  ImageGadget(#Gadget, 0, 0, 400, 400, ImageID(#Image)) : UpdateImage()
  
AddWindowTimer(#Window, #Timer, 1000)

Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow
      End
    Case #PB_Event_Timer
      Select EventTimer()
        Case #Timer
          UpdateImage() 
      EndSelect
  EndSelect
ForEver
EDIT:
Mit rotierten Sprites3D gehts natürlich einfacher, da brauchst du dann nur die Normierte Zeit *360 rechnen und bekommst die richtige Rotation

Re: Koordinaten AUF Kreis errechnen (Analoge Uhr)

Verfasst: 29.01.2011 22:01
von Bisonte
Das ist natürlich noch einfacher ;) Danke...

Aber Sprite3D und Screen ist ein wenig "overdressed" für ein kleines "Uhrengadget" was ich versuche ;)