[C++] Berechnung des Winkels zwischen Stunden- und Minutenzeiger (Uhr)

albaum

Ensign
Registriert
Juli 2014
Beiträge
172
Hallo,

ich wollte ein Programm schreiben womit ich den Winkel zwischen Stunden- und Minutenzeiger ausrechnen kann.
Dafür habe ich ausgerechnet wie viel Grad sich der Stunden- und Minutenzeiger sich pro Minute bewegen: Stundenzeiger bewegt sich pro Minute 3° und Minutenzeiger bewegt sich pro Minute 6°.
Da sich beide Zeiger ständig bewegen, müsste für die Stunde die Formel: 360-3*Stunde, gelten
und für die Minute die Formel: 360-6*Minute, gelten.

Jedoch habe ich einige Probleme.

Zum Beispiel wenn ich die Stunde: 10 und die Minute: 30 eingebe, dann kommt ein Winkel von 150° heraus, aber der Winkel beträgt eigentlich 135°...

Dann wollte ich noch nachfragen ob man es irgendwie hinbekommen kann dass die Stunde, die die Person eingeben soll, auch nach der Ausgabe "Stunde:" steht und nicht eine Zeile drunter und dasselbe mit der Minute.
Im Moment sieht es so aus:

" Stunden:
10
Minuten:
30
Der Winkel betraegt 150 Grad"

Ich hoffe ihr könnt mir helfen da ich schon länger versuche den Fehler zu finden aber es irgendwie nicht schaffe den Grad-Rechner zum laufen zu bekommen.

PHP:
#include <iostream>

using namespace std;

int main ()
{
	int WinkelStunde;
	int WinkelMinute;
	int Stunde;
	int Minute;
	int Winkel;

	cout << " Stunden:" << "" << endl;
	cin >> Stunde;
	cout << " Minuten: " << "" << endl;
	cin >> Minute;

	WinkelStunde= 360-3*Stunde;
	WinkelMinute= 360-6*Minute;

	Winkel= WinkelStunde - WinkelMinute;


	cout <<"Der Winkel betraegt " << Winkel << " " << "Grad" << endl;

	return 0;
}
 
Zuletzt bearbeitet:
Stundenzeiger bewegt sich pro Minute 3° und Minutenzeiger bewegt sich pro Minute 6°.
Bist du dir da ganz ganz ganz sicher?
 
Jap. überprüfe mal deine Formeln. Und wenn du dann richtige Formeln hast, deklariere manche der Variablen als Gleitkomma.
 
Minutenzeiger: 360°/60Minuten=6°
=> Der Minutenzeiger bewegt sich 6° pro Minute.
Stundenzeiger: bewegt sich in 3 Stunden 90° => 90/3=30° => In einer Stunde bewegt sich der Zeiger um 30° => pro Minute 0,5°

Ups... Habe mich da wohl doch verrechnet... Jedoch kommt bei mir, bei 10 Stunden und 30 Minuten nur 120° raus (wobei es eigentlich 135° sein sollten)

Edit: Bei Stunde angefügt => pro Minute 0,5°
 
Für die gleiche Zeile solltest Du das endl weglassen. Zu den Bewegungen pro Minute haben die beiden vor mir ja schon gepostet. 3 Grad pro Minute würden 180 Grad Drehung des Stundenzeigers in einer Stunde bedeuten.
 
albaum schrieb:
Zum Beispiel wenn ich die Stunde: 10 und die Minute: 30 eingebe, dann kommt ein Winkel von 150° heraus, aber der Winkel beträgt eigentlich 135°...
Wie kommst du auf den Winkel? Dieser müsste 120° lauten. Am besten du rechnest die Stunden in Minuten um oder die Minuten in Stunden..
 
@ModellbahnerTT Der Stundenzeiger soll sich pro Minute mitdrehen somit komme ich auf die 135°

Verbessert:

Bsp: Stunden: 10
Minuten:30
Grad: 175Grad (müsste eig 135° sein)

Bsp: Stunden:9
Minuten:30
Grad: 175Grad (müsste eig 105° sein)


PHP:
#include <iostream>

using namespace std;

int main ()
{
	char WinkelStunde;
	char WinkelMinute;
	int Stunde;
	int Minute;
	int Winkel;

	cout << " Stunden:" << ""; 
	cin >> Stunde;
	cout << " Minuten: " << "";
	cin >> Minute;

	WinkelStunde= 360-0.5*Stunde;
	WinkelMinute= 360-6*Minute;

	Winkel= WinkelStunde - WinkelMinute;


	cout <<"Der Winkel betraegt " << Winkel << " " << "Grad" << endl;

	return 0;
}

Sind meine Berechnungen beim Stundenzeiger oder Minutenzeiger falsch?
 
Zuletzt bearbeitet:
Dein Programm ist mit diesen Datentypen nicht möglich. Du kannst du Stundenbewegung nicht in Integer ausdrücken (ok man kann, aber nur indem man es unnötig komplizierter macht). Deine Zeile 18 ist eben komplett falsch.

Als Beispielrechnung für 9:30:
Zeile 18 Resultat: 360 - 30*9 = 90
Zeile 19 Resultat: 360 - 6 * 30 = 180

Zeile 21 Resultat deswegen: 90 - 180 = -90. Wie zur Hölle kommst du auf 166° ?

PS: nein auch auf das geänderte 175° kannst du nicht kommen. Geht schlicht nicht mit diesem Programm.
 
Zuletzt bearbeitet:
Warum läuft deine Uhr eigentlich Rückwärts? Oder warum die 360-
 
Die Winkelstunde ist ja eben nicht nur "WinkelStunde= 360-0.5*Stunde;"
pro STUNDE ändert sich der Winkel um 30°, pro weitere MINUTE um 0,5°.
Also musst du sowohl die 30° mit den Stunden, als auch die 0,5° mit den Minuten iwie in der Winkelstunde unterbringen.

Desweiteren solltest du vllt das Vorzeichen am Ende mal prüfen.
 
Zuletzt bearbeitet:
Jetzt verrat doch nicht alles ;)
 
Er hat nichts verraten, sondern nur durch weitere Fehler, mehrere Fehler, das Problem vergrößert.
 
@Bonanca bin grad ebend auch drauf gekommen, jedoch funktioniert mein Programm weiterhin nicht...

PHP:
#include <iostream>

using namespace std;

int main ()
{
	char WinkelStunde;
	char WinkelMinute;
	int Stunde;
	int Minute;
	int Winkel;

	cout << " Stunden:" << ""; 
	cin >> Stunde;
	cout << " Minuten: " << "";
	cin >> Minute;

	WinkelMinute= 360-6*Minute;  //Berechnet den Winkel des Minutenzeigers
	WinkelStunde= 360-30*Stunde; //Berechnet den Winkel der vollen Stunde
	WinkelStunde -= 0.5*Minute;  // Berechnet den Winkel des Stundenzeigers in Abhängigkeit des Minutenzeiger

		if (WinkelStunde < WinkelMinute)
		{
		Winkel = WinkelMinute - WinkelStunde;
		}
		
		if (WinkelStunde > WinkelMinute)
		{
		Winkel= WinkelStunde - WinkelMinute;
		}


	cout <<"Der Winkel betraegt " << Winkel << " " << "Grad" << endl;

	return 0;
}

Stunden:9
Minuten: 30
Der Winkel betraegt 151 Grad

Stunden:10
Minuten: 30
Der Winkel betraegt 121 Grad

Edit: Problem gefunden
 
Zuletzt bearbeitet:
Ich hab auf der Arbeit schon genug damit zu tun Schüler nur auf den richtigen Weg zu 'lenken', da muss ich das eigtl nicht hier auch noch haben :D
Aber ja hast ja recht ;)

@Homini:
Ob das Problem vergrößert wurde finde ich ist ansichtssache, ich habe mich lediglich an dem Lösungsansatz vom TE orientiert.
Dass es dann immernoch nicht vollends funktionierten wird damit ist klar, liegt aber nicht nur an der Berechnung der Winkelstunde.
 
Zuletzt bearbeitet:
So, das Problem war, wie HominiLupus schon beschrieben hat, dass die Uhr falsch herum läuft. Nun habe ich die -360° entfernt und es sollte das richtige rauskommen oder?

Die Rechnung habe ich als Kommentar dahinter angefügt. Jedoch kommt 75° heraus (bei Stunden: 9 und Minuten: 30) was ich mir ehrlich gesagt nicht erklären kann.

PHP:
#include <iostream>

using namespace std;

int main ()
{
	char WinkelStunde;
	char WinkelMinute;
	int Stunde;
	int Minute;
	int Winkel;

	cout << " Stunden:" << ""; 
	cin >> Stunde;
	cout << " Minuten: " << "";
	cin >> Minute;

	WinkelMinute= 6*Minute;  // 6*30=180°
	WinkelStunde= 30*Stunde; // 30*9=270°
	WinkelStunde = WinkelStunde - 0.5*Minute; // 270°-0,5*30=285°

		if (WinkelStunde < WinkelMinute)
		{
		Winkel = WinkelMinute - WinkelStunde;
		}
		
		if (WinkelStunde > WinkelMinute)
		{
		Winkel= WinkelStunde - WinkelMinute; //285°-180°=105
		}


	cout <<"Der Winkel betraegt " << Winkel << " " << "Grad" << endl;

	return 0;
}
Ergänzung ()

Habe in Zeile 20 Minus anstatt Plus stehen. Fehler behoben und Programm läuft.

Werde das Thema als gelöst markieren.

Vielen Dank für eure Hilfe!!!:)
 
Bonanca schrieb:
Ob das Problem vergrößert wurde finde ich ist ansichtssache, ich habe mich lediglich an dem Lösungsansatz vom TE orientiert.
Dass es dann immernoch nicht vollends funktionierten wird damit ist klar, liegt aber nicht nur an der Berechnung der Winkelstunde.
Doch, weil du abgezogen hast. Zudem Integer, nix mit 0.5 da. Wenn du 9:30 berechnest kommt 8:30 raus. Im günstigsten Falle.
 
@albaum: Dein Code funktioniert nur für 314 von 720 möglichen Inputs! Du hast ein Integer-Overflow Problem, weil chars nur von -128 bis 127 gehen. Zudem rechnest du mit ganzen Zahlen, obwohl manche Ergebnisse Nachkommastellen haben.
Außerdem ist deine Winkelberechnung fragwürdig. Warum ist der Winkel um 12:59 gleich 324.5° (wenn man richtig rechnet) und um 1:00 gleich 30°? Der Konsistenz halber sollte der Winkel doch viel eher 330° sein. Und erst wenn der Minutenzeiger den Stundenzeiger wieder einholt, sollte der Winkel wieder bei 0 anfangen.

Edit: Weil mir gerade langweilig war, habe ich was ich meine noch etwas visualisiert:
12.59.png1.00.png

Gruß
BlackMark
 
Zuletzt bearbeitet:
Ich weiß nicht ob du es mittlerweile hinbekommen hast, aber das ganze habe ich mal schnell in C# runterprogrammiert inkl. Visualisierung mit Graphics (lässt sich problemlos aber in andere Sprache adaptieren).
Der Trick hierbei ist schlichtweg alles in die kleinste Einheit umzurechnen - Sekunden z.b. und dann einfach nur die Skalierung berechnen mit dem Tau (2 PI) multipliziert werden muss. Wobei wichtig ist, das eine Umdrehung für den Stundenzeiger 2 * Tau entspricht und nicht 1 Tau!

Code:
    public partial class MainForm : Form
    {      
        Font font;

        private static float GetSecondsFromTime(int hour, int min, int sec)
        {
            Debug.Assert(hour >= 0 && hour <= 23);
            Debug.Assert(min >= 0 && min <= 59);
            Debug.Assert(sec >= 0 && sec <= 59);
            float result = hour * 60.0f * 60.0f + min * 60.0f + sec;
            return (result);
        }

        private static string GetTimeFromSeconds(float seconds)
        {
            int hours = (int)Math.Floor(seconds / (60.0f * 60.0f));
            int mins = (int)Math.Floor((seconds / 60.0f) % 60);
            int secs = (int)seconds % 60;
            string result = string.Format("{0:D2}:{1:D2}:{2:D2}", hours, mins, secs);
            return (result);
        }

        public MainForm()
        {
            InitializeComponent();
            DateTime now = DateTime.Now;
            timeInSeconds = GetSecondsFromTime(now.Hour, now.Minute, now.Second);
        }

        const float DayInSeconds = 24.0f * 60.0f * 60.0f;
        float timeInSeconds = 0.0f;

        private void MainForm_Paint(object sender, PaintEventArgs e)
        {
            // Radiant nach Grad Factor
            const float Rad2Deg = 180.0f / (float)Math.PI;

            // Es gibt kein Float PI und auch kein Tau in C# -.-
            const float Pi = (float)Math.PI;
            const float Tau = Pi * 2.0f;

            // Uhr radius in pixel
            const float clockRadius = 200.0f;
            const float innerRadius = 6.0f;

            // Zeiger -und Tickdistanzen
            const float hoursHalfDistance = clockRadius * 0.7f;
            const float minutesHalfDistance = clockRadius * 0.8f;
            const float secondsHalfDistance = clockRadius * 0.9f;
            const float hoursTicksDistance = clockRadius * 0.1f;
            const float minsTicksDistance = clockRadius * 0.075f;

            // Zentrum
            float centerX = Width / 2.0f;
            float centerY = Height / 2.0f;

            // Winkel in radianten Umrechnen
            float minutes = (timeInSeconds / 60.0f) % 60.0f;
            float seconds = timeInSeconds % 60.0f;
            float hoursAngle = (Tau * 2) * (timeInSeconds / DayInSeconds) + Pi;
            float minutesAngle = Tau * (minutes / 60.0f) + Pi;
            float secondsAngle = Tau * (seconds / 60.0f) + Pi;

            // Antialiasing aktivieren
            e.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;

            // Hintergründe zeichnen
            e.Graphics.FillRectangle(new SolidBrush(Color.White), new RectangleF(0, 0, Width, Height));
            e.Graphics.DrawArc(new Pen(Color.Black, 1.0f), centerX - clockRadius, centerY - clockRadius, clockRadius * 2, clockRadius * 2, 0, Rad2Deg * Pi * 2.0f);
            e.Graphics.DrawArc(new Pen(Color.Black, 1.0f), centerX - innerRadius, centerY - innerRadius, innerRadius * 2, innerRadius * 2, 0, Rad2Deg * Pi * 2.0f);

            // Stundenmarkierungen zeichnen
            for (int i = 0; i < 12; ++i)
            {
                float a = (i / 12.0f) * Tau + Pi;
                float ax = centerX + (-(float)Math.Sin(a)) * clockRadius;
                float ay = centerY + ((float)Math.Cos(a)) * clockRadius;
                float bx = centerX + (-(float)Math.Sin(a)) * (clockRadius - hoursTicksDistance * 0.5f);
                float by = centerY + ((float)Math.Cos(a)) * (clockRadius - hoursTicksDistance * 0.5f);
                e.Graphics.DrawLine(new Pen(Color.Black, 3.0f), ax, ay, bx, by);
            }
            // Minutenmarkierungen zeichnen
            for (int i = 0; i < 60; ++i)
            {
                float a = (i / 60.0f) * Tau + Pi;
                float ax = centerX + (-(float)Math.Sin(a)) * clockRadius;
                float ay = centerY + ((float)Math.Cos(a)) * clockRadius;
                float bx = centerX + (-(float)Math.Sin(a)) * (clockRadius - minsTicksDistance * 0.5f);
                float by = centerY + ((float)Math.Cos(a)) * (clockRadius - minsTicksDistance * 0.5f);
                e.Graphics.DrawLine(new Pen(Color.Black, 1.0f), ax, ay, bx, by);
            }

            // Zeiger zeichnen
            {
                float tx = centerX + (-(float)Math.Sin(secondsAngle)) * secondsHalfDistance;
                float ty = centerY + ((float)Math.Cos(secondsAngle)) * secondsHalfDistance;
                e.Graphics.DrawLine(new Pen(Color.Yellow, 2.0f), centerX, centerY, tx, ty);
            }
            {
                float tx = centerX + (-(float)Math.Sin(minutesAngle)) * minutesHalfDistance;
                float ty = centerY + ((float)Math.Cos(minutesAngle)) * minutesHalfDistance;
                e.Graphics.DrawLine(new Pen(Color.Red, 4.0f), centerX, centerY, tx, ty);
            }
            {
                float tx = centerX + (-(float)Math.Sin(hoursAngle)) * hoursHalfDistance;
                float ty = centerY + ((float)Math.Cos(hoursAngle)) * hoursHalfDistance;
                e.Graphics.DrawLine(new Pen(Color.Blue, 8.0f), centerX, centerY, tx, ty);
            }

            // Text zeichnen
            string timeStr = GetTimeFromSeconds(timeInSeconds);
            e.Graphics.DrawString($"Sekunden: {timeInSeconds}, Uhrzeit: {timeStr}", font, new SolidBrush(Color.Black), 0, 0);
        }

        private void MainForm_SizeChanged(object sender, EventArgs e)
        {
            Invalidate();
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            DateTime now = DateTime.Now;
            timeInSeconds = GetSecondsFromTime(now.Hour, now.Minute, now.Second);
            /*
            timeInSeconds += 1.0f;
            if (timeInSeconds > DayInSeconds)
            {
                timeInSeconds = 0.0f;
            }
            */
            Invalidate();
        }

        private void MainForm_Load(object sender, EventArgs e)
        {
            font = Font;
        }
    }
 
Zuletzt bearbeitet:
Zurück
Oben