c# - 如何简化图形路径?

标签 c# winforms simplify graphicspath

我正在通过跟随 MouseMove 事件创建一个相当密集的 GraphicsPath。 GraphicsPath除了运动时的过滤,有没有事后简化GraphicsPath的套路?

我现在还想实现“基于矢量的洪水填充”,这将创建另一个非常密集的路径。

我想我将不得不遍历它并比较每条线的方向,直到它的变化超过一个限制或直到变化加起来达到这个限制。或者我可以简单地删除所有其他点。比较粗糙。

我曾希望有一个内置例程或一个标准算法;但也许我没有使用正确的搜索词..?

感谢所有建议。

最佳答案

阅读 this question我想起了我的旧帖子;所以我决定最终实现一个简单的减少方案:

List<PointF> ReducePath(List<PointF> points, float epsilon)
{
    if (points.Count < 3) return points;
    var newPoints = new List<PointF>();
    newPoints.Add(points[0]);
    float delta = 0f;
    float prevAngle = (float)(Angle(points[0], points[1]) /10f);
    for (int i = 1; i < points.Count - 1; i++)
    {
        float ang = Angle(points[i-1], points[i])/10f;
        delta += ang - prevAngle; 
        prevAngle = ang;
        if (Math.Abs(delta) > epsilon)
        {
            delta = 0;
            newPoints.Add(points[i]);
        }
    }
    newPoints.Add(points[ points.Count -1]);
    return newPoints;
}

float Angle(PointF p1, PointF p2)
{
    if (p1.Y == p2.Y) return p1.X > p2.Y ? 0 : 180;
    else if (p1.X == p2.X) return p1.Y > p2.Y ? 90 : 270;
    else return (float)Math.Atan((p1.Y - p2.Y)/(p1.X - p2.X));
}

//float Slope(PointF p1, PointF p2)
//{
//    if (p1.Y == p2.Y) return 0;
//    else if (p1.X == p2.X) return 12345;
//    else return (p1.Y - p2.Y)/(p1.X - p2.X);
//}

这是 epsilon 值为 1、0.1 和 0.01 的结果:

enter image description here

请注意 GraphicsPath.PathPoints 是只读的,因此我们必须从新的点列表中重新创建路径!

更新:我更新了数学以使用 1°/10 而不是斜率,将 Slope 函数替换为 Angle 函数.. 这应该在各个方向上提供更统一的结果..

更新 2:

感谢以法莲;我已经添加了建议的编辑以使用正确的起始角度..

关于c# - 如何简化图形路径?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22553184/

相关文章:

c# - 将指针函数移植到 C#

c# - 在 OpenFileDialog 中过滤文件的正则表达式

c# - 隐藏新工作表选项卡

c# - 如何监控启动 "dllhost.exe"的进程?

javascript - 这个javascript可以减少吗?

C++ 结束这个 8 位 for 循环的最佳方法是什么

c# - 从 Redis 获取复杂对象时,值为空

c# - 从另一个线程调用 show 后 Windows 窗体窗体挂起

Python:列表代数简化

c# - Admob 广告卡住一半屏幕