【曲线绘制】贝塞尔曲线
gamemaker吧
全部回复
仅看楼主
吧务
level 14
梦想君🐨 楼主
一楼放曲线演示
2015年08月27日 13点08分 1
吧务
level 14
梦想君🐨 楼主
先上一段摆渡百科:贝塞尔曲线(Bézier curve),又称贝兹曲线或贝济埃曲线,是应用于二维图形应用程序的数学曲线。一般的矢量图形软件通过它来精确画出曲线,贝兹曲线由线段与节点组成,节点是可拖动的支点,线段像可伸缩的皮筋,我们在绘图工具上看到的钢笔工具就是来做这种矢量曲线的。贝塞尔曲线是计算机图形学中相当重要的参数曲线,在一些比较成熟的位图软件中也有贝塞尔曲线工具,如PhotoShop等。在Flash4中还没有完整的曲线工具,而在Flash5里面已经提供出贝塞尔曲线工具。
2015年08月27日 13点08分 2
吧务
level 14
梦想君🐨 楼主
众所周知,gm中可以绘制出各种各样的形状,但却没有曲线绘制,因此功能受到了局限
但是
,虽然没有曲线绘制函数,但是gm中却有一种曲线,那就是路径
当路径的连接方式设定为
平滑曲线时,则绘制出来的路径是一条
二次贝塞尔曲线,可以使用draw_path()函数绘制出来
虽然这样可以画出一条曲线,但是由于路径属于资源在使用时不灵活、曲线精度较低、且我们实际使用时大多使用的是三次贝塞尔曲线,因此这种方式不提倡使用
二次曲线看起来就是这样的:
由于我们不使用二次曲线,所以在这里不多加讨论
2015年08月27日 13点08分 5
吧务
level 14
梦想君🐨 楼主
我们就直接开始讨论三次曲线(另外,插楼的自重)
三次贝塞尔曲线比二次曲线多了一个控制点,所以整个曲线由两个控制点(P1,P2)和起始终止点(P0,P3)控制。
P0、P1、P2、P3四个点在平面或在三维空间中定义了三次方贝塞尔曲线。曲线起始于P0走向P1,并从P2的方向来到P3。一般不会经过P1或P2;这两个点只是在那里提供方向资讯。P0和P1之间的间距,决定了曲线在转而趋进P3之前,走向P2方向的“长度有多长”。
曲线的参数形式为:
上图的曲线,是参数t从0到1时,上图中移动的黑点所走过的路径,那么看到这里,有些人就不太明白这个三次曲线是怎么定义的了,所以。我们还是得从头说起
2015年08月27日 13点08分 6
吧务
level 14
梦想君🐨 楼主
线性贝塞尔曲线
给定点P0、P1,线性贝塞尔曲线只是一条两点之间的直线。这条线由下式给出:
当参数t由0到1变化时,其过程如下:
这个t值是曲线占总曲线长度的分量,你可以把总曲线长度看作1,当t为0.5时,图中的黑点就在这条曲线的中间(虽然一次贝塞尔曲线实际上就是条直线)
二次曲线
二次曲线实际上是由一次曲线得出的,为构建二次贝塞尔曲线,我们需要定义多条一次贝塞尔曲线
由P0至P1的连续点Q0,描述一条线性贝塞尔曲线。
由P1至P2的连续点Q1,描述一条线性贝塞尔曲线。
由Q0至Q1的连续点Q1,描述一条线性贝塞尔曲线。
由P0至P1的连续点B(t),描述一条二次贝塞尔曲线。
点B(t)所走过的路径就是一条二次贝塞尔曲线
同理,三次贝塞尔曲线也是由多条线性曲线定义的
2015年08月27日 14点08分 7
吧务
level 14
梦想君🐨 楼主
那么,知道了原理,我们就能绘制出曲线了,在这里,由于没办法直接绘制曲线,我使用的是原始绘制函数使用多段直线连接的方式绘制出近似曲线
draw_primitive_begin(kind) //开始一个原始显示类型。
draw_vertex(x,y) //增加顶点 (x,y)到原始表中,使用之前设定的颜色和透明度 。
pr_linestrip //一组连续线,从第一个点到第二个点,再到第三个点,等等。最后一个没有 和第一个点连接。你需要指定一个额外的第一顶点拷贝。
draw_primitive_end() //结束描述原始绘制,这个函数是马上绘制它。
用以上代码即可完成连续线的绘制,使用原始绘制直线也比直接用draw_line()+for循环绘制直线要快
我们将他写成一个脚本以便于绘制:
///draw_bezier_cubic(x1,y1,x2,y2,x3,y3,x4,y4,complexity);
//画一条三阶贝塞尔曲线 两个控制点(x2,y2,x3,y3) 两个起始点和中间点(x1,y1,x4,y4) 精度(complexity)
var point_x,point_y;
draw_primitive_begin(pr_linestrip)
for(i = 0; i <= 1; i+= 1/argument8)
{
point_x = power(1-i,3)*argument0 + 3*power(1-i,2)*i*argument2
+3
*(1-i)*power(i,2)*argument4+power(i,3)*argument6;
point_y = power(1-i,3)*argument1 + 3*power(1-i,2)*i*argument3+3*(1-i)*power(i,2)*argument5+power(i,3)*argument7;
//由曲线函数得出当t==i时的点坐标
draw_vertex(point_x,point_y);
//插入原始绘制顶点,意在将曲线拟合到指定点上
}
draw_primitive_end();
//结束原始绘制,绘制出直线化后的曲线(如果精度足够高,是能达到曲线的效果的)
这是精度为100时的曲线,没有直线化的特征
精度为10的曲线,看上去很有意思
2015年08月27日 14点08分 8
level 10
初中党表示看不太懂
2015年08月28日 11点08分 10
嘛,只要知道贝赛尔函数,直接往里面带参数就行了
2015年08月30日 04点08分
@梦想君🐨 多谢分享了[真棒]
2015年08月30日 04点08分
level 2
[滑稽]求支持矢量插件
2016年02月10日 01点02分 11
这种东西,,,怎么可能会有,自己写吧
2016年02月10日 16点02分
flash啊
2017年08月06日 03点08分
level 7
6666!类似ps里面的钢笔工具
2016年02月10日 19点02分 12
level 7
画曲线不愁了,ps里的钢笔工具是三阶贝塞尔曲线?
2016年02月10日 19点02分 13
level 12
有没有四次?
2016年02月13日 14点02分 14
要四次干嘛
2016年02月14日 10点02分
level 7
原来flash里面的钢笔工具是这个用处
2017年08月14日 02点08分 15
1