Mohamad Homaei
Mohamad Homaei

Reputation: 1

I wrote the code for this analog clock, but I don't know why place of the numbers are not correct

import pygame
from math import radians, sin, cos
from datetime import datetime

class Clock:
    def __init__(self):
        self.width, self.height = 800, 800
        self.white = (255, 255, 255)
        self.blue = (34, 79, 228)
        self.FBS = 60
        self.center = (self.width // 2, self.height // 2)
        self.clock_radius = self.width // 2

        pygame.init()
        self.screen = pygame.display.set_mode((self.width, self.height))
        pygame.display.set_caption('Analog Clock')
        self.clock = pygame.time.Clock()

    def numbers(self, number, size, position):
        font = pygame.font.SysFont('Calibri', size, True, False)
        text = font.render(str(number), True, self.white)
        text_rect = text.get_rect(center=position)
        self.screen.blit(text, text_rect)

    def polar_to_cartesian(self, r, theta):
        x = r * sin(radians(theta))
        y = r * cos(radians(theta))
        return self.width//2 + x, self.height//2 + y

    def draw_circle(self, screen):
        # main circle
        pygame.draw.circle(self.screen, self.white, self.center, self.clock_radius - 10, 5)
        # center circle
        pygame.draw.circle(self.screen, self.white, self.center, 10)

        for number in range(1, 13):
            self.numbers(number, 60, self.polar_to_cartesian(self.clock_radius - 80, number * 30))

        for number in range(0, 360, 6):
            if number % 5:
                pygame.draw.line(self.screen, self.white, self.polar_to_cartesian(
                    self.clock_radius - 15, number), self.polar_to_cartesian(self.clock_radius - 30, number),2)
            else:
                pygame.draw.line(self.screen, self.white, self.polar_to_cartesian(
                    self.clock_radius - 15, number), self.polar_to_cartesian(self.clock_radius - 35, number), 6)

    def draw_clock_hand(self):
        current_time = datetime.now()
        second = current_time.second
        minute = current_time.minute
        hour = current_time.hour

        # hour
        rad = self.clock_radius - 190
        theta = (hour + minute/60 + second/3600) * 360 / 12
        pygame.draw.line(self.screen, self.white, self.center, self.polar_to_cartesian(rad, theta), 14)
        # # minute
        rad = self.clock_radius - 150
        theta = (minute + second / 3600) * 360 / 60
        pygame.draw.line(self.screen, self.white, self.center, self.polar_to_cartesian(rad, theta), 10)
        # # second
        rad = self.clock_radius - 100
        theta = second * 360 / 60
        pygame.draw.line(self.screen, self.white, self.center, self.polar_to_cartesian(rad, theta), 4)

    def run(self):
        while True:
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    exit()

            self.screen.fill(self.blue)
            self.draw_circle(self.screen)
            self.draw_clock_hand()
            pygame.display.update()
            self.clock.tick(self.FBS)


if __name__ == '__main__':
    myClock = Clock()
    myClock.run()

Upvotes: 0

Views: 40

Answers (1)

Vecta
Vecta

Reputation: 46

First of all, thats very cool. Good job.

One thing, if you could keep your question title concise and provide details in the post body, that would make your post much easier to read. The thing about the cartesian is that it increases counter-clockwise. You need to reverse your degrees so that as the number increases the radial degree decreases, this will make it run clockwise.

for number in range(1, 13):
    self.numbers(number, 60, self.polar_to_cartesian(self.clock_radius - 80, number * -30))

Reversed numbers running clockwise

The you'll need to offset the numbers by 180 degrees:

for number in range(1, 13):
    self.numbers(number, 60, self.polar_to_cartesian(self.clock_radius - 80, number * -30 - 180))

Corrected numbers

Upvotes: 0

Related Questions