Created
May 20, 2012 06:57
-
-
Save ZhanruiLiang/2757075 to your computer and use it in GitHub Desktop.
A set of python scripts to show the animation of the problem POJ1070: Deformed Wheel.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import pygame as pg | |
import sys | |
from pygame.locals import * | |
import subprocess as sb | |
W, H = 800, 600 | |
x0, y0 = 400, 400 | |
BgColor = (0xff, 0xff, 0xff, 0xff) | |
LineColor = (0, 0, 0, 0xff) | |
SCROLL_UP, SCROLL_DOWN = 4, 5 | |
k = 3. | |
inputfile='map-poj1070-0002' | |
def onexit(): | |
proc.kill() | |
sys.exitfunc = onexit | |
def init(): | |
global screen, proc, font | |
pg.display.init() | |
pg.font.init() | |
screen = pg.display.set_mode((W, H), 0, 32) | |
proc = sb.Popen(['./a', inputfile], stdout=sb.PIPE, stderr=sb.PIPE, stdin=sb.PIPE) | |
font = pg.font.SysFont('monospace', 16) | |
lines = [] | |
data = [] | |
def fetch(): | |
global waiting | |
while 1: | |
line = proc.stdout.readline() | |
if not line: | |
# eof | |
return | |
line = line.rstrip() | |
if line.startswith(':'): | |
line = line[1:] | |
if line == 'stroke': | |
waiting = 1 | |
return | |
lines.append(line) | |
else: | |
print 'client: ', line | |
def send(): | |
try: | |
proc.stdin.write(':\n') | |
proc.stdin.flush() | |
except IOError as e: | |
sys.stderr.write(proc.stderr.read()) | |
print e | |
def tfp((x, y)): | |
return (int(k*x + x0), int(-y*k + y0)) | |
def rtfp((x, y)): | |
return ((x - x0 - 0.)/k, (-y + y0 - 0.)/k) | |
def transform(ps): | |
return [tfp((x, y)) for x, y in ps] | |
cnt = 0 | |
def draw(): | |
global cnt, data, lines | |
cnt += 1 | |
print 'draw', cnt | |
data = lines | |
lines = [] | |
redraw() | |
def redraw(): | |
global data | |
if not data: return | |
databk = data[:] | |
n = int(data.pop(0)) | |
ps = transform([map(float, data.pop(0).split()) for i in xrange(n)]) | |
g = tfp(map(float, data.pop(0).split())) | |
m = int(data.pop(0)) | |
ps1 = transform([map(float, data.pop(0).split()) for i in xrange(m)]) | |
screen.fill(BgColor) | |
pg.draw.polygon(screen, LineColor, ps, 1) | |
for i, p in enumerate(ps): | |
pg.draw.circle(screen, (255*i/n, 0, 0, 0xff), p, 4) | |
pg.draw.lines(screen, LineColor, 0, ps1, 1) | |
pg.draw.circle(screen, (0, 0, 0xff, 0xff), g, 4) | |
# draw the coordinate | |
pg.draw.circle(screen, (0, 0xff, 0, 0xff), tfp((0, 0)), 4) | |
screen.blit(txt, (0, 0)) | |
pg.display.flip() | |
data = databk | |
init() | |
waiting = 0 | |
pg.key.set_repeat(500, 50) | |
txt = pg.Surface((1, 1)) | |
mpos = None | |
dx, dy = 0, 0 | |
while 1: | |
for e in pg.event.get(): | |
if e.type == QUIT: | |
exit(0) | |
if e.type == KEYDOWN: | |
if e.key == K_RETURN: | |
if waiting: | |
send() | |
waiting = 0 | |
else: | |
print 'not waiting, ignored' | |
elif e.key == K_SPACE: | |
k = 3 | |
x0 = 400 | |
y0 = 400 | |
redraw() | |
if e.key == K_q: | |
exit(0) | |
if e.type == MOUSEBUTTONDOWN: | |
if e.button in (SCROLL_UP, SCROLL_DOWN): | |
x, y = rtfp(e.pos) | |
dk = 0.1 | |
if e.button == SCROLL_UP: | |
k *= (1+dk) | |
if e.button == SCROLL_DOWN: | |
k /= (1+dk) | |
x0 = e.pos[0] - k * x | |
y0 = e.pos[1] + k * y | |
redraw() | |
if e.button == 1: | |
txt = font.render("(%.1f, %.1f)" % rtfp(e.pos), 1, (0, 0, 0, 0xff), BgColor) | |
redraw() | |
elif e.type == MOUSEMOTION: | |
if e.buttons[0]: | |
dx += e.rel[0] | |
dy += e.rel[1] | |
if dx*dx+dy*dy > 40: | |
x0, y0 = x0 + dx, y0 + dy | |
dx, dy = 0, 0 | |
redraw() | |
if not waiting: | |
fetch() | |
if lines: | |
draw() | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import pygame as pg | |
import sys, os | |
from pygame.locals import * | |
import subprocess as sb | |
W, H = 1200, 800 | |
x0, y0 = 400, 400 | |
BgColor = (0xff, 0xff, 0xff, 0xff) | |
LineColor = (0, 0, 0, 0xff) | |
SCROLL_UP, SCROLL_DOWN = 4, 5 | |
k = 3. | |
poly = [] | |
gra = None | |
hill = [] | |
pbuf = [] | |
def init(): | |
global screen, proc, font | |
pg.display.init() | |
pg.font.init() | |
screen = pg.display.set_mode((W, H), 0, 32) | |
font = pg.font.SysFont('monospace', 12) | |
def tfp((x, y)): | |
return (int(k*x + x0), int(-y*k + y0)) | |
def rtfp((x, y)): | |
return ((x - x0 - 0.)/k, (-y + y0 - 0.)/k) | |
def transform(ps): | |
return [tfp((x, y)) for x, y in ps] | |
def inform(msg): | |
h = 0 | |
txt.fill((0, 0, 0, 0)) | |
for line in msg.split('\n'): | |
txtline = font.render(line, 1, LineColor) | |
txt.blit(txtline, (5, h)) | |
h += font.size(line)[1] | |
redraw() | |
print msg | |
def add_point(p): | |
pbuf.append(p) | |
inform("add point at (%.2f, %.2f)" % p) | |
def collect_poly(): | |
while len(pbuf) > 1: | |
poly.append(pbuf.pop(0)) | |
global gra | |
gra = pbuf.pop(0) | |
inform("polygon collected\ngravity center collected\n") | |
def collect_hill(): | |
while len(pbuf): | |
hill.append(pbuf.pop(0)) | |
def dist(a, b): | |
return ((a[0] - b[0])**2 + (a[1] - b[1])**2)**0.5 | |
def collect_save(): | |
prefix = 'map-poj1070-%04d' | |
for i in xrange(1000): | |
fn = prefix % i | |
if not os.path.exists(fn): | |
pg.image.save(screen, fn + '.png') | |
with open(fn, 'w') as fout: | |
print >> fout, 1 | |
print >> fout, len(poly) | |
print >> fout, '\n'.join('%.2f %.2f' % p for p in poly) | |
print >> fout, '%.2f %.2f' % gra | |
endp = None | |
for p in poly: | |
if endp is None or dist(endp, hill[0]) > dist(p, hill[0]): | |
endp = p | |
hill[0] = endp | |
x0, y0 = endp | |
for x, y in hill[1:]: | |
k = (y - y0)/(x - x0 - 0.) | |
if k < -1e-8: | |
print 'WARNING: DATA INVALID. k = %s => k = 0, expected k >= 0' % (k,) | |
k = 0 | |
l = ((y-y0)**2+(x-x0)**2)**0.5 | |
print >> fout, '%.2f %.2f' % (l, k) | |
x0, y0 = x, y | |
print >> fout, '%.2f %.2f' % endp | |
inform("saved as %s and %s.png" % (fn, fn)) | |
break | |
else: | |
inform("can not save, too many files") | |
def redraw(): | |
screen.fill(BgColor) | |
for p in pbuf: | |
pg.draw.circle(screen, (0xff, 0, 0, 0xff), tfp(p), 3) | |
if poly: | |
# draw poly | |
pg.draw.polygon(screen, LineColor, transform(poly), 1) | |
pg.draw.circle(screen, (0, 0, 0xff, 0xff), tfp(gra), 4) | |
if hill: | |
pg.draw.lines(screen, LineColor, 0, transform(hill), 1) | |
pg.draw.circle(screen, (0, 0xff, 0, 0xff), tfp((0, 0)), 4) | |
pg.draw.circle(screen, (0, 0, 0, 0xff), tfp((100, 100)), 4) | |
screen.blit(txt, (0, 0)) | |
pg.display.flip() | |
init() | |
# pg.key.set_repeat(500, 50) | |
txt = pg.Surface((500, 300)).convert_alpha() | |
mpos = None | |
dx, dy = 0, 0 | |
helpMsg = """Welcome the the data maker of poj1070: Deformed Wheel | |
Use left mouse button to add new point | |
Use backspace to undo | |
Use mouse scroll to zoom | |
Drag with right mouse button to navigate | |
Use spacebar to reset the view | |
Use enter to goto next state, note this can not be undo | |
Press F1 to show this message | |
""" | |
inform(helpMsg) | |
collectors = [collect_poly, collect_hill, collect_save] | |
timer = pg.time.Clock() | |
while 1: | |
for e in pg.event.get(): | |
if e.type == QUIT: | |
exit(0) | |
if e.type == KEYDOWN: | |
if e.key == K_SPACE: | |
# reset view | |
k = 3 | |
x0 = 400 | |
y0 = 400 | |
redraw() | |
if e.key == K_q: | |
exit(0) | |
if e.key == K_F1: | |
inform(helpMsg) | |
if e.key == K_RETURN: | |
collector = collectors.pop(0) | |
collector() | |
if e.key == K_BACKSPACE: | |
if pbuf: | |
pbuf.pop() | |
redraw() | |
if e.type == MOUSEBUTTONDOWN: | |
if e.button in (SCROLL_UP, SCROLL_DOWN): | |
# zoom | |
x, y = rtfp(e.pos) | |
dk = 0.1 | |
if e.button == SCROLL_UP: | |
k *= (1+dk) | |
if e.button == SCROLL_DOWN: | |
k /= (1+dk) | |
x0 = e.pos[0] - k * x | |
y0 = e.pos[1] + k * y | |
redraw() | |
if e.button == 1: | |
add_point(rtfp(e.pos)) | |
redraw() | |
elif e.type == MOUSEMOTION: | |
if e.buttons[2]: | |
dx += e.rel[0] | |
dy += e.rel[1] | |
if dx*dx+dy*dy > 40: | |
x0, y0 = x0 + dx, y0 + dy | |
dx, dy = 0, 0 | |
redraw() | |
redraw() | |
timer.tick(30) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment