Skip to content

Instantly share code, notes, and snippets.

@hallundbaek
Last active December 26, 2020 18:41
Show Gist options
  • Save hallundbaek/a1aefce0f51f9f8a230512b1eb111a31 to your computer and use it in GitHub Desktop.
Save hallundbaek/a1aefce0f51f9f8a230512b1eb111a31 to your computer and use it in GitHub Desktop.
import svgwrite
import sys
import math
from cmath import rect, phase
# Takes a strings seperated by newline from stdin, sanitizes to only contain numbers 1-12,
# generates a compass for the average value this is saved as "compass.svg".
# Example usage:
# cat text.txt | python avgcompass.py
# Example compass generated: https://i.imgur.com/2m1FaAd.png
filename = 'compass.svg'
WIDTH = 1000
HEIGHT = 1000
STROKE_WIDTH = 30
DIAL_LENGTH = 60
dialColor = 'darkred'
handColor = 'green'
centerColor = 'darkgreen'
dwg = svgwrite.Drawing(filename)
dwg.viewbox(width=WIDTH, height=HEIGHT)
circle = dwg.circle(center=(WIDTH/2, HEIGHT/2), r=WIDTH/2-STROKE_WIDTH/2, fill='none',stroke=dialColor,
stroke_width=STROKE_WIDTH)
dwg.add(circle)
def x_coord(angle,radius,center_x):
angle = math.radians(angle)
x = radius * math.cos(angle) + center_x
x = round(x)
return x
def y_coord(angle,radius,center_y):
angle = math.radians(angle)
y = radius * math.sin(angle) + center_y
y = round(y)
return y
def makeLine(ang,dwg,color):
line = dwg.line(
start=(x_coord(ang,WIDTH/2-STROKE_WIDTH/2,WIDTH/2),y_coord(ang,HEIGHT/2-STROKE_WIDTH/2,HEIGHT/2)),
end=(x_coord(ang,WIDTH/2-STROKE_WIDTH-DIAL_LENGTH,WIDTH/2),y_coord(ang,HEIGHT/2-STROKE_WIDTH-DIAL_LENGTH,HEIGHT/2)),
stroke=color, stroke_width=STROKE_WIDTH)
dwg.add(line)
def makeHand(ang,dwg,color):
start = (x_coord(ang,WIDTH/2-STROKE_WIDTH/2,WIDTH/2),y_coord(ang,HEIGHT/2-STROKE_WIDTH/2,HEIGHT/2))
centerLeft = (x_coord(ang-90, STROKE_WIDTH, WIDTH/2), y_coord(ang-90, STROKE_WIDTH, HEIGHT/2))
centerRight = (x_coord(ang+90, STROKE_WIDTH, WIDTH/2), y_coord(ang+90, STROKE_WIDTH, HEIGHT/2))
poly = dwg.polygon([
start,
centerLeft,
centerRight
],
fill=color,
stroke=centerColor,
stroke_width=STROKE_WIDTH/5,
stroke_linejoin="round")
dwg.add(poly)
def isInt(s):
try:
int(s)
return True
except ValueError:
return False
def clockFilter(s):
return isInt(s) and int(s) > 0 and int(s) < 13
def sanitise(strs):
return list(map(lambda s: int(s)*30, filter(clockFilter, strs)))
def meanAngle(deg):
return math.degrees(phase(sum(rect(1, math.radians(d)) for d in deg)/len(deg)))
[makeLine(i * 30, dwg, dialColor) for i in range(0,12)]
data = sys.stdin.read().splitlines()
makeHand(meanAngle(sanitise(data)) - 90, dwg, handColor)
center = dwg.circle(center=(WIDTH/2, HEIGHT/2), r=STROKE_WIDTH*1.5, fill=centerColor)
dwg.add(center)
dwg.save()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment