如何简化图形路径? [英] how can I simplify a graphicspath?

查看:343
本文介绍了如何简化图形路径?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

通过跟随MouseMove事件,我正在创建一个相当密集的GraphicsPath.除了在移动过程中进行过滤之外,是否还有一个例程可以在事件发生后简化GraphicsPath?

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

我想我将不得不逐步检查它,并比较每条线的方向,直到其变化超过极限或直到变化累加到该极限为止.或者我可以简单地删除其他所有内容.相当粗糙.

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

感谢所有建议.

解决方案

阅读这个问题我想起了我的旧职位;所以我决定最终实现一个简单的减少方案:

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的结果:

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

更新:我已经将数学更新为使用1°/10而不是斜率,将Slope函数替换为Angle函数.方向.

更新2:

对以弗所的称赞;我添加了建议的修改以使用适当的起始角度.

I'm creating a rather dense GraphicsPath by following the MouseMove event. Besides filtering during the movement, is there a routine to simplify the GraphicsPath after the fact?

I also want to implement a 'vector-based flood fill' now and this will create another really dense path.

I guess I will have to step through it and compare the directions of each line until it changes more than a limit or until the changes add up to this limit. Or I could simply erase every other point. Rather crude.

I had hoped for a built-in routine or a standard algorithm; but maybe I have not used the right search words..?

All suggestions appreciated.

解决方案

Reading this question I was reminded of my old post; so I decided to finally implement a simple reduction scheme:

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);
//}

Here is a result with epsilon values of 1, 0.1 and 0.01:

Note the the GraphicsPath.PathPoints are read-only, so we have to re-create the path from the new points list!

Update: I have updated the math to work with 1°/10 instead of slopes, replacing the Slope function with an Angle function.. This should give more uniform results over various directions..

Update 2:

Kudos to ephraim; I have added the suggested edits to use a proper starting angle..

这篇关于如何简化图形路径?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆