编写一个操作类似的函数pygame.draw.line() http://www.pygame.org/docs/ref/draw.html#pygame.draw.lines但画一条虚直线。该函数有一个附加参数prev_line_len
它指示线段在连续曲线内的位置。计算欧氏距离 https://en.wikipedia.org/wiki/Euclidean_distance点与点之间单位向量 https://en.wikipedia.org/wiki/Unit_vector从线段的起点指向线段的终点。沿线分布笔画:
def draw_dashed_line(surf, color, p1, p2, prev_line_len, dash_length=8):
dx, dy = p2[0]-p1[0], p2[1]-p1[1]
if dx == 0 and dy == 0:
return
dist = math.hypot(dx, dy)
dx /= dist
dy /= dist
step = dash_length*2
start = (int(prev_line_len) // step) * step
end = (int(prev_line_len + dist) // step + 1) * step
for i in range(start, end, dash_length*2):
s = max(0, start - prev_line_len)
e = min(start - prev_line_len + dash_length, dist)
if s < e:
ps = p1[0] + dx * s, p1[1] + dy * s
pe = p1[0] + dx * e, p1[1] + dy * e
pygame.draw.line(surf, color, pe, ps
编写另一个功能类似于pygame.draw.lines() https://www.pygame.org/docs/ref/draw.html#pygame.draw.lines,但使用前一个函数(draw_dashed_line
) 绘制虚线。计算从曲线起点到每条线段起点的长度并将其传递给函数:
def draw_dashed_lines(surf, color, points, dash_length=8):
line_len = 0
for i in range(1, len(points)):
p1, p2 = points[i-1], points[i]
dist = math.hypot(p2[0]-p1[0], p2[1]-p1[1])
draw_dashed_line(surf, color, p1, p2, line_len, dash_length)
line_len += dist
最小的例子:
repl.it/@Rabbid76/DashedLine
import pygame
import math
def draw_dashed_line(surf, color, p1, p2, prev_line_len, dash_length=8):
dx, dy = p2[0]-p1[0], p2[1]-p1[1]
if dx == 0 and dy == 0:
return
dist = math.hypot(dx, dy)
dx /= dist
dy /= dist
step = dash_length*2
start = (int(prev_line_len) // step) * step
end = (int(prev_line_len + dist) // step + 1) * step
for i in range(start, end, dash_length*2):
s = max(0, start - prev_line_len)
e = min(start - prev_line_len + dash_length, dist)
if s < e:
ps = p1[0] + dx * s, p1[1] + dy * s
pe = p1[0] + dx * e, p1[1] + dy * e
pygame.draw.line(surf, color, pe, ps)
def draw_dashed_lines(surf, color, points, dash_length=8):
line_len = 0
for i in range(1, len(points)):
p1, p2 = points[i-1], points[i]
dist = math.hypot(p2[0]-p1[0], p2[1]-p1[1])
draw_dashed_line(surf, color, p1, p2, line_len, dash_length)
line_len += dist
pygame.init()
screen = pygame.display.set_mode((400, 300))
done = False
line = [(i, 150 + math.sin(math.radians(i*2)) * 100) for i in range(400)]
while not done:
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
draw_dashed_lines(screen, (255, 255, 255), line)
pygame.display.flip()