如何用pygame绘制虚线曲线? [英] How to draw a dashed curved line with pygame?

查看:55
本文介绍了如何用pygame绘制虚线曲线?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要在与

导入pygame导入数学def draw_dashed_line(surf, color, p1, p2, prev_line_len, dash_length=8):dx, dy = p2[0]-p1[0], p2[1]-p1[1]如果 dx == 0 且 dy == 0:返回dist = math.hypot(dx, dy)dx/= 距离dy/= dist步长 = dash_length*2start = (int(prev_line_len)//步) * 步end = (int(prev_line_len + dist)//step + 1) * step对于范围内的 i(开始,结束,dash_length*2):s = max(0, start - prev_line_len)e = min(start - prev_line_len + dash_length, dist)如果 s <电子:ps = p1[0] + dx * s, p1[1] + dy * spe = p1[0] + dx * e, p1[1] + dy * epygame.draw.line(冲浪,颜色,pe,ps)def draw_dashed_lines(surf, color, points, dash_length=8):line_len = 0对于范围内的 i (1, len(points)):p1, p2 = 点[i-1], 点[i]dist = math.hypot(p2[0]-p1[0],p2[1]-p1[1])draw_dashed_line(冲浪,颜色,p1,p2,line_len,dash_length)line_len += distpygame.init()屏幕 = pygame.display.set_mode((400, 300))完成 = 错误line = [(i, 150 + math.sin(math.radians(i*2)) * 100) for i in range(400)]虽然没有完成:对于 pygame.event.get() 中的事件:如果 event.type == pygame.QUIT:完成 = 真draw_dashed_lines(屏幕,(255, 255, 255),线)pygame.display.flip()

I need to draw sine and cosine waves on a coordinate system exactly like in this picture. I did all the work well except I failed to represent dashed and curved line with pygame. I have smth similar to what I need, but how can I make it curved? Or how can I improve this to make it like pygame.draw.lines, not 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()

解决方案

Write a function that operates similar as pygame.draw.line() but draws a dashed straight line. The function has an additional argument prev_line_len which indicates where the line segment is within a consecutive curve. Compute the Euclidean distance between the points and the Unit vector that points from the beginning of the line segment to its end. Distribute the strokes along the line:

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

Write another function that behaves similarly to pygame.draw.lines(), but uses the former function (draw_dashed_line) to draw the dashed curve. Calculate the length from the beginning of the curve to the beginning of each line segment and pass it to the 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


Minimal example:

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

这篇关于如何用pygame绘制虚线曲线?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆