三阶贝塞尔曲线拟合1/2正弦
2015-08-31 22:54
288 查看
三阶贝塞尔曲线拟合1/2正弦
根据贝塞尔曲线的知识,我们知道三阶贝塞尔曲线的参数方程如下,其中A、B、C、D为四个控制点坐标,P(t)表示曲线上的每一点。
因为要模拟1/2正弦,所以通过P(0)和P(1)的切线方向,应该按照下图所示位置安放。
其中AB为水平向左方向,DC为水平向右方向,并且线段长度|AB| = |DC| = h。
那么这个问题实际上,就转换为计算出合理的h值,使得曲线(原点)中点处的斜率为1。
根据P(t)定义,求得三阶贝塞尔曲线的导数为:
根据贝塞尔曲线的对称性,不难想出P(0.5)在原点处,代入公式即可求得:
代入四个控制点坐标A(-PI/2, -1),B(-PI/2 + h, 1),C(PI/2 - h, 1)和D(PI/2, 1),可以求解P'(0.5)的值如下:
根据正弦曲线在原点处的斜率为1可知,P'(0.5)表示的斜率为1,从而拟出下面方程:
从而求解出h的值为:
所以,可以最终求解出三阶贝塞尔曲线模拟1/2正弦的参数方程P(t)定义如下:
另一方面,该方程描述的曲线与真实1/2正弦有多大差异呢?下面就针对这个问题进行数值求解。
采用t = 0.0到1.0,步进值0.01,求解-PI/2到PI/2的每个点到正弦曲线的数值差异。
输出结果如下:
从输出结果分析可以看到,误差在-90度到0度为上浮,在0度到90度为下浮。
在-90度、0度和90度为最小误差0.000000,在-57.9度和57.9度达到最大误差为0.000768,基本上非常接近1/2正弦了。
以上,即为三阶贝塞尔曲线模拟1/2正弦的全部内容。
感谢Grapher和GeoGebra软件,使得方便排版文章中使用的公式和曲线。
根据贝塞尔曲线的知识,我们知道三阶贝塞尔曲线的参数方程如下,其中A、B、C、D为四个控制点坐标,P(t)表示曲线上的每一点。
因为要模拟1/2正弦,所以通过P(0)和P(1)的切线方向,应该按照下图所示位置安放。
其中AB为水平向左方向,DC为水平向右方向,并且线段长度|AB| = |DC| = h。
那么这个问题实际上,就转换为计算出合理的h值,使得曲线(原点)中点处的斜率为1。
根据P(t)定义,求得三阶贝塞尔曲线的导数为:
根据贝塞尔曲线的对称性,不难想出P(0.5)在原点处,代入公式即可求得:
代入四个控制点坐标A(-PI/2, -1),B(-PI/2 + h, 1),C(PI/2 - h, 1)和D(PI/2, 1),可以求解P'(0.5)的值如下:
根据正弦曲线在原点处的斜率为1可知,P'(0.5)表示的斜率为1,从而拟出下面方程:
从而求解出h的值为:
所以,可以最终求解出三阶贝塞尔曲线模拟1/2正弦的参数方程P(t)定义如下:
另一方面,该方程描述的曲线与真实1/2正弦有多大差异呢?下面就针对这个问题进行数值求解。
采用t = 0.0到1.0,步进值0.01,求解-PI/2到PI/2的每个点到正弦曲线的数值差异。
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <math.h> double bezier3(double a, double b, double c, double d, double t) { double nt = 1.0 - t; double nt2 = nt * nt; double nt3 = nt * nt * nt; double t2 = t * t; double t3 = t * t * t; return (a * nt3 + b * 3.0 * nt2 * t + c * 3.0 * nt * t2 + d * t3); } #define PI 3.1415926 int main() { double t, a; double d, e; double max_e = 0.0, min_e = 1.0; double x, y; double h = PI - 2.0; for(t = 0.0; t < 1.01; t+=0.01) { x = bezier3(-PI / 2.0, -PI / 2.0 + h, PI / 2.0 - h, PI / 2.0, t); y = bezier3(-1, -1, 1, 1, t); d = sin(x); e = y - d; a = x * 180.0 / 3.1415926; if(max_e < e) max_e = e; if(min_e > e) min_e = e; printf("%4.1f, %f\n", a, e); } printf("max_e = %f, min_e = %f\n", max_e, min_e); return 0; }
输出结果如下:
-90.0, -0.000000 -88.0, 0.000012 -86.1, 0.000046 -84.2, 0.000095 -82.2, 0.000155 -80.3, 0.000222 -78.4, 0.000293 -76.5, 0.000364 -74.6, 0.000433 -72.7, 0.000498 -70.8, 0.000559 -69.0, 0.000612 -67.1, 0.000659 -65.2, 0.000697 -63.4, 0.000727 -61.6, 0.000749 -59.7, 0.000762 -57.9, 0.000768 -56.1, 0.000766 -54.3, 0.000756 -52.4, 0.000741 -50.6, 0.000719 -48.8, 0.000692 -47.0, 0.000660 -45.3, 0.000625 -43.5, 0.000587 -41.7, 0.000547 -39.9, 0.000505 -38.2, 0.000462 -36.4, 0.000419 -34.6, 0.000376 -32.9, 0.000335 -31.1, 0.000294 -29.4, 0.000256 -27.6, 0.000220 -25.9, 0.000186 -24.2, 0.000155 -22.4, 0.000127 -20.7, 0.000102 -19.0, 0.000080 -17.2, 0.000061 -15.5, 0.000045 -13.8, 0.000032 -12.0, 0.000022 -10.3, 0.000014 -8.6, 0.000008 -6.9, 0.000004 -5.2, 0.000002 -3.4, 0.000001 -1.7, 0.000000 0.0, 0.000000 1.7, -0.000000 3.4, -0.000001 5.2, -0.000002 6.9, -0.000004 8.6, -0.000008 10.3, -0.000014 12.0, -0.000022 13.8, -0.000032 15.5, -0.000045 17.2, -0.000061 19.0, -0.000080 20.7, -0.000102 22.4, -0.000127 24.2, -0.000155 25.9, -0.000186 27.6, -0.000220 29.4, -0.000256 31.1, -0.000294 32.9, -0.000335 34.6, -0.000376 36.4, -0.000419 38.2, -0.000462 39.9, -0.000505 41.7, -0.000547 43.5, -0.000587 45.3, -0.000625 47.0, -0.000660 48.8, -0.000692 50.6, -0.000719 52.4, -0.000741 54.3, -0.000756 56.1, -0.000766 57.9, -0.000768 59.7, -0.000762 61.6, -0.000749 63.4, -0.000727 65.2, -0.000697 67.1, -0.000659 69.0, -0.000612 70.8, -0.000559 72.7, -0.000498 74.6, -0.000433 76.5, -0.000364 78.4, -0.000293 80.3, -0.000222 82.2, -0.000155 84.2, -0.000095 86.1, -0.000046 88.0, -0.000012 90.0, 0.000000 max_e = 0.000768, min_e = -0.000768
从输出结果分析可以看到,误差在-90度到0度为上浮,在0度到90度为下浮。
在-90度、0度和90度为最小误差0.000000,在-57.9度和57.9度达到最大误差为0.000768,基本上非常接近1/2正弦了。
以上,即为三阶贝塞尔曲线模拟1/2正弦的全部内容。
感谢Grapher和GeoGebra软件,使得方便排版文章中使用的公式和曲线。
相关文章推荐
- Python游戏引擎开发(一):序
- 常用的正则表达式归纳—JavaScript正则表达式
- IT职场人生系列之四:怎样写简历
- CSFB技术概述
- 开发完的思考
- 构造函数,哪些成员变量一定要通过初始化列表来初始化?
- uva 11275 - 3D Triangles(几何)
- iwi的模板
- Android简单练习(TableLayout)
- maven项目管理之-06-pom.xml说明
- Colours–颜色库,包含100种预定义的颜色和方法
- 友盟分享 -QQAPI- QQApi.m:250 param error: url is nil
- Linux程序包管理:rpm、yum、编译安装
- Intellij idea 中 JUnit 的简单配置
- Socket 异步
- hasOwnProperty方法,检索ajax响应对象的存储
- SQL Server 2008 R2创建定期自动备份任务
- JSON 入门
- Codeforces Beta Round #34 (Div. 2) C. Page Numbers
- 追求炉火纯青的技艺,极客-写给自己!