JClock VIII

Interpreting the hour hand on a clock as a two-dimensional object on a plane, the hand’s tip can be seen as a complex number.
This clock converts the hour hand’s position into a complex number, sets the number’s length to the current minutes and displays it in the form a + b \cdot i.
The angle \phi is determined by the hours passed (\frac{2 \cdot \pi \cdot \text{hour}}{12} = \frac{\pi \cdot \text{hour}}{6}) but has to be slightly modified because a complex number starts at the horizontal axis and turns anti-clockwise whilst an hour hand starts at the vertical axis and turns — as the name implies — clockwise.
Thus \phi = (2 \cdot \pi - \frac{\pi \cdot \text{hour}}{6}) + \frac{\pi}{2} = (\frac{15 - \text{hour}}{6}) \cdot \pi.
The complex number’s length is simply determined by the minutes passed. Because the length must not be equal to 0, I simply add 1. |z| = k = \text{minute} + 1.
Lastly, to convert a complex number in the form k \cdot e^{\phi \cdot i} into the form a + b \cdot i, I use the formula k \cdot (\cos{\phi} + \sin{\phi} \cdot i) = a + b \cdot i.

17:04


# Python 2.7.7 Code
# Pygame 1.9.1 (for Python 2.7.7)
# Jonathan Frech 29th of July, 2016

# Python 2.7.7 Code
# Pygame 1.9.1 (for Python 2.7.7)
# Jonathan Frech 29th of July, 2016

# importing needed modules
import pygame, sys, time, math, os, datetime
pygame.font.init()

""" CLASSES """
# screen class
class Screen():
	def __init__(self, size = None):
		if not size:
			self.size = [G.Width, G.Height]
		else:
			self.size = size

		self.surface = pygame.Surface(self.size)

	def swap(self):
		pass

	def render(self, surface):
		pass

	def tick(self):
		pass

	def handle(self, event):
		pass

# main screen
class mainScreen(Screen):
	def __init__(self):
		Screen.__init__(self)

		self.font = pygame.font.Font(pygame.font.match_font("Courier"), 50)

	def render(self, surface):
		self.surface.fill([10, 10, 10])
		
		now = datetime.datetime.now()
		hour = now.hour % 12
		minute = now.minute

		phi = ((15 - hour) / 6.) * math.pi
		k = minute + 1

		a = round( math.cos(phi) * k, 3)
		b = round( math.sin(phi) * k, 3)

		#s = str(k) + " * e**(" + str(phi) + "*i)"
		s = str(a) + [" + ", " - "][b<0] + str(abs(b)) + "i"
		print s

		txt = self.font.render(s, True, [255, 255, 255])
		rct = txt.get_rect()
		pos = [(G.Width-rct.right)/2, (G.Height-rct.bottom)/2]
		self.surface.blit(txt, pos)

		surface.blit(self.surface, [0, 0])

""" GAME """
# game class
class Game():
	def __init__(self):
		# screen (class)
		self.screenname = "main"
		
		# screen (window)
		self.Width, self.Height = 600, 300
		self.Size = [self.Width, self.Height]
		self.Screen = pygame.display.set_mode(self.Size)

		# running variables
		self.ticks = 0
		self.running = True

		# functions
		pygame.display.set_caption("JClock VIII")
	
	# further initialization
	def init(self):
		self.screens = {
			"main": mainScreen()
		}

	# get the screen based on name
	def screen(self):
		if self.screenname in self.screens:
			return self.screens[self.screenname]
		else:
			return Screen()

	def swapscreen(self, name = ""):
		self.screenname = name
		self.screen().swap()

	# tick function
	def tick(self):
		# handle events
		for event in pygame.event.get():
			
			# quit when window is closed
			if event.type == pygame.QUIT:
				self.quit()

			# handle key presses
			if event.type == pygame.KEYDOWN:
				# F12 quits
				if event.key == pygame.K_F12:
					self.quit()

				# F1 screenshots
				if event.key == pygame.K_F1:
					self.screenshot()

			# handle screen
			self.screen().handle(event)

		# tick screen
		self.screen().tick()

	# render function
	def render(self):
		# fill
		self.Screen.fill([0, 0, 0])
		
		#render screen
		self.screen().render(self.Screen)
		
		# flip
		pygame.display.flip()
	
	# quits
	def quit(self):
		self.running = False

	# takes a screenshot
	def screenshot(self):
		# define path
		path = os.getcwd() + "/out/"
		
		# try to save
		try:
			# create path
			if not os.path.isdir(path):
				os.mkdir(path)
			
			# define name
			now = datetime.datetime.now()
			name = "img" + str(len(os.listdir(path))) + " (" + str(now.hour) + "h " + str(now.minute) + "m).png"

			# save image
			pygame.image.save(self.Screen, path + name)
		
		# save failed somehow
		except:
			pass

	# run function (uses tick() and render())
	def run(self):
		ticksPerSecond = 60
		lastTime = time.time() * 1000000000
		nsPerTick =  1000000000.0 / float(ticksPerSecond)
	
		ticks = 0
		frames = 0
	
		lastTimer = time.time() * 1000
		delta = 0.0
		
		while self.running:
			now = time.time() * 1000000000
			delta += float(now - lastTime) / float(nsPerTick)
			lastTime = now
			shouldRender = False
					
			while delta >= 1:
				ticks += 1
				self.ticks += 1
				self.tick()
				delta -= 1
				shouldRender = True
			
			if shouldRender:
				frames += 1
				self.render()
			
			if time.time() * 1000 - lastTimer >= 1000:
				lastTimer += 1000
			
				frames = 0
				ticks = 0

# start game
G = Game()
G.init()
G.run()
Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s