c2 TIP 2020
from math import sin, cos, pi, asin, sqrt | |
from tkinter import * | |
cave_w, cave_h = 128, 64 | |
fl, cv = [43, 40, 34, 28, 26, 26, 27, 26, 23, 20, 19, 20, 20, 20, 21, 24, 27, 28, 24, 19, 15, 15, 17, 18, 17, 15, 15, 16, 18, 19, 21, 25, 30, 34, 35, 31, 27, 26, 27, 30, 30, 27, 24, 23, 22, 22, 21, 21, 23, 26, 27, 24, 19, 16, 16, 19, 22, 22, 20, 19, 18, 19, 18, 17, 17, 19, 21, 20, 15, 10, 8, 10, 14, 17, 18, 17, 17, 18, 19, 18, 17, 17, 18, 18, 15, 8, 3, 2, 5, 9, 11, 11, 11, 13, 15, 17, 18, 19, 22, 24, 24, 21, 16, 13, 14, 17, 20, 21, 19, 18, 19, 19, 19, 19, 19, 20, 21, 20, 15, 10, 7, 9, 12, 13, 11, 8, 6, 5], [38, 37, 35, 33, 33, 35, 36, 35, 32, 28, 26, 25, 26, 26, 27, 29, 30, 29, 26, 22, 19, 19, 20, 20, 17, 13, 9, 8, 9, 10, 11, 14, 17, 19, 20, 19, 18, 19, 22, 26, 28, 28, 26, 25, 26, 28, 29, 30, 32, 33, 33, 30, 27, 24, 24, 27, 29, 28, 26, 23, 22, 22, 23, 23, 23, 23, 22, 20, 16, 11, 9, 10, 13, 15, 14, 13, 12, 14, 16, 19, 20, 22, 23, 23, 20, 16, 12, 12, 13, 15, 16, 14, 12, 11, 12, 14, 16, 17, 19, 20, 19, 17, 14, 12, 13, 16, 19, 19, 17, 15, 15, 16, 18, 19, 20, 21, 22, 20, 18, 15, 15, 17, 21, 22, 20, 17, 14, 13] | |
wl = [676499, 819210, 704161, 828804, 911396, 1010837, 772540, 600182, 526017, 803480, 756064, 701196, 1756736, 1376344, 1158834, 1315990, 1102792, 1323847, 1497194, 1810708, 1327018, 1094903, 1349813] | |
colors = ([0, 0, 0], [255, 255, 255], [0, 0, 255], [255, 0, 0], [159, 159, 159], [0,0,0]) | |
zint = 2 | |
zx, zy = 5.031496062992126, 7.603174603174603 | |
screen_w, screen_h = cave_w * zx + zint, cave_h * zy + zint | |
master = Tk() | |
master.resizable(0, 0) | |
index = 0 | |
path = [(0, 0, 1)] | |
autoComp = False | |
def escape(event): | |
global master | |
master.quit() | |
def add(event): | |
global path, index | |
if len(path) < 24: | |
index += 1 | |
path.append((0.0, 0.0, 0.0)) | |
aller_selon(path) | |
def remove(event): | |
global path, index | |
if len(path) > 1: | |
path = path[:-1] | |
if index > len(path) - 1: | |
index = len(path) - 1 | |
aller_selon(path) | |
def next(event): | |
global path, index | |
if index < len(path) - 1: | |
index += 1 | |
aller_selon(path) | |
def previous(event): | |
global path, index | |
if index > 0: | |
index -= 1 | |
aller_selon(path) | |
def left(event, step): | |
global path, index | |
path[index] = (round(path[index][0] + step, 2), path[index][1], path[index][2]) | |
aller_selon(path) | |
def right(event, step): | |
global path, index | |
path[index] = (round(path[index][0] - step, 2), path[index][1], path[index][2]) | |
aller_selon(path) | |
def secondUp(event, step): | |
global path, index | |
path[index] = (path[index][0], round(path[index][1] + step, 2), path[index][2]) | |
aller_selon(path) | |
def secondDown(event, step): | |
global path, index | |
path[index] = (path[index][0], round(path[index][1] - step, 2), path[index][2]) | |
aller_selon(path) | |
def thirdUp(event, step): | |
global path, index | |
path[index] = (path[index][0], path[index][1], round(path[index][2] + step, 2)) | |
aller_selon(path) | |
def thirdDown(event, step): | |
global path, index | |
path[index] = (path[index][0], path[index][1], round(path[index][2] - step, 2)) | |
aller_selon(path) | |
def print_code(event): | |
global path | |
print('') | |
print('path = %s' % path) | |
print('') | |
print('def plan():') | |
for i in range(len(path)): | |
print(' modifier_vol{}'.format(path[i])) | |
print('') | |
def changeAutoComp(event): | |
global autoComp | |
autoComp= not autoComp | |
aller_selon(path) | |
master.bind('<Escape>', escape) | |
master.bind('<Return>', add) | |
master.bind('<BackSpace>', remove) | |
master.bind('<Control-Left>', previous) | |
master.bind('<Control-Right>', next) | |
master.bind('<Left>', lambda e: left(e, 0.1)) | |
master.bind('<Right>', lambda e: right(e, 0.1)) | |
master.bind('<Shift-Left>', lambda e: left(e, 0.01)) | |
master.bind('<Shift-Right>', lambda e: right(e, 0.01)) | |
master.bind('z', lambda e: thirdUp(e, 1)) | |
master.bind('s', lambda e: thirdDown(e, 1)) | |
master.bind('<Shift-KeyPress-Z>', lambda e: thirdUp(e, 0.1)) | |
master.bind('<Shift-KeyPress-S>', lambda e: thirdDown(e, 0.1)) | |
master.bind('<Up>', lambda e: secondUp(e, 0.1)) | |
master.bind('<Down>', lambda e: secondDown(e, 0.1)) | |
master.bind('<Shift-Up>', lambda e: secondUp(e, 0.01)) | |
master.bind('<Shift-Down>', lambda e: secondDown(e, 0.01)) | |
master.bind('c', changeAutoComp) | |
master.bind('p', print_code) | |
master.bind('P', print_code) | |
canvas = Canvas(master, width = screen_w, height = screen_h + 100, bg = 'white') | |
canvas.pack() | |
def _from_rgb(rgb): | |
"""translates an rgb tuple of int to a tkinter friendly color code | |
""" | |
return "#%02x%02x%02x" % tuple(rgb) | |
def clean_screen(): | |
global canvas | |
canvas.delete('all') | |
def draw_rect(x, y, w, h, color): | |
global canvas | |
x += 1 | |
y += 1 | |
canvas.create_rectangle(x, y, x + w, y + h, fill = color, outline = '') | |
def draw_line(x1, y1, x2, y2, color): | |
global canvas | |
canvas.create_line(x1 + 1, y1 + 1, x2 + 1, y2 + 1, fill = color, width = 2.0) | |
def poly_fill_ellipse(x, y, r1, r2, c): | |
global canvas | |
canvas.create_oval(x+r1, y+r2, x-r1, y-r2, fill = _from_rgb(c), outline='') | |
# def poly_fill_ellipse(x, y, rx, ry, c): | |
# canvas.create_oval(x, y, rx, ry, fill = _from_rgb(c)) | |
# for h in range(int(-ry), int(ry+1)): | |
# w = sqrt(max(0, rx*rx*(1-h*h/ry/ry))) | |
# x1, x2 = x - w, x + w | |
# yc = y + h | |
# draw_line(x1, yc, x2, yc, _from_rgb(c)) | |
def draw_help(): | |
global canvas | |
help1 = 'change angle: [Shift+]Left/Right, change circle size: [Shift+]Up/Down, change lenght: [Shift+]a/z, disable/enable auto-' | |
help2 = 'completion: c, add/remove element: Enter/BackSpace, previous/next element: Ctrl+Left/Right, print code: P, exit: Esc' | |
canvas.create_text(4, screen_h + 52, anchor = NW, text = help1, fill = 'black') | |
canvas.create_text(4, screen_h + 68, anchor = NW, text = help2, fill = 'black') | |
def draw_path(): | |
global canvas, path | |
for i in range(len(path)): | |
if i == index: | |
color = 'red' | |
else: | |
color = 'blue' | |
if i < 6: | |
y = 0 | |
elif (i>=6 and i<12): | |
y = 16 | |
else: | |
y = 32 | |
canvas.create_text(4 + (i % 6) * 98, screen_h + 8 + y, anchor = NW, text = '(%5.2f, %5.2f, %5.2f)' % path[i], fill = color) | |
def draw_score(state): | |
global canvas | |
canvas.create_text(4, screen_h + 84, anchor = NW, text = 'score: %7.1f (state[0]: %3.1f, state[1]: %3.1f, state[2]: %3.1f, collisions: %2.0f)' % (state[4], state[0], state[1], state[2], state[5]), fill = 'black') | |
def rxy(a): | |
if a%2 == 1: | |
rx, ry = 0, 1-2*(a%4 == 3) | |
else: | |
a = fix_angle(a * pi/2) | |
rx, ry = abs(cos(a)), abs(sin(a)) | |
return 1 + abs(rx), 1 + abs(ry) | |
def interpol1(yi, yf, dx): | |
return yi + dx*(yf - yi) | |
def interpol_list(lst, i): | |
i0 = int(i) | |
v = lst[i0] | |
if i > i0 and i < len(lst) - 1: | |
v = interpol1(v, lst[i0 + 1], i - i0) | |
return v | |
def fix_angle(a): | |
return a * 2 * asin(1) / pi | |
def test_collision(x, y): | |
f = cave_h - interpol_list(fl, x) | |
return y >= f or y <= f-interpol_list(cv, x) | |
def test_collision_rect(x, y, dx, dy): | |
x1, x2, y1, y2 = max(0, x - dx), min(cave_w - 1, x + dx), y - dy, y + dy | |
return test_collision(x1, y1) + test_collision(x2, y1) + test_collision(x1, y2) + test_collision(x2, y2) | |
def test_balloon(x, y, rx, ry, d_vert): | |
rmax, r2, k, collisions = [rx, ry][d_vert], [ry, rx][d_vert], -1, 0 | |
while k < rmax: | |
k = min(k + 1, rmax) | |
k2 = sqrt(max(0, r2*r2*(1 - k*k/rmax/rmax))) | |
collisions += test_collision_rect(x, y, [k, k2][d_vert], [k2, k][d_vert]) | |
return collisions | |
def cout(x): | |
n, c = 5, 1 | |
x = round(abs(x) * 10**n) | |
if x: | |
c = max(n + 1 - len(str(x)), 0) | |
while n and not (x % 10): | |
x = x // 10 | |
n -= 1 | |
c += not n | |
return 1 + len(str(x)) + c | |
def modifier_vol(ay, da, dt, color=0): | |
global state | |
if ay or da: | |
state[4] += 10 | |
x, y, a = state[0:3] | |
while state[0] < cave_w - 1 and dt: | |
state[0] += 1 | |
state[2] = max(0, min(1, a + da)) | |
state[3] -= ay | |
state[1] = max(0, min(cave_h - 1, state[1] + state[3])) | |
dt = max(0, dt - 1) | |
da, dapi, dx = abs(state[2] - a), abs(state[2] - .5), 1 | |
state[4] += 3*(da > 0)*(1 + da) + 2*(dapi > 0)*(1 + dapi) | |
xc, yc, dx = x, y, 1 | |
rx, ry = rxy(state[2]) | |
if state[1] != y: | |
dx = min(1 / abs(state[1] - y), 1) | |
collisions = test_balloon(state[0], state[1], rx, ry, 0) + test_balloon(state[0], state[1], rx, ry, 1) | |
if collisions: | |
state[4] += 7 * (1 + collisions) | |
state[5] += collisions | |
while xc < state[0]: | |
xc += dx/zx | |
yc = interpol1(y, state[1], xc - x) | |
rx, ry = rxy(interpol1(a, state[2], state[2] - a)) | |
poly_fill_ellipse(xc * zx, yc * zy, rx * zx, ry * zy, colors[2*1+ color + (collisions > 0)]) | |
x, y, a = state[0], state[1], state[2] | |
def aller_selon(path): | |
global state, fl, cv, autoComp | |
state = [0, 12, .5, 0, 0, 0] | |
clean_screen() | |
draw_rect(0, 0, screen_w, screen_h, _from_rgb(colors[4])) | |
for x in range(cave_w): | |
f1, dx = cave_h - fl[x], 0 | |
c1 = f1 - cv[x] | |
while dx < zx: | |
f2 = cave_h - interpol_list(fl, x + dx/zx) | |
c2 = f2 - interpol_list(cv, x + dx/zx) | |
draw_line(x*zx + dx, c2 * zy, x*zx + dx, f2 * zy, _from_rgb(colors[1])) | |
dx += 1 | |
# if poly_has_color: | |
draw_line(x * zx, c1 * zy, (x + 1) * zx, c2 * zy, _from_rgb(colors[0])) | |
draw_line(x * zx, f1 * zy, (x + 1) * zx, f2 * zy, _from_rgb(colors[0])) | |
for i in range(len(path)): | |
if i == index: | |
color = 2 | |
else: | |
color = 0 | |
modifier_vol(path[i][0], path[i][1], path[i][2], color) | |
# tourner(path[i][0]) | |
# if i == index: | |
# color = 'red' | |
# else: | |
# color = 'blue' | |
# avancer(path[i][1], color) | |
# state[5] += sin(fix_angle(state[7])) - state[6] // 2 | |
if (state[0] < cave_w - 1) and autoComp : | |
modifier_vol(0, 0, cave_w - 1 - state[0]) | |
draw_help() | |
draw_path() | |
draw_score(state) | |
aller_selon(path) | |
master.mainloop() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment