[英]How to draw a dashed curved line with pygame?
我需要在坐標系上繪制正弦波和余弦波,就像在這張圖片中一樣。 除了沒有用 pygame 表示虛線和曲線外,我所有的工作都做得很好。 我有類似於我需要的東西,但我怎樣才能讓它彎曲呢? 或者我該如何改進它以使其像pygame.draw.lines ,而不是pygame.draw.line ?
import pygame
import math
class Point:
# constructed using a normal tupple
def __init__(self, point_t = (0,0)):
self.x = float(point_t[0])
self.y = float(point_t[1])
# define all useful operators
def __add__(self, other):
return Point((self.x + other.x, self.y + other.y))
def __sub__(self, other):
return Point((self.x - other.x, self.y - other.y))
def __mul__(self, scalar):
return Point((self.x*scalar, self.y*scalar))
def __div__(self, scalar):
return Point((self.x/scalar, self.y/scalar))
def __len__(self):
return int(math.sqrt(self.x**2 + self.y**2))
# get back values in original tuple format
def get(self):
return (self.x, self.y)
def draw_dashed_line(surf, color, start_pos, end_pos, width=1, dash_length=4):
origin = Point(start_pos)
target = Point(end_pos)
displacement = target - origin
length = len(displacement)
slope = displacement.__div__(length)
for index in range(0, int(length/dash_length), 2):
start = origin + (slope * index * dash_length)
end = origin + (slope * (index + 1) * dash_length)
pygame.draw.line(surf, color, start.get(), end.get(), width)
pygame.init()
screen = pygame.display.set_mode((400, 300))
done = False
while not done:
draw_dashed_line(screen,(0,255,0),(0,0),(110,110))
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
pygame.display.flip()
編寫一個 function ,其操作類似於pygame.draw.line()
但繪制一條虛線。 function 有一個附加參數prev_line_len
,它指示線段在連續曲線中的位置。 計算點與從線段起點到終點的單位向量之間的歐幾里得距離。 沿線分布筆畫:
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
編寫另一個 function,其行為類似於pygame.draw.lines()
,但使用前 function 虛線draw_dashed_line
繪制虛線計算曲線起點到每條線段起點的長度,傳給function:
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
最小的例子:
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()
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.