100分求助:图像算法高手 如何用平滑曲线连接多个点?

walkerzhou 2005-08-20 09:12:17
新接到公司任务:
根据给定的500个点,在屏幕上连接成平滑曲线。
请高手指点!
...全文
1488 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
malingxian 2005-08-20
  • 打赏
  • 举报
回复
C#(大小写可能有笔误):
//定义Point数组
Point[] ppoints = new point[500]{}
//将这500个点值存放到这个ppoints数组中,过程略......
ppoints[0].x=...:ppoints[0].y=...
...........
ppoints[n].x=...:ppoints[n].y=...
...........
ppoints[499].x=...:ppoints[499].y=...

//绘制平滑曲线
e.Grapjocs.SmoothingMode = Drawing2D.SmoothingMode.AntiAlias //消除锯齿
e.Graphics.(Drawing.Pens.Red, ppoints) //用红色绘制此平滑线条
malingxian 2005-08-20
  • 打赏
  • 举报
回复
楼上的几种方法都没必要啊,直接用DrawCurve方法即可[VB.NET代码,C#类似]:

'在要绘制的对象上绘制平滑的曲线:
Private Sub Form_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles MyBase.Paint
'定义Point数组
dim ppoints as point() = new point(499){}
'将这500个点值存放到这个ppoints数组中,过程略......
ppoints(0).x=...:ppoints(0).y=...
...........
ppoints(n).x=...:ppoints(n).y=...
...........
ppoints(499).x=...:ppoints(499).y=...

'绘制平滑曲线
e.Grapjocs.SmoothingMode = Drawing2D.SmoothingMode.AntiAlias '消除锯齿
e.Graphics.(Drawing.Pens.Red, ppoints) '用红色绘制此平滑线条
End Sub
Macosx 2005-08-20
  • 打赏
  • 举报
回复
实在对不起 我自己记错了 Bezier是不能经过所有的点的 当然自己加一些辅助点能达到目的 但显然麻烦 用Hermite插值方法也可以 但也麻烦
用上边几位提到的DrawCurve 这是Programming Windows with C#中使用DrawCurve的范例
//----------------------------------------------
// CanonicalSpline.cs ?2001 by Charles Petzold
//----------------------------------------------
using System;
using System.Drawing;
using System.Windows.Forms;

class CanonicalSpline: Form
{
protected Point[] apt = new Point[4];
protected float fTension = 0.5f;

public static void Main()
{
Application.Run(new CanonicalSpline());
}
public CanonicalSpline()
{
Text = "Canonical Spline";
BackColor = SystemColors.Window;
ForeColor = SystemColors.WindowText;
ResizeRedraw = true;

ScrollBar scroll = new VScrollBar();
scroll.Parent = this;
scroll.Dock = DockStyle.Right;
scroll.Minimum = -100;
scroll.Maximum = 109;
scroll.SmallChange = 1;
scroll.LargeChange = 10;
scroll.Value = (int) (10 * fTension);
scroll.ValueChanged += new EventHandler(ScrollOnValueChanged);

OnResize(EventArgs.Empty);
}
void ScrollOnValueChanged(object obj, EventArgs ea)
{
ScrollBar scroll = (ScrollBar) obj;

fTension = scroll.Value / 10f;

Invalidate(false);
}
protected override void OnResize(EventArgs ea)
{
base.OnResize(ea);

int cx = ClientSize.Width;
int cy = ClientSize.Height;

apt[0] = new Point( cx / 4, cy / 2);
apt[1] = new Point( cx / 2, cy / 4);
apt[2] = new Point( cx / 2, 3 * cy / 4);
apt[3] = new Point(3 * cx / 4, cy / 2);
}
protected override void OnMouseDown(MouseEventArgs mea)
{
Point pt;

if (mea.Button == MouseButtons.Left)
{
if (ModifierKeys == Keys.Shift)
pt = apt[0];
else if (ModifierKeys == Keys.None)
pt = apt[1];
else
return;
}
else if (mea.Button == MouseButtons.Right)
{
if (ModifierKeys == Keys.None)
pt = apt[2];
else if (ModifierKeys == Keys.Shift)
pt = apt[3];
else
return;
}
else
return;

Cursor.Position = PointToScreen(pt);
}
protected override void OnMouseMove(MouseEventArgs mea)
{
Point pt = new Point(mea.X, mea.Y);

if (mea.Button == MouseButtons.Left)
{
if (ModifierKeys == Keys.Shift)
apt[0] = pt;
else if (ModifierKeys == Keys.None)
apt[1] = pt;
else
return;
}
else if (mea.Button == MouseButtons.Right)
{
if (ModifierKeys == Keys.None)
apt[2]= pt;
else if (ModifierKeys == Keys.Shift)
apt[3] = pt;
else
return;
}
else
return;

Invalidate();
}
protected override void OnPaint(PaintEventArgs pea)
{
Graphics grfx = pea.Graphics;
Brush brush = new SolidBrush(ForeColor);

grfx.DrawCurve(new Pen(ForeColor), apt, fTension);

grfx.DrawString("Tension = " + fTension, Font, brush, 0, 0);

for (int i = 0; i < 4; i++)
grfx.FillEllipse(brush, apt[i].X - 3, apt[i].Y - 3, 7, 7);
}
}
walkerzhou 2005-08-20
  • 打赏
  • 举报
回复
最小二乘法 计算出方程,根据方程得到连续的X/Y值

能否更具体一些呢?比如 如何运用?
The_Gathering 2005-08-20
  • 打赏
  • 举报
回复
最小二乘法 计算出方程,根据方程得到连续的X/Y值,即可画出曲线
walkerzhou 2005-08-20
  • 打赏
  • 举报
回复
补充一下:
有一组500个数据,记录了特定时间的测量值。需要绘制该值随时间变化的曲线图。
请问如何将得到的图像进行平滑处理?急用。。
walkerzhou 2005-08-20
  • 打赏
  • 举报
回复
补充一下:
有一组500个数据,记录了特定时间的测量值。需要绘制该值随时间变化的曲线图。
请问如何将得到的图像进行平滑处理?急用。。
walkerzhou 2005-08-20
  • 打赏
  • 举报
回复
Macosx
绘制贝塞尔曲线需要开始和结束两个点,还要两个控制点。
你是说,用开始和结束两个点旁边的点作控制点吗?
Macosx 2005-08-20
  • 打赏
  • 举报
回复
Graphics.DrawBezier 它需要四个点 你只要四个四个的画就可以了 我自己做过
zhilunchen 2005-08-20
  • 打赏
  • 举报
回复
[GvBasic编程]平滑曲线算法(2)[转]
http://xynet.6to23.com/blog/more.asp?name=chdxueyuan&id=14

C语言编写,参考一下哈!
TechEye 2005-08-20
  • 打赏
  • 举报
回复
移动平均线用 DrawLine 连就可以了!
TechEye 2005-08-20
  • 打赏
  • 举报
回复
楼主,我做过,可以用移动平均值进行平滑!

设你的原始数数为
A1,A2,A3,A4,A5,A6,A7,A8,.....An

选前面K个数(这里设K=5)进行计算,计算后的值为

Y5 = (A1 + A2 + A3 + A4 + A5) / 5

Y6 = (A2 + A3 + A4 + A5 + A6) / 5;

...
Yn = (An-4 + An-3 + An-2 + An-1 + An) / K

即,目前点的值为前K个点的平均值。

最后,再把Y1...Yn这些点连起来主很平滑了。K越大越平滑!!!


你一定要试一下啊,因为我也做过,可以的!!!!!!
walkerzhou 2005-08-20
  • 打赏
  • 举报
回复
原来这么容易就解决了 呵呵
查了些资料,还有些收获!贴出来,请高手点拨

查阅了一些以前的帖子,有了些头绪:
给定两点坐标,需要一个插值算法来做平滑处理
查到了三个插值算法公式
分别是
1 线形插值
2 余弦插值
3 三次样条插值

比如三次样条插值的公式
v0 = the point before a
v1 = the point a
v2 = the point b
v3 = the point after b
function Cubic_Interpolate(v0, v1, v2, v3,x)
P = (v3 - v2) - (v0 - v1)
Q = (v0 - v1) - P
R = v2 - v0
S = v1

return Px3 + Qx2 + Rx + S
end of function
但是,对于一个点来说,有两个坐标值。
是不是将前后4个点的X坐标代入公式,得到插值得x坐标;
将前后4个点的Y坐标代入公式,得到插值得y坐标;

另外,公式中的x,是一个系数(0 到1),根据x值的变化,求得的插值在a和b间变化。
在计算横纵坐标值时,只要x相等就得到一个插值点了

我不知理解的是否正确,请高手指点 ,急
lovebanyi 2005-08-20
  • 打赏
  • 举报
回复
g.DrawCurve 用这个函数

110,545

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

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