从点阵列平滑2d线

时间:2011-10-18 18:10:46

标签: c#

当用户绘制时,我会在每次输入事件触发时捕获其输入的位置,然后在每个点之间绘制直线。

不幸的是,这会产生一种非常锯齿状的外观,并且它会变得更糟,这取决于用户相对于输入事件触发的速度移动输入的速度。

我想要的是一个函数,它接受一个点数组并返回一个已经平滑的点数组,既填充点之间的任何大间隙,又删除锯齿状边缘并用平滑替换它们曲线。

我知道这是一个众所周知的问题,只是没有运气形成搜索查询以找到我正在寻找的东西。

谢谢!

如果函数是用c#编写的,则为奖励积分:)

谢谢!

4 个答案:

答案 0 :(得分:9)

float数组的扩展方法c#(sample

  public static NoiseReduction(this float[] src, int severity = 1)
    {
        for (int i = 1; i < src.Length; i++)
        {
            //---------------------------------------------------------------avg
            var start = (i - severity > 0 ? i - severity : 0);
            var end = (i + severity < src.Length ? i + severity : src.Length);

            float sum = 0;

            for (int j = start; j < end; j++)
            {
                sum += src[j];
            }

            var avg = sum / (end - start);
            //---------------------------------------------------------------
            src[i] = avg;

        }
    }

答案 1 :(得分:6)

我不会得到奖励积分(这是一项家庭作业吗?;),但有一个很容易理解和实施的解决方案。它被称为Catmull-Rom插值。

看看这里

http://en.wikipedia.org/wiki/Catmull-Rom_spline

在这里

http://www.mvps.org/directx/articles/catmull/

(忽略最后一个的DirectX部分)

答案 2 :(得分:3)

谢谢大家!我根据发布的链接编写了以下功能。它可以清理任何间隔太近的点,然后使用Catmull-Rom来平滑点列表。

    public static void Smooth(this List<Vector2> pointList)
    {
        List<Vector2> smoothedPoints = new List<Vector2>();

        for (int i = 1; i < pointList.Count; i++)
        {
            if (Vector2.Distance(pointList[i - 1], pointList[i]) < 30f)
            {
                pointList.RemoveAt(i);
                i--;
            }
        }

        if (pointList.Count < 4) return;

        smoothedPoints.Add(pointList[0]);

        for (int i = 1; i < pointList.Count - 2; i++)
        {
            smoothedPoints.Add(pointList[i]);

            smoothedPoints.Add(Vector2.CatmullRom(pointList[i - 1], pointList[i], pointList[i + 1], pointList[i + 2], .5f));
            //smoothedPoints.Add(Vector2.CatmullRom(pointList[i - 1], pointList[i], pointList[i + 1], pointList[i + 2], .2f));
            //smoothedPoints.Add(Vector2.CatmullRom(pointList[i - 1], pointList[i], pointList[i + 1], pointList[i + 2], .3f));
            //smoothedPoints.Add(Vector2.CatmullRom(pointList[i - 1], pointList[i], pointList[i + 1], pointList[i + 2], .7f));
            //smoothedPoints.Add(Vector2.CatmullRom(pointList[i - 1], pointList[i], pointList[i + 1], pointList[i + 2], .8f));
            //smoothedPoints.Add(Vector2.CatmullRom(pointList[i - 1], pointList[i], pointList[i + 1], pointList[i + 2], .9f));
        }

        smoothedPoints.Add(pointList[pointList.Count - 2]);
        smoothedPoints.Add(pointList[pointList.Count - 1]);

        pointList.Clear();
        pointList.AddRange(smoothedPoints);
    }

答案 3 :(得分:1)

你在做什么画画?

如果您正在使用System.Drawing,您是否可以将这些点传递给DrawBeziers,这应该可以为您做好反对别名。