首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Bezier曲线求值

Bezier曲线求值
EN

Stack Overflow用户
提问于 2011-10-30 01:51:12
回答 5查看 11.2K关注 0票数 1

我在这里使用de的算法评估跟踪本文,并尝试使用主题在C++,OpenGL中用De Casteljau算法绘制Bezier曲线提供帮助。没有成功。

求值时,我的bezier曲线如下所示

正如你所看到的,即使它没有达到我想要的效果,但所有的点都在曲线上。因此,我不认为这个算法是不准确的。

这是我在那张图像的顶部曲线上的点:(0,0) (2,0) (2,2) (4,2)第二条曲线使用相同的点集,除了第三点是(0,2),即在第一点之上的两个单位,形成一个更陡峭的曲线。

有些地方不对劲。我应该为t加0.25个,它应该为X值喷出1.0,.75应该总是返回3,假设t是时间。它应该以恒定的速度前进,是吗?精确的25%的方式,X值应该是1.0,然后Y应该与该值相关联。

有什么足够的方法来评估bezier曲线吗?有人知道这是怎么回事吗?

(谢谢你的帮助!)

编辑?

我在谷歌搜索curves.pdf中找到了这本书,这是我在显式/非参数bezier曲线上找到的页面。它们是用bezier曲线表示的多项式,这就是我要说的。这是这本书的那一页:

有人知道如何将bezier曲线转换成参数曲线吗?我现在可以打开另一条线..。

2011年11月1日再次编辑-

我意识到我只问了这个问题,大概是我应该问的一半。我想要构建的是玛雅的动画图形编辑器,比如这个http://www.youtube.com/watch?v=tckN35eYJtg&t=240,其中用来修改曲线的贝塞尔控制点更像是等长的切线修饰符。老实说,我不记得他们是一样长的。通过强制这样的系统,您可以确保100%的结果是一个函数,并且不包含重叠段。

我找到了这个,这可能是我的答案,编辑器

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2013-06-13 22:57:20

过了这么久,我一直在找她的曲线。Hermites是好的,因为在一维,他们保证产生一个功能曲线,可以评估到XY点。我把Hermites和Bezier搞混了。

票数 0
EN

Stack Overflow用户

发布于 2011-11-01 01:43:39

在这里,您可以看到在链接中的术语下面用Mathematica实现的算法,以及您的两幅图:

代码语言:javascript
复制
(*Function Definitions*)

lerp[a_, b_, t_] := (1 - t) a + t b;
pts1[t_] := {
   lerp[pts[[1]], pts[[2]], t],
   lerp[pts[[2]], pts[[3]], t],
   lerp[pts[[3]], pts[[4]], t]};
pts2[t_] := {
   lerp[pts1[t][[1]], pts1[t][[2]], t],
   lerp[pts1[t][[2]], pts1[t][[3]], t]};
pts3[t_] := {
   lerp[pts2[t][[1]], pts2[t][[2]], t]};

(*Usages*)

pts = {{0, 0}, {2, 0}, {2, 2}, {4, 2}};
Framed@Show[ParametricPlot[pts3[t], {t, 0, 1}, Axes -> True], 
            Graphics[{Red, PointSize[Large], Point@pts}]]

pts = {{0, 0}, {2, 0}, {0, 2}, {4, 2}};
Framed@Show[ParametricPlot[pts3[t], {t, 0, 1}, Axes -> True], 
            Graphics[{Red, PointSize[Large], Point@pts}]]

顺便说一句,曲线是由以下参数方程定义的,这些参数方程是上面代码中的函数pts3[t]

代码语言:javascript
复制
c1[t_] := {2 t (3 + t (-3 + 2 t)), (* <- X component *)
                 2 (3 - 2 t) t^2}  (* <- Y component *)

代码语言:javascript
复制
c2[t_] := {2 t (3 + t (-6 + 5 t)), (* <- X component *)
               , 2 (3 - 2 t) t^2}  (* <- Y component *)

试试策划他们!

取任何这些曲线方程,通过求解三次多项式,你就可以得到yx的表达式,这当然不总是可能的。您只需从第一条曲线(C语法)中了解它的味道:

代码语言:javascript
复制
y[x]= 3 - x - 3/Power(-2 + x + Sqrt(5 + (-4 + x)*x),1/3) + 
              3*Power(-2 + x + Sqrt(5 + (-4 + x)*x),1/3)

Try plotting it!

编辑

只是一种娱乐:

Mathematica是一种功能强大的语言,实际上整个算法可以用一行代码来表示:

代码语言:javascript
复制
f = Nest[(1 - t) #[[1]] + t #[[2]] & /@ Partition[#, 2, 1] &, #, Length@# - 1] &

比如

代码语言:javascript
复制
f@{{0, 0}, {2, 0}, {0, 2}, {4, 2}}

给出上述结果,但支持任意数量的点。

让我们来看看六个随机点:

代码语言:javascript
复制
p = RandomReal[1, {6, 2}];
Framed@Show[
  Graphics[{Red, PointSize[Large], Point@p}],
  ParametricPlot[f@p, {t, 0, 1}, Axes -> True]]

此外,同样的功能也适用于3D:

代码语言:javascript
复制
p = RandomReal[1, {4, 3}];
Framed@Show[
  Graphics3D[{Red, PointSize[Large], Point@p}],
  ParametricPlot3D[f[p], {t, 0, 1}, Axes -> True]]

票数 12
EN

Stack Overflow用户

发布于 2011-11-01 03:19:49

bezier曲线可以通过求解x、y和z坐标的下列参数方程来求解(如果它只是2D,只做x和y):

代码语言:javascript
复制
Px = (1-t)^3(P1x) + 3t(1-t)^2(P2x) + 3t^2(1-t)(P3x) + t^3(P4x)
Py = (1-t)^3(P1y) + 3t(1-t)^2(P2y) + 3t^2(1-t)(P3y) + t^3(P4y)
Pz = (1-t)^3(P1z) + 3t(1-t)^2(P2z) + 3t^2(1-t)(P3z) + t^3(P4z)

还可以通过乘以矩阵方程ABC =X来解决这个问题,其中:

  1. 矩阵A是一个1x4矩阵,表示t的幂值。
  2. 矩阵B是t的幂系数,是一个下三角4x4矩阵。
  3. 矩阵C是一个4x3矩阵,它代表三维空间中的四个bezier点(它将是2D空间中的一个4x2矩阵)。

如下所示:

(更新-左下角1应该是a -1)

方程的两种形式(参数形式和矩阵形式)的一个重要注意事项是,t在0,1的范围内。

与其试图求解t的值,这将给出xy的积分值,这将是耗时的,因为你基本上是在求解一个3次多项式的真实根,最好是简单地在t值中创建一个足够小的微分,这样曲线上任何两个点之间的差值都小于像素值增量。换句话说,P(t1)P(t2)两点之间的距离小于像素值。或者,您可以在t中使用更大的微分,只需在P(t1)P(t2)之间线性内插,同时要记住,如果P(t1)P(t2)之间的差异对于给定的t范围(从0,1 )来说不够小,则曲线可能不是“光滑的”。

t中找到从视觉角度创建相当“光滑”曲线的必要微分的一个好方法是实际测量定义bezier曲线的四个点之间的距离。测量P1到P2、P2、P3和P3到P4的距离。然后取最长距离,并使用该值的逆值作为t的微分。你可能还需要在点之间做一些线性插值,但是每个“线性”子曲线中的像素数应该相当小,因此曲线本身看起来相当平滑。您可以始终将t上的差分值从这个初始值降到“平滑”。

最后,回答你的问题:

假设这是时间。它应该以恒定的速度前进,是吗?精确的25%的方式,X值应该是1.0,然后Y应该与该值相关联。

不,这是不正确的,原因是向量(P2 - P1)和(P3 - P4)不仅与P1和P4的bezier曲线相切,而且它们的长度也定义了在这些点沿曲线的速度。因此,如果向量(P2 - P1)是一个短距离,那么这意味着在给定的时间内t,您将不会很远地从点P1 .这转化为x,y值沿曲线非常紧密地包装在一起,一个给定的固定微分的t。当你向P1移动时,你的速度实际上是“减慢”了。同样的影响发生在P4上的曲线上,这取决于向量的长度(P3 - P4)。唯一的方法,沿着曲线的速度将是“恒定”,因此,任何一点之间的任何一点之间的共同微分t将是相同的,如果所有三个区段的长度(P2 - P1),(P3 - P2)和(P4 - P3)是相同的。这就表明曲线上的速度没有变化。

票数 9
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7942840

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档