折线移位算法

时间:2016-11-15 11:04:29

标签: c# winforms 2d gdi+ polyline

我有一个带折线的列表(PointCollection),如图所示。有些段像蓝色和橙色线一样重叠,如“原始”中所示。我已经知道这些是哪些细分市场。我需要将重叠的部分分开。棘手的是避免与“错误”中显示的其他行重叠。

enter image description here

我遇到的问题是,我只是节点的坐标而没有关于段的信息。有没有可能确定我是否在另一条线的一段上移动一个节点?有个好主意我怎么能解决这个问题?

1 个答案:

答案 0 :(得分:1)

如评论中所述,您可以选择

  • 通过几何计算或
  • 分析解决问题
  • 使用一些GDI +方法

以下是后者的一个例子:

首先,您的控制台应用程序需要包含对System.Drawing的引用和一些使用子句的引用:

using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;  //optional, used for bitmap saving only

这是一个静态函数,用于测试两个GraphicsPaths是否相交:

static bool intersect(GraphicsPath gp1, GraphicsPath gp2, Graphics g) 
{
    using (Region reg = new Region(gp1))
    {
        reg.Intersect(gp2);
        return !reg.IsEmpty(g);
    }
}

需要两个GraphicsPaths和一个Graphics对象。

这是一个测试平台,用于演示如何使用它。它会创建2个随机折线,然后每次将第二个向右移动50个像素,直到它不再与第一个相交。

所有阶段都被绘制成一个位图,然后保存..:

static void Main(string[] args)
{
    int w = 1234;
    int h = 1234;

    Random rnd = new Random(0);
    for (int t = 0; t < 33; t++)
    {
        List<Point> l1 = new List<Point>();
        List<Point> l2 = new List<Point>();
        for (int i = 0; i < 4; i++)
        {
            l1.Add(new Point(rnd.Next(1234), rnd.Next(567)));
            l2.Add(new Point(rnd.Next(567), rnd.Next(1234)));
        }

        using (Matrix m = new Matrix())
        using (Bitmap bmp = new Bitmap(w, h))
        using (Graphics g = Graphics.FromImage(bmp))
        using (GraphicsPath gp1 = new GraphicsPath())
        using (GraphicsPath gp2 = new GraphicsPath())
        {
            gp1.AddLines(l1.ToArray());
            gp2.AddLines(l2.ToArray());
            m.Translate(50, 0);
            bool intersects = intersect(gp1, gp2, g);
            g.Clear(Color.White);
            g.DrawPath(Pens.Blue, gp1);
            g.DrawPath(intersects ? Pens.Red : Pens.Green, gp2);

            while (intersects)
            {
                gp2.Transform(m);
                intersects = intersect(gp1, gp2, g);
                g.DrawPath(intersects ? Pens.Red : Pens.Green, gp2);
                intersects = intersect(gp1, gp2, g);
            }


            bmp.Save(@"D:\scrape\x\__xTest_" + t.ToString("000") + ".png", 
                     ImageFormat.Png);

        }
    }
}

这是输出文件之一:

enter image description here

您可以访问移位的路径点

 List<PointF> l3 = gp2.PathPoints.ToList();

请注意,您应该使Bitmap足够大,以适合您的实际数字或缩小它们并使用floats