zoukankan
html css js c++ java
优化了的过关键点的光滑曲线拟合算法
这个是我一个数学老师(教授,数学高手,经常自己做算法)给我的例子,用于多个离散点拟合光滑曲线的,他优化了追赶法,这个例子适用于闭合和不闭合两种情况。当时由于工程情况,写的急,代码不好看,但是很好用。为了方便传递参数,我做了一个链表,用时候根据自己情况可以修改,核心算法不动即可。
class
CFoldPoint
{
public
:
double
X;
double
Y;
}
;
typedef CTypedPtrList CFoldPointList;
typedef CArray CDoubleArray;
//
三个函数,SPLine 调用另外两个。用时候直接调用SPLine函数,入口pList是已知离散点链表,pDestList是生成的点的链表。SM是在两个点中间插入点的数目,continue=0是采样点无规律,要求生成闭合曲线。1是采样点x坐标连续 2是y连续
void
ZG(CDoubleArray
*
A,CDoubleArray
*
B,CDoubleArray
*
C,CDoubleArray
*
G,
int
&
LOGI)
{
//
追赶法
register
long
I;
int
N;
N
=
A
->
GetSize();
if
(LOGI
==
0
)
{
(
*
C)[
0
]
=
(
*
C)[
0
]
/
(
*
B)[
0
];
for
(I
=
1
;I
{
(
*
B)[I]
=
(
*
B)[I]
-
(
*
A)[I]
*
(
*
C)[I
-
1
];
(
*
C)[I]
=
(
*
C)[I]
/
(
*
B)[I];
}
(
*
A)[
0
]
=
0
.;
(
*
C)[N
-
1
]
=
0
.;
LOGI
=
1
;
}
(
*
G)[
0
]
=
(
*
G)[
0
]
/
(
*
B)[
0
];
for
(I
=
1
;I
{
(
*
G)[I]
=
((
*
G)[I]
-
(
*
A)[I]
*
(
*
G)[I
-
1
])
/
(
*
B)[I];
}
for
(I
=
N
-
2
;I
>-
1
;I
--
)
//
DO 30 I=N-1,1,-1
{
(
*
G)[I]
=
(
*
G)[I]
-
(
*
C)[I]
*
(
*
G)[I
+
1
];
}
return
;
}
void
SPLine4(CDoubleArray
*
X,CDoubleArray
*
Y,
double
&
XI,
double
&
YI,CDoubleArray
*
A,CDoubleArray
*
B,CDoubleArray
*
C,CDoubleArray
*
G,
int
&
LOGI,
int
MD)
{
register
long
I;
double
W1,W2,H;
int
N
=
X
->
GetSize();
if
(LOGI
==
0
)
{
for
(I
=
1
;I
{
(
*
B)[I]
=
(
*
X)[I]
-
(
*
X)[I
-
1
];
(
*
C)[I]
=
((
*
Y)[I]
-
(
*
Y)[I
-
1
])
/
(
*
B)[I];
}
for
(I
=
1
;I
{
(
*
A)[I]
=
(
*
B)[I]
+
(
*
B)[I
+
1
];
(
*
G)[I]
=
6
.
*
((
*
C)[I
+
1
]
-
(
*
C)[I])
/
(
*
A)[I];
(
*
A)[I]
=
(
*
B)[I]
/
(
*
A)[I];
}
for
(I
=
1
;I
{
(
*
C)[I]
=
1
.
-
(
*
A)[I];
(
*
B)[I]
=
2
.;
}
(
*
B)[
0
]
=
2
.;
(
*
B)[N
-
1
]
=
2
.;
if
(MD
==
3
)
{
(
*
C)[
0
]
=-
1
.;
(
*
A)[N
-
1
]
=-
1
.;
(
*
A)[
0
]
=
0
.;
(
*
C)[N
-
1
]
=
0
.;
}
ZG(A,B,C,G,LOGI);
}
for
(I
=
1
;I
{
if
(XI
>=
(
*
X)[I
-
1
]
&&
XI
<=
(
*
X)[I])
//
GE LE
{
H
=
(
*
X)[I]
-
(
*
X)[I
-
1
];
W1
=
(
*
X)[I]
-
XI;
W2
=
XI
-
(
*
X)[I
-
1
];
YI
=
W1
*
W1
*
W1
*
(
*
G)[I
-
1
]
/
6
.
/
H;
YI
=
YI
+
W2
*
W2
*
W2
*
(
*
G)[I]
/
6
.
/
H;
YI
=
YI
+
W1
*
((
*
Y)[I
-
1
]
-
(
*
G)[I
-
1
]
*
H
*
H
/
6
.)
/
H;
YI
=
YI
+
W2
*
((
*
Y)[I]
-
(
*
G)[I]
*
H
*
H
/
6
.)
/
H;
}
}
}
void
SPLine(CFoldPointList
*
pList,CFoldPointList
*
pDestList,
int
SM,
int
Continue
=
0
)
{
CFoldPoint
*
pFoldHead,
*
pFoldTail;
POSITION pos;
CDoubleArray A,B,C,G,X,Y,T;
double
XI,YI,XX,YY;
register
long
i;
long
N;
int
LOGI;
long
RealSM;
long
Bei,Yu;
CFoldPoint
*
pFold;
file:
//
赋初值
N
=
pList
->
GetCount();
A.SetSize(N);
B.SetSize(N);
C.SetSize(N);
G.SetSize(N);
X.SetSize(N);
Y.SetSize(N);
T.SetSize(N);
RealSM
=
(N
-
1
)
*
SM
+
N;
pos
=
pList
->
GetHeadPosition();
for
(i
=
0
;i
{
pFold
=
pList
->
GetNext(pos);
X[i]
=
pFold
->
X;
Y[i]
=
pFold
->
Y;
}
pFoldHead
=
pList
->
GetHead();
pFoldTail
=
pList
->
GetTail();
if
(Continue
==
0
)
//
pFoldHead->X==pFoldTail->X && pFoldHead->Y==pFoldTail->Y)
{ file:
//
闭合
T[
0
]
=
0
;
for
(i
=
0
;i
{
T[i
+
1
]
=
T[i]
+
CalculateDistance(X[i],Y[i],X[i
+
1
],Y[i
+
1
])
+
0.000000001
;
}
LOGI
=
0
;
YI
=
0
;
for
(i
=
0
;i
{
Bei
=
i
/
(SM
+
1
);
Yu
=
i
%
(SM
+
1
);
if
(Yu
!=
0
)
{
XI
=
T[Bei]
+
(T[Bei
+
1
]
-
T[Bei])
/
(SM
+
1
)
*
Yu;
SPLine4(
&
T,
&
Y,XI,YI,
&
A,
&
B,
&
C,
&
G,LOGI,
3
);
YY
=
YI;
//
+Y[Bei];
}
else
{
YY
=
Y[Bei];
}
pFold
=
new
CFoldPoint;
pFold
->
Y
=
YY;
pDestList
->
AddTail(pFold);
}
LOGI
=
0
;
YI
=
0
;
pos
=
pDestList
->
GetHeadPosition();
for
(i
=
0
;i
{
Bei
=
i
/
(SM
+
1
);
Yu
=
i
%
(SM
+
1
);
if
(Yu
!=
0
)
{
XI
=
T[Bei]
+
(T[Bei
+
1
]
-
T[Bei])
/
(SM
+
1
)
*
Yu;
SPLine4(
&
T,
&
X,XI,YI,
&
A,
&
B,
&
C,
&
G,LOGI,
3
);
YY
=
YI;
//
+X[Bei];
}
else
{
YY
=
X[Bei];
}
pFold
=
pDestList
->
GetNext(pos);
pFold
->
X
=
YY;
}
}
else
if
(Continue
==
1
)
{
file:
//
x连续
LOGI
=
0
;
YI
=
0
;
for
(i
=
0
;i
{
Bei
=
i
/
(SM
+
1
);
Yu
=
i
%
(SM
+
1
);
if
(Yu
!=
0
)
{
XI
=
X[Bei]
+
(X[Bei
+
1
]
-
X[Bei])
/
(SM
+
1
)
*
Yu;
SPLine4(
&
X,
&
Y,XI,YI,
&
A,
&
B,
&
C,
&
G,LOGI,
3
);
XX
=
XI;
YY
=
YI;
}
else
{
XX
=
X[Bei];
YY
=
Y[Bei];
}
pFold
=
new
CFoldPoint;
pFold
->
X
=
XX;
pFold
->
Y
=
YY;
pDestList
->
AddTail(pFold);
}
}
else
{
file:
//
y连续
LOGI
=
0
;
YI
=
0
;
for
(i
=
0
;i
{
Bei
=
i
/
(SM
+
1
);
Yu
=
i
%
(SM
+
1
);
if
(Yu
!=
0
)
{
XI
=
Y[Bei]
+
(Y[Bei
+
1
]
-
Y[Bei])
/
(SM
+
1
)
*
Yu;
SPLine4(
&
Y,
&
X,XI,YI,
&
A,
&
B,
&
C,
&
G,LOGI,
3
);
XX
=
YI;
YY
=
XI;
}
else
{
XX
=
X[Bei];
YY
=
Y[Bei];
}
pFold
=
new
CFoldPoint;
pFold
->
X
=
XX;
pFold
->
Y
=
YY;
pDestList
->
AddTail(pFold);
}
}
return
;
}
查看全文
相关阅读:
OpenOffice 在 Linux 下安装使用
LINUX环境使用rpm命令安装gcc
用shell脚本执行mysql脚本
CentOS 7下用firewall-cmd控制端口与端口转发详解(转载)
Hive字段中文注释乱码解决办法
真正从零开始,TensorFlow详细安装入门图文教程!
九、Oracle SQL(优化专题&分表分区)
八、Oracle SQL(聚合函数&标量函数)
七、Oracle SQL(Oracle 定时任务基础)
六、Oracle SQL(游标&RECORD&存过、游标、RECORD整合)
原文地址:https://www.cnblogs.com/yunbo/p/1155100.html
最新文章
Android的appium实例
Appium入门示例(Java)
appium 环境搭建
[Java] Eclipse下导入外部jar包的3种方式
[Selenium] 处理表格(python + java)
python 多模块文件共享变量
appium 支持输入中文
VC++ 学习笔记(六):简单C++
VC++ 学习笔记(五):跨平台是正确打开C++的方式吗?
VC++ 学习笔记(四):停止还是暂停这个系列
热门文章
C#高阶与初心:(二)P/Invoke平台调用
Web重温系列(三):OracleDependency实现监听数据库变化
Web重温系列(二):SQLite+EF6实现本地化存储
Web重温系列(一):利用寄宿于IIS的WCF序列化文件
Python学习小组微信群公告页面
C#高阶与初心:(一)List.Add添加的到底是什么?
用route命令添加永久路由
[转载]MySQL中dblink的实现
海事局 与 港航局 的区别
git pull 设置git记住用户和密码
Copyright © 2011-2022 走看看