如果两点之间的距离小于指定值,则生成线而不是贝塞尔曲线

问题描述

如果两点之间的距离小于我指定的像素数量(即圆的大小),我想生成一条线 除了它没有做我想要的,而是创建了不连接的奇怪线条

enter image description here

如您所见,它没有按预期工作,(不是故意的,因为我的代码可能做错了导致此问题的问题)这是我的代码 rn:

import pygame
from pygame import gfxdraw
from random import randint
from win32api import GetSystemMetrics
from time import time
import math

class circles(pygame.sprite.Sprite):
    def __init__(self,surface,x,y,cs):
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.image.load("./assets/circle.png").convert_alpha()
        size = (round(2.25*(109-(9*cs))),round(2.25*(109-(9*cs))))
        self.image = pygame.transform.scale(self.image,size)
        self.draw = surface.blit(self.image,(x-((size[0])/2),y-((size[1])/2)))

width = GetSystemMetrics(0)
height = GetSystemMetrics(1)

def generate_original_points_coordinates():
    points.append([randint(0,width),randint(0,height)])

def generate_points_coordinates(count,spacing,circle_size_px):
    for i in range(0,count):
        generating = True
        while generating:
            x = points[0][0]+randint(-spacing,spacing)
            y = points[0][1]+randint(-spacing,spacing)
            if y < height-circle_size_px and y > circle_size_px and x < width-circle_size_px and x > circle_size_px: 
                generating = False
        points.append([x,y])

def generate_original_and_p(count,circle_size_px):
    generate_original_points_coordinates()
    generate_points_coordinates(count,circle_size_px)
    return points

def draw_circles(surface,r,rgb_code):
    gfxdraw.filled_circle(surface,rgb_code)


running = True
while running:
    start = time()
    points = []
    gen_points = generate_original_and_p(10,800,234)
    size = [width,height]
    screen = pygame.display.set_mode(size,32)
    screen.fill((255,255,255))
    circles_list = [circles(screen,gen_points[i][0],gen_points[i][1],4) for i in range(0,len(gen_points))]

    # Draw bezier curves from points in a list

    for i in range(2,len(gen_points)):
        if math.sqrt(math.pow(gen_points[i-1][0]-gen_points[i-2][0],2)+math.pow(gen_points[i-1][1]-gen_points[i-2][1],2)) > 234:
            gfxdraw.line(screen,gen_points[i-2][0],gen_points[i-2][1],gen_points[i-1][1],(0,255))
    
    [gfxdraw.bezier(screen,[gen_points[i-2],gen_points[i-1],gen_points[i]],4500,(255,0)) for i in range(2,len(gen_points))]

    # Place points on such curves and lines

    
    pygame.display.flip()
    print(gen_points)
    end = time()
    print(end-start)
    i = input("quit?: ")
    pygame.display.quit()
    if i == "quit":
        running = False

我也尝试过 math.hypo,但结果相同,所以我缺乏想法

解决方法

我的实现有几个问题,我现在已经全部重新设计,它现在应该可以工作,这是我想要和制作的示例案例

case if 2 non-control points distance

case if 2 non-control points distance < 234

其他:

enter image description here

正如你所看到的,它现在可以使用这段代码,我可能会以某种方式缩短和优化

import pygame
from pygame import gfxdraw
from random import randint
from win32api import GetSystemMetrics
from time import time
import math

class circles(pygame.sprite.Sprite):
    def __init__(self,surface,x,y,cs):
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.image.load("./assets/circle.png").convert_alpha()
        size = (round(2.25*(109-(9*cs))),round(2.25*(109-(9*cs))))
        self.image = pygame.transform.scale(self.image,size)
        self.draw = surface.blit(self.image,(x-((size[0])/2),y-((size[1])/2)))

width = GetSystemMetrics(0)
height = GetSystemMetrics(1)

def generate_original_points_coordinates(circle_size_px):
    generating = True
    while generating:
        x = randint(0,width)
        y = randint(0,height)
        if y < height-circle_size_px and y > circle_size_px and x < width-circle_size_px and x > circle_size_px:
            points.append([x,y])
            generating = False

def generate_points_coordinates(count,spacing,circle_size_px):
    for i in range(0,count-1):
        generating = True
        while generating:
            x = points[-1][0]+randint(-spacing,spacing)
            y = points[-1][1]+randint(-spacing,spacing)
            if y < height-circle_size_px and y > circle_size_px and x < width-circle_size_px and x > circle_size_px: 
                generating = False
                points.append([x,y])
        
def generate_original_and_p(count,circle_size_px):
    generate_original_points_coordinates(circle_size_px)
    generate_points_coordinates(count,circle_size_px)
    return points

def draw_circles(surface,r,rgb_code):
    gfxdraw.filled_circle(surface,rgb_code)
from time import sleep

prompt = True
while prompt:
    circle_count = input("Count: ")
    if circle_count.isdigit():
        circle_count = int(circle_count)
        prompt = False

running = True
while running:
    pygame.font.init()
    font = pygame.font.SysFont('freesansbold.ttf',32)
    text = font.render('NotBezier',True,(0,255))
    start = time()
    points = []
    gen_points = generate_original_and_p(circle_count,800,234)
    size = [width,height]
    screen = pygame.display.set_mode(size,32)
    screen.fill((33,33,33))
    #circles_list = [circles(screen,gen_points[i][0],gen_points[i][1],4) for i in range(0,len(gen_points))]
    circles_list = []
    # Draw bezier curves from points in a list
    skip = 0
    for i in range(0,len(gen_points)-2):
        dist_s = math.sqrt(math.pow(gen_points[i+2][0]-gen_points[i][0],2)+math.pow(gen_points[i+2][1]-gen_points[i][1],2))
        if skip:
            skip = 0
            continue
        if dist_s < 234/2:
            print(dist_s)
            gfxdraw.line(screen,gen_points[i+2][0],gen_points[i+2][1],255))
            skip=1
            print("line")
        else:
            gfxdraw.bezier(screen,[gen_points[i],gen_points[i+1],gen_points[i+2]],4500,(255,0))
            skip = 1
        if i+2 == len(gen_points)-1:
            circles_list.append(circles(screen,4))
            gfxdraw.filled_circle(screen,5,255,0))
            screen.blit(font.render(str(i+2),0)),(gen_points[i+2][0],gen_points[i+2][1]+10))
            
        circles_list.append(circles(screen,4))
        gfxdraw.filled_circle(screen,0))
        screen.blit(font.render(str(i),(gen_points[i][0],gen_points[i][1]+10))

    pygame.display.flip()

    # Place points on such curves and lines

    print(gen_points)
    end = time()
    print(end-start)
    i = input("quit?: ")
    pygame.display.quit()
    if i == "quit":
        running = False

跳过控制点是我正在寻找的解决方案,这就是结果