"""a handful of utility functions used by GlitterPOS.""" import math import time # https://gist.githubusercontent.com/jeromer/2005586/raw/5456a9386acce189ac6cc416c42e9c4b560a633b/compassbearing.py def compass_bearing(pointA, pointB): """ Calculates the bearing between two points. The formulae used is the following: θ = atan2(sin(Δlong).cos(lat2), cos(lat1).sin(lat2) − sin(lat1).cos(lat2).cos(Δlong)) :Parameters: - `pointA: The tuple representing the latitude/longitude for the first point. Latitude and longitude must be in decimal degrees - `pointB: The tuple representing the latitude/longitude for the second point. Latitude and longitude must be in decimal degrees :Returns: The bearing in degrees :Returns Type: float """ if (type(pointA) != tuple) or (type(pointB) != tuple): raise TypeError("Only tuples are supported as arguments") lat1 = math.radians(pointA[0]) lat2 = math.radians(pointB[0]) diffLong = math.radians(pointB[1] - pointA[1]) x = math.sin(diffLong) * math.cos(lat2) y = math.cos(lat1) * math.sin(lat2) - (math.sin(lat1) * math.cos(lat2) * math.cos(diffLong)) initial_bearing = math.atan2(x, y) # Now we have the initial bearing but math.atan2 return values # from -180° to + 180° which is not what we want for a compass bearing # The solution is to normalize the initial bearing as shown below initial_bearing = math.degrees(initial_bearing) compass_bearing = (initial_bearing + 360) % 360 return compass_bearing def bearing_to_pixel(bearing, count=16): # Subtract from count since the neopixel ring runs counterclockwise: pixel = count - int(round((bearing / 360) * count)) if pixel == count: return 0 return pixel def map_range(x, in_min, in_max, out_min, out_max): """ Maps a number from one range to another. :return: Returns value mapped to new range :rtype: float """ mapped = (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min if out_min <= out_max: return max(min(mapped, out_max), out_min) return min(max(mapped, out_max), out_min) def timestamp(): """print a human-readable timestamp""" timestamp = time.localtime() return '{}/{}/{} {:02}:{:02}:{:02}'.format( timestamp.tm_year, timestamp.tm_mon, timestamp.tm_mday, timestamp.tm_hour, timestamp.tm_min, timestamp.tm_sec )