折线平移算法
Polyline shifting algorithm
我有一个包含多段线 (PointCollection) 的列表,如图所示。一些片段像“原始”中显示的蓝色和橙色线一样重叠。我已经知道这些是哪些细分市场。我需要将重叠的部分分开。棘手的事情是避免新的与其他行重叠,如“错误”所示。
我遇到了问题,我只有节点的坐标,没有关于段的信息。是否有可能确定我是否移动了另一条线段上的节点?有人知道如何解决这个问题吗?
如评论中所述,您可以选择
- 通过几何计算或
分析解决问题
- 使用一些 GDI+ 方法
这是后者的一个例子:
首先,您的控制台应用程序需要包含对 System.Drawing
的引用和一些 using 子句:
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 个像素,直到它不再与第一条相交。
所有阶段都绘制成位图,然后保存..:[=21=]
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);
}
}
}
这是输出文件之一:
您可以访问移动的路径点作为
List<PointF> l3 = gp2.PathPoints.ToList();
请注意,您应该使 Bitmap
足够大以适应您的实际数字,或者缩小它们并使用 floats
!
我有一个包含多段线 (PointCollection) 的列表,如图所示。一些片段像“原始”中显示的蓝色和橙色线一样重叠。我已经知道这些是哪些细分市场。我需要将重叠的部分分开。棘手的事情是避免新的与其他行重叠,如“错误”所示。
我遇到了问题,我只有节点的坐标,没有关于段的信息。是否有可能确定我是否移动了另一条线段上的节点?有人知道如何解决这个问题吗?
如评论中所述,您可以选择
- 通过几何计算或 分析解决问题
- 使用一些 GDI+ 方法
这是后者的一个例子:
首先,您的控制台应用程序需要包含对 System.Drawing
的引用和一些 using 子句:
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 个像素,直到它不再与第一条相交。
所有阶段都绘制成位图,然后保存..:[=21=]
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);
}
}
}
这是输出文件之一:
您可以访问移动的路径点作为
List<PointF> l3 = gp2.PathPoints.ToList();
请注意,您应该使 Bitmap
足够大以适应您的实际数字,或者缩小它们并使用 floats
!