WindMessAnlage/Display/elements/Compass.py

138 lines
5.2 KiB
Python

import pygame
import math
class Compass():
def __init__(self, font_size, size):
pygame.font.init()
self.textColor = pygame.Color("white")
self.backgroundColor = pygame.Color("White")
self.needleColor = pygame.Color("black")
self.font = pygame.font.Font(pygame.font.get_default_font(), font_size)
self.surface = pygame.Surface(size, pygame.SRCALPHA)
self.size = size
self.x = 0
self.y = 0
self.backgroundSurface = None
def setX(self, x):
self.x = x
def getX(self):
return self.x
def setY(self, y):
self.y = y
def getY(self):
return self.y
def get(self):
return self.surface
def setTextColor(self, color):
try:
self.textColor = pygame.Color(color)
except:
self.textColor = pygame.Color("black")
def setBackgroundColor(self, color):
try:
self.backgroundColor = pygame.Color(color)
except:
self.backgroundColor = pygame.Color("white")
def setNeedleColor(self, color):
try:
self.needleColor = pygame.Color(color)
except:
self.needleColor = pygame.Color("black")
def update(self, value):
raise NotImplementedError()
class MiddleNeedle(Compass):
def update(self, value):
radius = min(self.size[0]//2, self.size[1]//2)
pygame.draw.circle( self.surface, self.backgroundColor, (self.size[0]//2, self.size[1]//2), radius)
arrow = pygame.Surface( ((self.size[0]//100*60)//2, self.size[1]//100*60), pygame.SRCALPHA )
polygon_list = [
( arrow.get_width()//2, 0 ), #Middle top
( 0, arrow.get_height() ), #bottom left
( arrow.get_width()//2, (arrow.get_height()-arrow.get_height()//100*30) ), #middle pos
( arrow.get_width(), arrow.get_height() ), #bottom right
]
pygame.draw.polygon(arrow, self.needleColor, polygon_list)
arrow = pygame.transform.rotate( arrow, value )
self.surface.blit( arrow, ( (self.size[0]//2)-(arrow.get_width()//2), (self.size[1]//2)-(arrow.get_height()//2)))
text = self.font.render("N", True, self.textColor)
self.surface.blit( text, ( (self.size[0]//2) - (text.get_width()//2), int(self.size[1]/100*10) - text.get_height()//2 ) )
text = self.font.render("W", True, self.textColor)
self.surface.blit( text, ( int(self.size[0]/100*10) - (text.get_width()//2), (self.size[1]//2) - (text.get_height()//2) ) )
text = self.font.render("O", True, self.textColor)
self.surface.blit( text, ( int(self.size[0]/100*90)- (text.get_width()//2), (self.size[1]//2) - (text.get_height()//2) ) )
text = self.font.render("S", True, self.textColor)
self.surface.blit( text, ( (self.size[0]//2) - (text.get_width()//2), int(self.size[1]/100*90) - text.get_height()//2 ) )
class OuterNeedle(Compass):
def update(self, value):
radius = min(self.size[0]//2, self.size[1]//2)
pygame.draw.circle( self.surface, self.backgroundColor, (self.size[0]//2, self.size[1]//2), radius)
if self.backgroundSurface:
self.surface.blit( self.backgroundSurface, (0,0) )
if self.lineLength is None:
self.lineLength = 5
# 0 is down -> +90
# alpha = 2 * arcsin (s / 2r); s is bottom line
alpha = 2 * math.asin( self.lineLength / (2*radius) )
value = math.radians(value) + math.pi/2 #put 0 to bottom
bottom_left = self.getPos(value +alpha/2, radius)
bottom_left = ( int(bottom_left[0] + radius), bottom_left[1]+radius) #offset to screen middle
bottom_right = self.getPos(value -alpha/2, radius)
bottom_right = ( int(bottom_right[0] + radius), bottom_right[1]+radius)
height_of_segment = self.lineLength/2 * math.tan( alpha / 4 )
height_of_triangle = math.sqrt(3) /2 * self.lineLength
top = self.getPos(value, radius-height_of_segment-height_of_triangle)
top = ( int(top[0] + radius), top[1]+radius )
points = [ bottom_left, top, bottom_right ]
pygame.draw.lines( self.surface, self.needleColor, False, points,3)
text = self.font.render("N", True, self.textColor)
self.surface.blit( text, ( (self.size[0]//2) - (text.get_width()//2), int(self.size[1]/100*10) - text.get_height()//2 ) )
text = self.font.render("W", True, self.textColor)
self.surface.blit( text, ( int(self.size[0]/100*10) - (text.get_width()//2), (self.size[1]//2) - (text.get_height()//2) ) )
text = self.font.render("O", True, self.textColor)
self.surface.blit( text, ( int(self.size[0]/100*90)- (text.get_width()//2), (self.size[1]//2) - (text.get_height()//2) ) )
text = self.font.render("S", True, self.textColor)
self.surface.blit( text, ( (self.size[0]//2) - (text.get_width()//2), int(self.size[1]/100*90) - text.get_height()//2 ) )
def getPos(self, alpha, radius):
return ( int( radius * math.cos(alpha) ), int( radius * math.sin(alpha) ) )
def setLineLength(self, length):
self.lineLength = length
def setBackgroundSurface(self, surface):
self.backgroundSurface = surface