为什么 Pygame 中的行进广场可视化不绘制任何内容?

问题描述 投票:0回答:1

所以我想通过使用其中的行进方块算法在pygame中绘制隐式的心方程。我实现了游行广场的算法,但它不起作用?谁能帮我解决为什么吗?

import pygame

w = 500
h = 500


grid = []
for i in range(-h//2, h//2):
    tempo = []
    for j in range(-w//2, w//2):
        tempo.append((i**2 + j**2 - 1)**3 - i**2 * j**3)
    grid.append(tempo)
    print(i)


def Bisection_Method(a, b, t, state, thresh = 0.001):
    if state:
        a -= w/2
        b -= w/2
    else:
        a -= h/2
        b -= h/2

    mid = (a + b)/2
    while abs(b - a) >= thresh:
        a1 = 0
        k1 = 0
        if state:
            i = a
            r = mid
            j = t

            a1 = (i**2 + j**2 - 1)**3 - i**2 * j**3
            k1 = (r**2 + j**2 - 1)**3 - r**2 * j**3
        else:
            i = t
            r = mid
            j = a
            a1 = (i**2 + j**2 - 1)**3 - i**2 * j**3
            k1 = (i**2 + r**2 - 1)**3 - i**2 * r**3)


        if(k1 == 0):
            return mid
        
        mid = (a + b)/2

        if(a1 * k1 < 0):
            b = mid
        else:
            a = mid
    if state:
        mid += w/2
    else:
        mid += h/2

    return mid


def MarchingSquares(i1, j1, i2, j2, i3, j3, i4, j4, plane):
    finalP1 = pygame.math.Vector2(float('inf'), float('inf'))
    finalP2 = pygame.math.Vector2(float('inf'), float('inf'))
    finalP3 = pygame.math.Vector2(float('inf'), float('inf'))
    finalP4 = pygame.math.Vector2(float('inf'), float('inf'))

    if((plane[i1][j1] < 0 and plane[i2][j2] > 0 and plane[i3][j3] > 0 and plane[i4][j4] > 0) or (plane[i1][j1] > 0 and plane[i2][j2] < 0 and plane[i3][j3] < 0 and plane[i4][j4] < 0)):
        finalP1 = pygame.math.Vector2(Bisection_Method(j1, j2, i1, True), i1)
        finalP2 = pygame.math.Vector2(j1, Bisection_Method(i1, i3, j1, False))
    elif((plane[i1][j1] > 0 and plane[i2][j2] < 0 and plane[i3][j3] > 0 and plane[i4][j4] > 0) or (plane[i1][j1] < 0 and plane[i2][j2] > 0 and plane[i3][j3] < 0 and plane[i4][j4] < 0)):
        finalP1 = pygame.math.Vector2(Bisection_Method(j1, j2, i1, True), i1)
        finalP2 = pygame.math.Vector2(j2, Bisection_Method(i4, i2, j2, False))
    elif((plane[i1][j1] > 0 and plane[i2][j2] > 0 and plane[i3][j3] < 0 and plane[i4][j4] > 0) or (plane[i1][j1] < 0 and plane[i2][j2] < 0 and plane[i3][j3] > 0 and plane[i4][j4] < 0)):
        finalP1 = pygame.math.Vector2(Bisection_Method(j3, j4, i3, True), i3)
        finalP2 = pygame.math.Vector2(j3, Bisection_Method(i1, i3, j3, False))  
    elif((plane[i1][j1] > 0 and plane[i2][j2] > 0 and plane[i3][j3] > 0 and plane[i4][j4] < 0) or (plane[i1][j1] < 0 and plane[i2][j2] < 0 and plane[i3][j3] < 0 and plane[i4][j4] > 0)):
        finalP1 = pygame.math.Vector2(Bisection_Method(j3, j4, i4, True), i4)
        finalP2 = pygame.math.Vector2(j4, Bisection_Method(i4, i2, j4, False))  
    elif((plane[i1][j1] > 0 and plane[i2][j2] > 0 and plane[i3][j3] < 0 and plane[i4][j4] < 0) or (plane[i1][j1] < 0 and plane[i2][j2] < 0 and plane[i3][j3] > 0 and plane[i4][j4] > 0)):
        finalP1 = pygame.math.Vector2(j1, Bisection_Method(i1, i3, j1, False))
        finalP2 = pygame.math.Vector2(j2, Bisection_Method(i4, i2, j2, False))
    elif((plane[i1][j1] > 0 and plane[i2][j2] > 0 and plane[i3][j3] > 0 and plane[i4][j4] < 0) or (plane[i1][j1] < 0 and plane[i2][j2] > 0 and plane[i3][j3] < 0 and plane[i4][j4] > 0)):
        finalP1 = pygame.math.Vector2(Bisection_Method(j1, j2, i1, True), i1)
        finalP2 = pygame.math.Vector2(Bisection_Method(j3, j4, i3, True), i3)
    elif((plane[i1][j1] < 0 and plane[i2][j2] > 0 and plane[i3][j3] > 0 and plane[i4][j4] < 0) or (plane[i1][j1] > 0 and plane[i2][j2] < 0 and plane[i3][j3] < 0 and plane[i4][j4] > 0)):
        i = (i1 + i3 - h)/2
        j = (j1 + j3 - w)/2

        state = (i**2 + j**2 - 1)**3 - i**2 * j**3
        if((state < 0 and plane[i1][j1] < 0) or (state > 0 and plane[i1][j1] > 0)):
            finalP1 = pygame.math.Vector2(j1, Bisection_Method(i1, i3, j1, False))
            finalP2 = pygame.math.Vector2(Bisection_Method(j3, j4, i3, True), i3)
            finalP3 = pygame.math.Vector2(Bisection_Method(j1, j2, i1, True), i1)
            finalP4 = pygame.math.Vector2(j4, Bisection_Method(i2, i4, j4, False))
        else:
            finalP2 = pygame.math.Vector2(j1, Bisection_Method(i1, i3, j1, False))
            finalP3 = pygame.math.Vector2(Bisection_Method(j3, j4, i3, True), i3)
            finalP1 = pygame.math.Vector2(Bisection_Method(j1, j2, i1, True), i1)
            finalP4 = pygame.math.Vector2(j4, Bisection_Method(i2, i4, j4, False))
    
    return finalP1, finalP2, finalP3, finalP4


t = []
for i in range(h - 1):
    for j in range(w - 1):
        P1, P2, P3, P4 = MarchingSquares(i, j, i, j + 1, i + 1, j, i + 1, j + 1, grid)

        t.append([P1, P2, P3, P4])
    print("marching {i}")
# pygame setup
pygame.init()
screen = pygame.display.set_mode((w, h))
clock = pygame.time.Clock()
running = True
dt = 0

while running:
    # poll for events
    # pygame.QUIT event means the user clicked X to close your window
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False

    # fill the screen with a color to wipe away anything from last frame
    screen.fill("white")

    for x in t:
        pygame.draw.line(screen, "purple", x[0], x[1])

        if(x[2].x != float('inf')):
            pygame.draw.line(screen, "purple", x[2], x[3])

    # flip() the display to put your work on screen
    pygame.display.flip()

    # limits FPS to 60
    # dt is delta time in seconds since last frame, used for framerate-
    # independent physics.
    dt = clock.tick(60) / 1000


pygame.quit()

现在首先解释我的代码,我在整个屏幕上生成网格。之后,我通过 if else 语句检查 16 个案例来编写行进平方算法,并使用二分法作为求根算法。我给它一个状态参数,它决定我应该从 a 和 b 中提取什么值,True => 我正在 X 轴上进行操作,False => 我正在 Y 轴上进行操作。

这是结果:

enter image description here

python pygame
1个回答
0
投票
import pygame
import numpy as np

pygame.init()

W, H = 500, 500
THRESHOLD = 0.001

screen = pygame.display.set_mode((W, H))
pygame.display.set_caption("Heart Curve")

def heart_function(x, y):
    x, y = (x - 0.5) * 2.8, -(y - 0.45) * 2.8
    return (x**2 + y**2 - 1)**3 - x**2 * y**3

def marching_squares(x, y, size):
    corners = [
        (x, y), (x + size, y),
        (x, y + size), (x + size, y + size)
    ]
    values = [heart_function(cx/W, cy/H) for cx, cy in corners]
    
    case = sum([1 << i for i, v in enumerate(values) if v < 0])
    
    lines = []
    if case in (1, 14):
        lines.append((x, y + size * values[0] / (values[0] - values[2])))
        lines.append((x + size * values[0] / (values[0] - values[1]), y))
    elif case in (2, 13):
        lines.append((x + size, y + size * values[1] / (values[1] - values[3])))
        lines.append((x + size * values[0] / (values[0] - values[1]), y))
    elif case in (4, 11):
        lines.append((x, y + size * values[0] / (values[0] - values[2])))
        lines.append((x + size * values[2] / (values[2] - values[3]), y + size))
    elif case in (7, 8):
        lines.append((x + size, y + size * values[1] / (values[1] - values[3])))
        lines.append((x + size * values[2] / (values[2] - values[3]), y + size))
    elif case in (3, 12):
        lines.append((x + size * values[0] / (values[0] - values[1]), y))
        lines.append((x + size * values[2] / (values[2] - values[3]), y + size))
    elif case in (5, 10):
        lines.append((x, y + size * values[0] / (values[0] - values[2])))
        lines.append((x + size, y + size * values[1] / (values[1] - values[3])))
    elif case in (6, 9):
        mid_x, mid_y = x/W + size/(2*W), y/H + size/(2*H)
        if heart_function(mid_x, mid_y) < 0:
            lines.append((x, y + size * values[0] / (values[0] - values[2])))
            lines.append((x + size * values[2] / (values[2] - values[3]), y + size))
            lines.append((x + size, y + size * values[1] / (values[1] - values[3])))
            lines.append((x + size * values[0] / (values[0] - values[1]), y))
        else:
            lines.append((x, y + size * values[0] / (values[0] - values[2])))
            lines.append((x + size * values[0] / (values[0] - values[1]), y))
            lines.append((x + size, y + size * values[1] / (values[1] - values[3])))
            lines.append((x + size * values[2] / (values[2] - values[3]), y + size))
    
    return lines

def draw_heart():
    screen.fill((255, 255, 255))
    cell_size = 5
    for x in range(0, W, cell_size):
        for y in range(0, H, cell_size):
            lines = marching_squares(x, y, cell_size)
            for start, end in zip(lines[::2], lines[1::2]):
                pygame.draw.line(screen, (255, 0, 0), start, end, 2)
        
        if x % 50 == 0: 
            pygame.display.flip()
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    return False
    return True

def main():
    clock = pygame.time.Clock()
    running = True
    heart_drawn = False

    while running:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                running = False

        if not heart_drawn:
            heart_drawn = draw_heart()

        pygame.display.flip()
        clock.tick(60)

    pygame.quit()

if __name__ == "__main__":
    main()
最新问题
© www.soinside.com 2019 - 2024. All rights reserved.