N个点的连接问题

yangyzqo 2005-12-11 12:08:09
已知二维平面中有N个点,如何用平滑的曲线把它们连接起来?
为了更具有通用性,如何动态的根据几个点,用曲线把它们连接起来呢?
最用可以用MFC实现,谢谢!
...全文
245 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
寻开心 2005-12-13
  • 打赏
  • 举报
回复
无论是逆合还是插值,都是要指定这n个点的顺序的
yangyzqo 2005-12-13
  • 打赏
  • 举报
回复
的确条件有些笼统:
加强条件:

1,点 CPoint(x, y)
2.范围:
x为正整数
y为 MIN <= y, MAX >= y 的整数,
(注:MIN, MAX为定义的宏,如:
#define MIN 0
#define MAX 100 )
3 要求
  随机的产生N个点, 对这N个点做一点的处理,让其满足上面的范围条件,然后用平滑的曲线把这N个点连接起来,曲线必须经过每一个点
mmmcd 2005-12-13
  • 打赏
  • 举报
回复
以前编的MFC实现(片断)

void CBezierView::OnLButtonUp(UINT nFlags, CPoint point)
{
pDC=this->GetDC();
p.push_back(point);
if(p.size()>1)
{
pDC->MoveTo(latest_point);
pDC->LineTo(point);
}
else
{
//pDC->MoveTo(point);
}
pDC->SetPixel(point,RGB(255,0,0));
num_click++;
if(num_click==4||num_click>4&&(num_click-4)%3==0)
{
pDC=this->GetDC();
DrawBezier(pDC);
//num_click=0;
point.x=point.x-latest_point.x+point.x;
point.y=point.y-latest_point.y+point.y;
p.push_back(point);
pDC->MoveTo(latest_point);
pDC->LineTo(point);
// latest_point=point;
pDC->SetPixel(point,RGB(255,0,0));
num_click++;
//OnLButtonUp(0,point);
}
latest_point=point;
CView::OnLButtonUp(nFlags, point);
}

void CBezierView::DrawBezier(CDC *pDC)
{
int i;
double x,y;
double b[4];
for(i=0;i+3<p.size();i+=3)
//i=num_click-4;
{
for(t=0.0;t<1.0;t+=0.001)
{
b[0]=(1-t)*(1-t)*(1-t);
b[1]=3*t*(1-t)*(1-t);
b[2]=3*t*t*(1-t);
b[3]=t*t*t;
x=b[0]*p[i+0].x+b[1]*p[i+1].x+b[2]*p[i+2].x+b[3]*p[i+3].x;
y=b[0]*p[i+0].y+b[1]*p[i+1].y+b[2]*p[i+2].y+b[3]*p[i+3].y;
pDC->SetPixel((int)(x+0.5),(int)(y+0.5),RGB(255,0,0));
}
}
}
xiaoxiaofei 2005-12-13
  • 打赏
  • 举报
回复
还要确定连续的阶数,比如一阶连续、二阶连续等
其次就是,是否要通过这些点,还是仅仅是逼近这些点
Kvci 2005-12-13
  • 打赏
  • 举报
回复
//java代码,自己改
public int cni(int i, int n) { //要用的函数
int j, N = 1, Nn = 1, Ni = 1, Nni = 1;
for (j = n; j >= 1; j--) {
Nn = Nn * j;
}
for (j = i; j >= 1; j--) {
Ni = Ni * j;
}
for (j = n - i; j >= 1; j--) {
Nni = Nni * j;
}
N = Nn / (Ni * Nni);
return N;
}

public void BezierSpline(int n, int m, Graphics g) {
//参数n是点的个数-1,如果是三个点就固定是2
//参数m是平滑系数,越大越平滑
//参数g是JAVA里的画布
//画一条平滑线连接nx[3],ny[3]三点
//nx[3]保存三点的x坐标
//ny[3]保存三点的y坐标
int k, i, x1 = 0, y1 = 0, x2, y2;
double x0, y0, t, blend;

for (k = 0; k <= m; k++) {
t = (double) k / m;
x0 = Math.pow( (1 - t), n) * nx[0];//Math.pow相当于pow()
y0 = Math.pow( (1 - t), n) * ny[0];
for (i = 1; i < n; i++) {
blend = cni(i, n) * Math.pow( (1 - t), (n - i)) * Math.pow(t, i);
x0 += blend * nx[i];
y0 += blend * ny[i];
}
x0 += Math.pow(t, n) * nx[n];
y0 += Math.pow(t, n) * ny[n];
x2 = (int) x0;
y2 = (int) y0;
if (k > 0) {
g.drawLine(x1, y1, x2, y2);//画线部分,自己修改
}
x1 = x2;
y1 = y2;
}
}
有了以上函数,构造若干个三点就可以平滑了
不过效果可能不太好
假设有N点
最好是这样构造三点:
第一点为p[i-1]与p[i]的中点
第二点为p[i]
第三点为p[i]与p[i+1]的中点
这样的平滑效果更好
yangyzqo 2005-12-12
  • 打赏
  • 举报
回复
太简单了?
哦,那能不能给一个解决方案参考一下呀?
谢谢
寻开心 2005-12-12
  • 打赏
  • 举报
回复
支持楼上的:
必须经过顶点用插值
不必经过顶点用逆合
xiaoxiaofei 2005-12-12
  • 打赏
  • 举报
回复
因为太简单,所以他们都不来,我来赚点分:

你可以看看图形处理的书籍,或者数值算法的书籍也行;
这个问题是曲线插值或者拟合,多项式插值、贝塞尔曲线、样条曲线等等都可以满足。资料网上随便搜。
yangyzqo 2005-12-12
  • 打赏
  • 举报
回复
不会吧?一天都过去了,怎么还没有一个人指点一下呢??
寻开心 2005-12-12
  • 打赏
  • 举报
回复
不是太简单了,是你的条件太笼统了
插值也好,逆合也好,方法很多
不同的方法,需要的条件不同,适应的环境不同
建议找 数值逼近 之类的书看看
下面是几个相关的连接,可以参考参考
http://mlsx.xplore.cn/index.php?job=art&articleid=a_20041019_001122
http://www.nar-associates.com/nurbs/c_code.html
http://www.math.ubc.ca/~cass/gfx/bezier.html
yangyzqo 2005-12-11
  • 打赏
  • 举报
回复
自己UP,还请各位指点一下,谢谢

33,028

社区成员

发帖
与我相关
我的任务
社区描述
数据结构与算法相关内容讨论专区
社区管理员
  • 数据结构与算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧