Прикреплённый файл «lines-antialias.py»
Загрузка 1 #!/usr/bin
2 # coding: UTF8
3 '''
4 Нарисовать отрезок от (x1,y1) до (x2,y2) толщиной в P точек
5 с учётом антиалиасинга (частичного перекрашивания точек,
6 заметаемых отрезком не полностью).
7 '''
8 from math import *
9 import pygame, sys
10
11 pygame.init()
12 scale=1 # размер точки
13 screen=pygame.display.set_mode((1024,768))
14
15 def dot(coord, color):
16 "Нарисовать точку"
17 r=pygame.Rect(coord[0]*scale,coord[1]*scale,scale,scale)
18 r=r.clip(screen.get_rect())
19 screen.fill(color, (coord[0]*scale,coord[1]*scale,scale,scale))
20
21 def mixdot(coord, color, opacity):
22 "Нарисовать полупрозрачную точку"
23 if not pygame.Rect(coord[0]*scale,coord[1]*scale,1,1).clip(screen.get_rect()):
24 return
25 back = screen.get_at((int(coord[0]*scale),int(coord[1]*scale)))
26 fore = [a*(1-opacity)+b*opacity for a,b in zip(back,color)]
27 dot(coord,fore)
28
29 def dist(A,B):
30 "Расстояние от точки A до точки B"
31 return sqrt((B[0]-A[0])**2+(B[1]-A[1])**2)
32
33 def ldist(M,A,B):
34 "Расстояние от точки M до прямой AB"
35 return ((A[1]-B[1])*M[0]+(B[0]-A[0])*M[1]+(A[0]*B[1]-B[0]*A[1]))/dist(A,B)
36
37 def l8(A,B,W,color):
38 "Построение отрезка в первом квадранте, без проверок"
39 X=A[0]-W/2.
40 for y in xrange(A[1],B[1]+1):
41 x=X
42 while True:
43 d=ldist((x,y),A,B)
44 if d>W/2.+0.5:
45 X+=1
46 elif d<-W/2.-0.5:
47 break
48 elif abs(d)>W/2.-0.5:
49 mixdot((x,y),color,W/2.+0.5-abs(d))
50 else:
51 dot((x,y),color)
52 x+=1
53 pygame.display.flip()
54
55 def line(A,B,W,color):
56 "Построение отрезка AB шириной W"
57 if A == B: return
58 if A[1]>B[1]: A,B=B,A # переводим шаг по Y в положительный"
59 L=dist(A,B)
60 # Прямоугольник
61 A0=(A[0]-(B[1]-A[1])*W/(2*L),A[1]+(B[0]-A[0])*W/(2*L))
62 A1=(A[0]+(B[1]-A[1])*W/(2*L),A[1]-(B[0]-A[0])*W/(2*L))
63 B0=(B[0]-(B[1]-A[1])*W/(2*L),B[1]+(B[0]-A[0])*W/(2*L))
64 B1=(B[0]+(B[1]-A[1])*W/(2*L),B[1]-(B[0]-A[0])*W/(2*L))
65 dx=A[0]>B[0] and -1 or 1 # Шаг по X
66 X=dx>0 and min(A0[0],A1[0]) or max(A0[0],A1[0]) # верхний угол
67 for y in dx>0 and xrange(int(A1[1]),int(B0[1]+1)) or xrange(int(A0[1]),int(B1[1]+1)):
68 x=X
69 while True:
70 d=ldist((x,y),A,B)
71 if d*dx>W/2.+0.5: # слишком рано начали сканировать точки
72 X+=dx # в следующий раз начнём попозже
73 x=X
74 continue
75 elif d*dx<-W/2.-0.5: # вышли за границу прямоугольника
76 break
77 elif ldist((x,y),A0,A1)>=0: # точка после начала прямоугольника
78 if ldist((x,y),B1,B0)>0: # точка перед окончанием прямоугольника
79 if abs(d)>W/2.-0.5: # точка на границе
80 mixdot((x,y),color,W/2.+0.5-abs(d))
81 else:
82 dot((x,y),color)
83 else: # точка после окончания прямоугольника
84 break # сканирование не требуется
85 x+=dx
86 if scale > 1: # Отладочная тонкая линия
87 pygame.draw.circle(screen,pygame.Color("red"),(int(scale*A0[0]),int(scale*A0[1])),2)
88 pygame.draw.lines(screen,pygame.Color("red"),False,[(scale*x,scale*y) for x,y in (A0,B0,B1,A1)])
89
90 scale=16
91 col=pygame.Color("yellowgreen")
92
93 while True:
94 event = pygame.event.wait()
95 if event.type == pygame.QUIT: sys.exit()
96 elif event.type == pygame.MOUSEMOTION:
97 if event.buttons[0]:
98 screen.blit(S,(0,0))
99 line(M,(event.pos[0]/scale,event.pos[1]/scale),3,col)
100 elif event.type == pygame.MOUSEBUTTONDOWN:
101 if event.button == 1:
102 S=screen.copy() # картинка без линии
103 M=(event.pos[0]/scale,event.pos[1]/scale)
104 pygame.display.flip()
Прикреплённые файлы
Для ссылки на прикреплённый файл в тексте страницы напишите attachment:имяфайла, как показано ниже в списке файлов. Не используйте URL из ссылки «[получить]», так как он чисто внутренний и может измениться.- [получить | показать] (2011-09-26 11:35:16, 0.3 KB) [[attachment:Sav_1_cercled_h(~500).py]]
- [получить | показать] (2011-09-26 11:35:16, 0.5 KB) [[attachment:Sav_2_graphfn(simple, different functions).py]]
- [получить | показать] (2011-09-26 11:35:16, 0.6 KB) [[attachment:circledot_factorials.py]]
- [получить | показать] (2011-09-26 11:35:16, 22.8 KB) [[attachment:lines-antialias.png]]
- [получить | показать] (2011-09-26 11:35:16, 4.3 KB) [[attachment:lines-antialias.py]]
- [получить | показать] (2011-09-26 11:35:16, 2.0 KB) [[attachment:lines-antialias.seg]]
- [получить | показать] (2011-09-26 11:35:16, 44.0 KB) [[attachment:lines-antialias2.png]]
- [получить | показать] (2011-09-26 11:35:16, 2.6 KB) [[attachment:lines-antialias2.seg]]
- [получить | показать] (2011-09-26 11:35:16, 15.1 KB) [[attachment:lines8.png]]
- [получить | показать] (2011-09-26 11:35:16, 1.9 KB) [[attachment:lines8.seg]]
Вам нельзя прикреплять файлы к этой странице.