Math 关于贝塞尔曲线实现的问题?

Math 关于贝塞尔曲线实现的问题?,math,geometry,Math,Geometry,我读过一些关于贝塞尔曲线的教程,比如这篇 创建贝塞尔曲线的基本思想是使用一些控制点,并决定需要创建多少个新点。然后对这些新点进行插值 问题是: 假设我有1000个点,我想再插值2000个点。我想使用的控制点数量是5。参数t在[0,1]的范围内 吉文斯点P0,P1,P2,P3,P4,P5,P6,…P1000。 我可以使用P0-P4生成新的点,然后下一步是什么? 使用P5-P9生成新点???我可以立即看到P4和P5之间有一个突然的转变 我如何解决这个问题 多谢各位 /////////////////

我读过一些关于贝塞尔曲线的教程,比如这篇

创建贝塞尔曲线的基本思想是使用一些控制点,并决定需要创建多少个新点。然后对这些新点进行插值

问题是:

假设我有1000个点,我想再插值2000个点。我想使用的控制点数量是5。参数t在[0,1]的范围内

吉文斯点P0,P1,P2,P3,P4,P5,P6,…P1000。 我可以使用P0-P4生成新的点,然后下一步是什么? 使用P5-P9生成新点???我可以立即看到P4和P5之间有一个突然的转变

我如何解决这个问题

多谢各位

///////////////////////////////////////////////////// 您好Stargazer712

我理解你的意见,直到它达到实施方法

假设我们有以下几点:

A1->A2->A3->A4->A5->A6->A7->A8 initial points
你说我们需要在每对的中点添加一个新点

我的问题是新点的顺序是什么

让我们使用这个注释(A1+A3)/2==A12

现在生成的新点是

A13 A24 A35 A46 A57 A68 (this is what you mean "every other pair"?
我应该在哪里将这些点插入原始列表

我正在处理的轮廓是从二值图像中提取的。生成的轮廓为之字形。在我应用这个平滑方法之后,它的形状没有太大的改善。我认为主要的原因是邻居彼此很近,使得插值没有那么有用

多谢各位


////////////////////////////////////////////////////

我认为您要做的是创建一条平滑的曲线,对点进行插值。为此,您需要了解以下关于贝塞尔曲线的内容:

假设我们有两条点为A1、A2、A3、A4和B1、B2、B3和B4的曲线

如果两条曲线在同一点上结束,并且如果第一条曲线的最后一个控制点与下一条曲线的第一个控制点共线,则曲线将平滑。因此,在我们的示例中,如果:

  • A4==B1
  • A3、A4和B2是共线的(与A3、B1、B2是共线的说法相同)
然后曲线将变得平滑

为了获取任意点列表并生成平滑曲线,我们需要强制这两个条件为真

为此,假设我们从一组点开始:

为了强制执行上述条件,让我们添加一些额外的点。我们将在每隔一对的中点处放置一个新点,如图所示:

我们现在可以在点0-3、3-6、6-9等之间绘制bezier曲线,我们可以确保它将形成平滑曲线:

希望这有帮助

编辑:这里有一个简单的python程序,它完全实现了上面所示的内容(我的意思是)。您需要安装python和PIL:

from PIL import Image
import math

#
#   draws a single point on our image
#
def drawPoint( img, loc, size=5, color=(0,0,0) ):
    px = img.load()
    for x in range(size):
        for y in range(size):
            xloc = loc[0] + x - size/2
            yloc = loc[1] + y - size/2
            px[ xloc, yloc ] = color


#
#   draws a simple bezier curve with 4 points
#            
def drawCurve( img, points ):

    steps = 20
    for i in range(steps):

        t = i / float(steps)

        xloc = math.pow(1-t,3) * points[0][0] \
             + 3*t*math.pow(1-t,2) * points[1][0] \
             + 3*(1-t)*math.pow(t,2) * points[2][0] \
             + math.pow(t,3) * points[3][0]
        yloc = math.pow(1-t,3) * points[0][1] \
             + 3*t*math.pow(1-t,2) * points[1][1] \
             + 3*(1-t)*math.pow(t,2) * points[2][1] \
             + math.pow(t,3) * points[3][1]

        drawPoint( img, (xloc,yloc), size=2 )


#
#   draws a bezier curve with any number of points
#
def drawBezier( img, points ):

    for i in range(0,len(points),3):
        if( i+3 < len(points) ):
            drawCurve( img, points[i:i+4] )


#
#   draws a smooth bezier curve by adding points that
#   force smoothness
#
def drawSmoothBezier( img, points ):

    newpoints = []

    for i in range(len(points)):

        # add the next point (and draw it)
        newpoints.append(points[i])
        drawPoint( img, points[i], color=(255,0,0) )

        if( i%2 == 0 and i>0 and i+1<len(points) ):

            # calculate the midpoint
            xloc = (points[i][0] + points[i+1][0]) / 2.0
            yloc = (points[i][1] + points[i+1][1]) / 2.0

            # add the new point (and draw it)
            newpoints.append( (xloc, yloc) )
            drawPoint( img, (xloc, yloc), color=(0,255,0) )

    drawBezier( img, newpoints )



#   Create the image
myImage = Image.new("RGB",(627,271),(255,255,255))

#   Create the points
points = [  (54,172), 
            (121,60), 
            (220,204), 
            (284,56), 
            (376,159), 
            (444,40), 
            (515,228), 
            (595,72) ]

#   Draw the curve
drawSmoothBezier( myImage, points )

#   Save the image
myImage.save("myfile.png","PNG")
从PIL导入图像
输入数学
#
#在图像上绘制一个点
#
def提取点(img,loc,尺寸=5,颜色=(0,0,0)):
px=img.load()
对于范围内的x(尺寸):
对于范围内的y(尺寸):
xloc=loc[0]+x-尺寸/2
yloc=loc[1]+y-尺寸/2
px[xloc,yloc]=颜色
#
#绘制具有4个点的简单贝塞尔曲线
#            
def牵引曲线(img,点):
步骤=20
对于范围内的i(步):
t=i/浮动(步数)
xloc=数学功率(1-t,3)*点[0][0]\
+3*t*数学功率(1-t,2)*分[1][0]\
+3*(1-t)*数学功率(t,2)*分[2][0]\
+数学功率(t,3)*分[3][0]
yloc=数学功率(1-t,3)*点[0][1]\
+3*t*数学功率(1-t,2)*点[1][1]\
+3*(1-t)*数学功率(t,2)*分[2][1]\
+数学功率(t,3)*分[3][1]
支点(img,(xloc,yloc),尺寸=2)
#
#绘制具有任意点数的贝塞尔曲线
#
def drawBezier(img,点):
对于范围内的i(0,len(点),3):
如果(i+3如果(i%2==0,i>0,i+1你好,Stargazer712,我根据你的评论发布了新问题。请查看我原始问题下的帖子。谢谢you@q0987-绘制贝塞尔曲线的程序非常简单。我希望一个示例能够回答您可能遇到的任何问题。非常感谢您的帮助。您的编码风格看起来非常完美:)您能为图像的A1、A2、B4添加标签吗?非常有帮助,谢谢。在
drawBezier
函数中进行一个小的修正,条件应该是
如果(i+3
这样,如果只传递了4个点,它就会起作用。