如何在 Pygame 中制作更厚的贝塞尔曲线?

How Can I Make a Thicker Bezier in Pygame?

我正在 Pygame 中构建一个专门的节点编辑器。每个节点将与贝塞尔曲线连接。这条曲线是通过先点击一个节点来构建的。在鼠标光标和节点之间绘制贝塞尔曲线,单击第二个节点后,贝塞尔曲线固定。我的代码已经可以绘制曲线并跟随鼠标光标。我的问题是曲线太细了。有谁知道在 pygame.gfxdraw.bezier 中轻松指定宽度的方法?另外,我不知道参数“6”对应的是什么;我只知道没有它代码将无法运行。

# This draws the bezier curve for the node editor
x, y = pygame.mouse.get_pos()
b_points = [(380,390),(410,385),(425,405), (425, y), (x, y)]
pygame.gfxdraw.bezier(screen, b_points, 6, blue)

简单的回答:你不能,至少不能 pygame.gfxdrawpygame.draw。你必须自己做。 计算沿曲线的点并将它们连接到 pygame.draw.lines.

参见 Finding a Point on a Bézier Curve: De Casteljau's Algorithm 并创建一个按点绘制贝塞尔曲线点的函数:

import pygame

def ptOnCurve(b, t):
    q = b.copy()
    for k in range(1, len(b)):
        for i in range(len(b) - k):
            q[i] = (1-t) * q[i][0] + t * q[i+1][0], (1-t) * q[i][1] + t * q[i+1][1]
    return round(q[0][0]), round(q[0][1])

def bezir(surf, b, samples, color, thickness):
    pts = [ptOnCurve(b, i/samples) for i in range(samples+1)]
    pygame.draw.lines(surf, color, False, pts, thickness)

最小示例:

import pygame, pygame.gfxdraw

def ptOnCurve(b, t):
    q = b.copy()
    for k in range(1, len(b)):
        for i in range(len(b) - k):
            q[i] = (1-t) * q[i][0] + t * q[i+1][0], (1-t) * q[i][1] + t * q[i+1][1]
    return round(q[0][0]), round(q[0][1])

def bezir(surf, b, samples, color, thickness):
    pts = [ptOnCurve(b, i/samples) for i in range(samples+1)]
    pygame.draw.lines(surf, color, False, pts, thickness)

pygame.init()
screen = pygame.display.set_mode((800, 600))
clock = pygame.time.Clock()
run = True
while run:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False 

    x, y = pygame.mouse.get_pos()
    b_points = [(380,390), (410,385), (425,405), (425, y), (x, y)]

    screen.fill(0)
    bezir(screen, b_points, 20, (255, 255, 0), 6)
    pygame.draw.lines(screen, (255, 255, 255), False, b_points, 1)
    pygame.gfxdraw.bezier(screen, b_points, 6, (255, 0, 0))
    pygame.display.flip()
    clock.tick(60)

pygame.quit()