问题描述
我现在正在做的是将贝塞尔曲线和线的 100 个坐标点重新组合成一条折线,为此,我试图使用数学来生成放置在 1 个起点和起点之间的线上的点的坐标1 个终点。
问题是我得到了正确的 y 值、高于预期的 y 值和低于预期的 y 值,具体取决于直线上的情况(贝塞尔曲线工作正常),这是我现在的代码:
import pygame
from pygame import gfxdraw
from random import randint
from win32api import GetSystemMetrics
from time import time
import math
import numpy as np
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
running = True
while running:
pygame.font.init()
font = pygame.font.SysFont('freesansbold.ttf',32)
text = font.render('NotBezier',True,(0,255))
points = []
gen_points = generate_original_and_p(9,800,234)
size = [width,height]
screen = pygame.display.set_mode(size,32)
screen.fill((33,33,33))
curve = []
# Draw bezier curves from points in a list
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))
dist_x = gen_points[i+2][0] - gen_points[i][0]
dist_y = gen_points[i+2][1] - gen_points[i][1]
if dist_s < 234/2:
line = []
print(dist_s)
gfxdraw.line(screen,gen_points[i][0],gen_points[i][1],gen_points[i+2][0],gen_points[i+2][1],255))
m = (gen_points[i][1] - gen_points[i+2][1]) / (gen_points[i][0] - gen_points[i+2][0])
b = np.linalg.norm(np.diff([gen_points[i],gen_points[i+2]],axis=0),axis=1).tolist()[0]
for ratio in np.linspace(0,1,10):
print("ratio = "+str(ratio)+",m = "+str(m)+",b = "+str(b)+",dist_x = "+str(dist_x)+",dist_y = "+str(dist_y))
line.append([gen_points[i][0]+(ratio * dist_x),gen_points[i][1] + (m * (ratio * dist_y) + b)])
curve.append(line)
if i+2 == len(gen_points)-1:
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))
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)
print(curve)
print(len(curve))
i = input("quit?: ")
pygame.display.quit()
if i == "quit":
running = False
这是点 [[1059,559],[1472,684],[1090,509]] 的示例列表
这是创建行时的示例输出:
ratio = 0.0,m = -1.6129032258064515,b = 58.83026432033091,dist_x = 31,dist_y = -50
ratio = 0.1111111111111111,dist_y = -50
ratio = 0.2222222222222222,dist_y = -50
ratio = 0.3333333333333333,dist_y = -50
ratio = 0.4444444444444444,dist_y = -50
ratio = 0.5555555555555556,dist_y = -50
ratio = 0.6666666666666666,dist_y = -50
ratio = 0.7777777777777777,dist_y = -50
ratio = 0.8888888888888888,dist_y = -50
ratio = 1.0,dist_y = -50
# Points on screen
[
[807,333],[1205,526],[1257,373],[1039,507],[724,834],[626,765],[1059,509]
]
# Coordinate of the 10 points located on that line and spaced by 10%
[
[
[1059.0,617.8302643203309],[1062.4444444444443,626.7908377970334],[1065.888888888889,635.7514112737359],[1069.3333333333333,644.7119847504384],[1072.7777777777778,653.6725582271409],[1076.2222222222222,662.6331317038434],[1079.6666666666667,671.593705180546],[1083.111111111111,680.5542786572485],[1086.5555555555557,689.514852133951],[1090.0,698.4754256106535]
]
]
如您所见,使用此函数的 y 横坐标高于预期,这只是许多情况中的一个案例。
是否知道导致此问题的原因以及如何解决?
TL:DR -> 使用 thisis 函数 https://pastebin.com/xgNLQiVt 在某些情况下获得不正确的 y 值
解决方法
猜猜 50K+ 提供某个函数的用法很复杂,因为我知道我也在我的代码中使用了 numpy,我找到了另一种方法来获得我想要的东西:
# Generate 1000 x coordinates / Generate 1000 y coordinates
list_x,list_y = np.linspace(Points[i][0],Points[i+2][0],1000),np.linspace(Points[i][1],Points[i+2][1],1000)
# Generate a list of coordinates out of list_x and list_y
line = [[list_x[i],list_y[i]] for i in range(1000)]
而且可能有一种更简单、更短的方法,我不知道获得相同的东西