社区
C语言
帖子详情
求Hermite曲线算法
fatcatman
2004-05-06 09:24:01
求Hermite曲线算法,谢谢
...全文
1056
13
打赏
收藏
求Hermite曲线算法
求Hermite曲线算法,谢谢
复制链接
扫一扫
分享
转发到动态
举报
AI
作业
写回复
配置赞助广告
用AI写文章
13 条
回复
切换为时间正序
请发表友善的回复…
发表回复
打赏红包
liushuaiboy
2004-05-06
打赏
举报
回复
没听过,楼主,这是作甚么地?
Johnnyxy
2004-05-06
打赏
举报
回复
热,顶你,给我分!
fatcatman
2004-05-06
打赏
举报
回复
顶
fatcatman
2004-05-06
打赏
举报
回复
顶
freefalcon
2004-05-06
打赏
举报
回复
因为屏幕坐标系的y轴正方向是向下的
你将y去负值,在考虑加上一个偏移量(比如屏幕的高度)就可以了
fatcatman
2004-05-06
打赏
举报
回复
请问用这void DrawHermiteCurve画出来的图和实际想要的上下是颠倒的啊?这是为什么啊?
fatcatman
2004-05-06
打赏
举报
回复
请问用这个算法画出来的图和实际想要的上下是颠倒的啊?这是为什么啊?
#define Iterative 24 /* 曲线仿真的线数(必须小于32) */
#define Iterative2 (Iterative*Iterative)
#define Iterative3 (Iterative2*Iterative)
void DrawHermiteCurve(int x1,int y1,int x2,int y2,int xr1,int yr1,
int xr2,int yr2)
{
/* ------------------------------------------------------------
作用:画出Hermite曲线
输入:x1,y1,x2,y2 = 曲线端点
xr1,yr1,xr2,yr2 = 曲线两参考向量
作者:邱奕南 Chi'u I-Nan
------------------------------------------------------------ */
int i, oldx, oldy, m1, m2, m3, m4, x, y, k1, k2;
oldx = x1;
oldy = y1;
m1 = Iterative3;
m2 = m3 = m4 = 0;
for (i=0; i<Iterative; i++) /* 用Iterative条直线仿真 */
{
k1 = (i << 1) + 1;
k2 = (k1+i)*i + k1;
m4 += (k2 -= (k1 *= Iterative));
m3 += (k1 = k2 - k1) + Iterative2;
m2 -= (k2 += k1);
m1 += k2;
x = (int) (((long) x1*m1 + (long) x2*m2 + (long) xr1*m3 +
(long) xr2*m4) / Iterative3);
y = (int) (((long) y1*m1 + (long) y2*m2 + (long) yr1*m3 +
(long) yr2*m4) / Iterative3);
DrawLine(oldx,oldy,x,y);
oldx = x;
oldy = y;
}
}
void DrawBezierCurve(int x1,int y1,int x2,int y2,int xr1,int yr1,
int xr2,int yr2)
{
/* ------------------------------------------------------------
作用:画出Bezier曲线
输入:x1,y1,x2,y2 = 曲线端点
xr1,yr1,xr2,yr2 = 曲线两参考点
作者:邱奕南 Chi'u I-Nan
------------------------------------------------------------ */
DrawHermiteCurve(x1,y1,x2,y2,3*(xr1-x1),3*(yr1-y1),3*(x2-xr2),3*(y2-yr2));
}
junnyfeng
2004-05-06
打赏
举报
回复
参考
fatcatman
2004-05-06
打赏
举报
回复
谢谢了,我试一下!
freefalcon
2004-05-06
打赏
举报
回复
多谢楼上,我也收藏一下此资料
happyasen
2004-05-06
打赏
举报
回复
发信人: william@cis_nctu (何陋居主), 信区: programming
标 题: [转载] Hermite 与 Bezier 曲线的绘制
发信站: 交大资科_BBS (May 25 00:32:41 1995)
转信站: cis_nctu
From: Chi'u I-Nan * Area: 90 C 语言
To: All Date: 03 May 95 22:37:26
Subj: Hermite 与 Bezier 曲线的绘制
**********************************************************************
* Hermite与Bezier曲线绘制方法研究 *
* 作者:邱奕南 (Chi'u I-Nan) *
* 版权声明:以下文章内容本人仅同意供BBS 站上流传学习,但必须完整流传 *
* (含版权声明及程序),其余权利一概保留。任何未经本人同意 *
* ,将本文贩卖、刊登、节录、或其它一切侵害本人著作权之行为 *
* 者,皆需负担刑事责任及民事赔偿责任。 *
**********************************************************************
Hermite及Bezier曲线为三度空间曲线的常用表示法,以下我们先说明一
下这两个曲线的定义:
1.Hermite曲线
Hermite曲线为给定两端点及两端点向量所得的三次曲线。令三次曲线:
3 2
x(t) = Ax * t + Bx * t + Cx * t + d
3 2
y(t) = Ay * t + By * t + Cy * t + d
且令给定的两端点为(x1,y1)、(x2,y2),以及两端点向量(xr1,yr1)、(xr2,yr2),
则:
x(0) = x1, y(0) = y1
x(1) = x2, y(1) = y2
x'(0) = xr1, y'(0) = yr1
x'(1) = xr2, y'(1) = yr2
绘出(x(t),y(t)),0<=t<=1,即为Hermite曲线。
2.Bezier曲线
Bezier曲线为给定两端点及另两参考点所得的三次曲线,它可说是Hermite
曲线的另一种表示方式。假设两端点为P1、P2,以及两参考点Pr1、Pr2,则
Bezier曲线换算成Hermite曲线的方式为:
R1 = 3*(Pr1-P1)
R2 = 3*(P2-Pr2)
R1、R2即为Hermite曲线的两端点向量。
由于Bezier曲线和Hermite曲线可以说是相同的,因此以下之说明我们便以
Hermite曲线为主。由Hermite曲线的定义,首先我们必须求出Ax,Bx...等值。
由定义中的条件:
x(0) = x1, x(1) = x2, x'(0) = xr1, x'(1) = xr2
以及
2
x'(t) = 3 * Ax * t + 2 * Bx * t + Cx
可得:
┌ 0 0 0 1 ┐┌ Ax ┐ ┌ x1 ┐
│ 1 1 1 1 ││ Bx │=│ x2 │
│ 0 0 1 0 ││ Cx │ │ xr1 │
└ 3 2 1 0 ┘└ Dx ┘ └ xr2 ┘
解之得:
┌ Ax ┐ ┌ 2 -2 1 1 ┐┌ x1 ┐
│ Bx │=│ -3 3 -2 1 ││ x2 │
│ Cx │ │ 0 0 1 0 ││ xr1 │
└ Dx ┘ └ 1 0 0 0 ┘└ xr2 ┘
因此
x(t) = (2*t^3 - 3*t^2 + 1) * x1 + (-2*t^3 + 3*t^2) * x2 +
(t^3 - 2*t^2 + t) * xr1 + (t^3 - t^2) * xr2
同理
y(t) = (2*t^3 - 3*t^2 + 1) * y1 + (-2*t^3 + 3*t^2) * y2 +
(t^3 - 2*t^2 + t) * yr1 + (t^3 - t^2) * yr2
上述的公式中,由于t的值是介于0与1之间,这对于我们在实际绘图上较不
方便,而且运算速度也比较慢。因此假设我们以n条直线来仿真Hermite曲线,
则我们必须将t值化成整数,使它成为0<=t<=n(注意n条连续直线需有n+1个点)。
令i=n*t代入上述公式,化简后可得:
x(i) = (m1*x1 + m2*x2 + m3*xr1 + m4*xr2) / n^3
y(i) = (m1*y1 + m2*y2 + m3*yr1 + m4*yr2) / n^3
其中
m1 = 2*i^3 - 3*n*i^2 + n^3 , 0 <= i <= n
m2 = -2*i^3 + 3*n*i^2
m3 = i^3 - 2*n*i^2 + n^2*i
m4 = i^3 - n*i^2
如此我们便能很方便地求出仿真直线的各端点。然而上述公式中的乘法仍相当
多,对于m1~m4的计算上至少需5次乘法、2次移位乘法和6次加法(或4次乘法、
3次移位乘法和7次加法),在计算上仍然会浪费相当多时间(PC上的乘法约为
加法的近20倍,移位乘法则和加法相当),因此有必要再予以化简。如何简化
呢?由上述公式可发现,主要的乘法来自于i^3的计算,因此欲将之简化的最简
单的方式便是由前一个m1~m4值来求得后一个m1~m4值,藉此消减掉这个三次
方值的运算:
m1(i+1) = m1(i) + 6*i^2 + 6*i + 2 - 3*n*(2*i+1)
m2(i+1) = m2(i) - 6*i^2 - 6*i - 2 + 3*n*(2*i+1)
m3(i+1) = m3(i) + 3*i^2 + 3*i + 1 - 2*n*(2i+1) + n^2
m4(i+1) = m4(i) + 3*i^2 + 3*i + 1 - n*(2*i+1)
现在便是要化简各式中后面的计算项次。由于这些项次有相当多的重复,故可
将之写成:
m1(i+1) = m1(i) + a
m2(i+1) = m2(i) - a
m3(i+1) = m3(i) + d - c + n^2
m4(i+1) = m4(i) + d
a = 2*b - 3*c
b = 3*i^2 + 3*i + 1
c = n*(2*i+1)
d = b-c
再进一步简化为:
e = 2*i + 1
c = n*e
b = 3*i^2 + 3*i + 1
= (3*i+1)*i + (2*i+1)
= (e+i)*i + e
整理一下成为(依计算顺序):
e = 2*i + 1
b = (e+i)*i + e
c = n*e
d = b-c
m4 = m4 + d
f = d-c
m3 = m3 + f + n^2
a = d + f
m2 = m2 - a
m1 = m1 + a
共计2次乘法、1次移位乘法和11次加法,等于是以两次加法代替了两次乘法,
其速度必然较快。记得m1~m4的初值为:
m1(0) = n^3
m2(0) = m3(0) = m4(0) = 0
接下来我们要探讨一下模拟线数n的问题。倒底取多少模拟线数较为恰当?
采用的仿真线数太少,曲线将不够平滑,但若模拟线数太多,曲线绘制速度又
会太慢。据作者实际的测试,一般取n=20以上曲线便已相当平滑,但对于弯度
太大的曲线,其转折处仍约略可见,不过并不严重。由于在绘制曲线时,大都
以整数来运算(为求速度),因此仿真线数最好不要超出32,以避免运算结果
超出整数运算的值域。以下便是Hermite曲线和Bezier曲线的绘制程式:
#define Iterative 24 /* 曲线仿真的线数(必须小于32) */
#define Iterative2 (Iterative*Iterative)
#define Iterative3 (Iterative2*Iterative)
void DrawHermiteCurve(int x1,int y1,int x2,int y2,int xr1,int yr1,
int xr2,int yr2)
{
/* ------------------------------------------------------------
作用:画出Hermite曲线
输入:x1,y1,x2,y2 = 曲线端点
xr1,yr1,xr2,yr2 = 曲线两参考向量
作者:邱奕南 Chi'u I-Nan
------------------------------------------------------------ */
int i, oldx, oldy, m1, m2, m3, m4, x, y, k1, k2;
oldx = x1;
oldy = y1;
m1 = Iterative3;
m2 = m3 = m4 = 0;
for (i=0; i<Iterative; i++) /* 用Iterative条直线仿真 */
{
k1 = (i << 1) + 1;
k2 = (k1+i)*i + k1;
m4 += (k2 -= (k1 *= Iterative));
m3 += (k1 = k2 - k1) + Iterative2;
m2 -= (k2 += k1);
m1 += k2;
x = (int) (((long) x1*m1 + (long) x2*m2 + (long) xr1*m3 +
(long) xr2*m4) / Iterative3);
y = (int) (((long) y1*m1 + (long) y2*m2 + (long) yr1*m3 +
(long) yr2*m4) / Iterative3);
DrawLine(oldx,oldy,x,y);
oldx = x;
oldy = y;
}
}
void DrawBezierCurve(int x1,int y1,int x2,int y2,int xr1,int yr1,
int xr2,int yr2)
{
/* ------------------------------------------------------------
作用:画出Bezier曲线
输入:x1,y1,x2,y2 = 曲线端点
xr1,yr1,xr2,yr2 = 曲线两参考点
作者:邱奕南 Chi'u I-Nan
------------------------------------------------------------ */
DrawHermiteCurve(x1,y1,x2,y2,3*(xr1-x1),3*(yr1-y1),3*(x2-xr2),3*(y2-yr2));
}
* 青衫诗客 -- 小邱 *
-- Via 中文银版快信 V2.28C
! Origin: 档案货柜, 欢迎您来挖宝, 28800 BPS, 04-230-2080; (90:2010/622)
________________________________________
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
≡ 何陋居 ≡ 中学生以伏案读书为主, 大学生则应起而高瞻远瞩。 Whitehead.
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
freefalcon
2004-05-06
打赏
举报
回复
http://bbs.ee.ntu.edu.tw/boards/Programming/14/7.html
我这里显示有乱码,不过程序还是比较清楚的
1.HermiteΡ絬
HermiteΡ絬倒﹚ㄢ狠翴のㄢ狠翴秖┮眔ΩΡ絬ΩΡ絬
3 2
x(t) = Ax * t + Bx * t + Cx * t + d
3 2
y(t) = Ay * t + By * t + Cy * t + d
倒﹚ㄢ狠翴(x1,y1)(x2,y2)のㄢ狠翴秖(xr1,yr1)(xr2,yr2)
玥
x(0) = x1, y(0) = y1
x(1) = x2, y(1) = y2
x'(0) = xr1, y'(0) = yr1
x'(1) = xr2, y'(1) = yr2
酶(x(t),y(t))0<=t<=1HermiteΡ絬
#define Iterative 24 /* Ρ絬家览絬计(ゲ斗32) */
#define Iterative2 (Iterative*Iterative)
#define Iterative3 (Iterative2*Iterative)
void DrawHermiteCurve(int x1,int y1,int x2,int y2,int xr1,int yr1,
int xr2,int yr2)
{
/* ------------------------------------------------------------
ノ礶HermiteΡ絬
块x1,y1,x2,y2 = Ρ絬狠翴
xr1,yr1,xr2,yr2 = Ρ絬ㄢ把σ秖
玭 Chi'u I-Nan
------------------------------------------------------------ */
int i, oldx, oldy, m1, m2, m3, m4, x, y, k1, k2;
oldx = x1;
oldy = y1;
m1 = Iterative3;
m2 = m3 = m4 = 0;
for (i=0; i<Iterative; i++) /* ノIterative兵絬家览 */
{
k1 = (i << 1) + 1;
k2 = (k1+i)*i + k1;
m4 += (k2 -= (k1 *= Iterative));
m3 += (k1 = k2 - k1) + Iterative2;
m2 -= (k2 += k1);
m1 += k2;
x = (int) (((long) x1*m1 + (long) x2*m2 + (long) xr1*m3 +
(long) xr2*m4) / Iterative3);
y = (int) (((long) y1*m1 + (long) y2*m2 + (long) yr1*m3 +
(long) yr2*m4) / Iterative3);
DrawLine(oldx,oldy,x,y);
oldx = x;
oldy = y;
}
}
fatcatman
2004-05-06
打赏
举报
回复
画曲线的一个算法
He
rmi
te
曲线
代码-
曲线
平滑代码-He
rmi
te
曲线
算法
描述-
曲线
平滑python代码
这是一份Python代码,用于生成三次He
rmi
te
曲线
,或者用于
曲线
平滑,代码逻辑清晰,简单易用。主要的He
rmi
te
功能代码封装成函数,可以很方便地调用,另外还编写一段测试代码,方便初学者充分理解如何去使用这个函数。一共编写了三个he
rmi
te
平滑函数,第一个是两点he
rmi
te
平滑,根据两点坐标以及两点的切线向量,生成两点之间的he
rmi
te
平滑
曲线
;第二个是多点he
rmi
te
平滑,需要输入三点以上的坐标以及相应的坐标点切线向量,生成多控制点的he
rmi
te
平滑
曲线
;第三个是多点自动he
rmi
te
平滑,只需要输入三个以上的坐标点,各坐标点的切线向量自动生成,然后在生成平滑后的
曲线
。本
算法
代码支持二维和三维的坐标点输入,并且可以生成闭合的和非闭合的he
rmi
te
平滑
曲线
。另外还附有详细对的He
rmi
te
算法
推导链接,让用户可以愉快地研究这个
算法
的底层数学公式。
He
rmi
te
曲线
glut 实现的He
rmi
te
曲线
c++代码
He
rmi
te
曲线
生成
算法
He
rmi
te
曲线
生成
算法
参数说明: (x01,y11)是点(x0,x1)的参数导数 (y01,y11)是点(y0,y1)的参数导数 例如:He
rmi
tCurve(50,50,200,100,200,100,-200,200,6)
He
rmi
te
曲线
Bresenham直线
在VS 2008上有opencv配置可运行 MFC单文档设计 有多种直线、
曲线
画法,园、椭圆,图形变换,裁剪,填充等
三次He
rmi
te
样条
曲线
算法
VC++ 计算机图形学 三次He
rmi
te
样条
曲线
算法
C语言
70,021
社区成员
243,263
社区内容
发帖
与我相关
我的任务
C语言
C语言相关问题讨论
复制链接
扫一扫
分享
社区描述
C语言相关问题讨论
社区管理员
加入社区
获取链接或二维码
近7日
近30日
至今
加载中
查看更多榜单
社区公告
暂无公告
试试用AI创作助手写篇文章吧
+ 用AI写文章