簡體   English   中英

如何用 pygame 繪制虛曲線?

[英]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

最小的例子:

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()

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM