带有限制的C#绘图

时间:2015-11-05 10:25:48

标签: c# drawing

我正在使用一个项目,该项目从DXF文件中获取信息(来自autocad或任何其他绘图程序的图形文件)。我从中获取信息,它显示了面板的边框。在这个面板中我需要设置线条,但是当面板上有坐标OUTSIDE时,我不允许绘制它们。

下面你可以找到一张图片,也许它会更清晰。

所以白线是砖,它们需要胶水线(黄色),海蓝宝石线是轮廓线。在此行之外,不允许绘制胶水线(黄线)

正如您在使用NR 4BA87的砖块上看到的那样,它会在面板外部绘制胶水线。

Example of drawlines

我需要某种检查point是否在我的轮廓/面板中我可以绘制它,否则不绘制它。我怎么能这样做?

编辑:

我从列表中绘制这些行,这样如果我可以删除(或不添加)我的列表中位于我的面板之外的gluelines,那将会很棒。

我有一个包含点轮廓的列表:

public List<PointF> ListContourPoints = new List<PointF>();

我有一个带胶线的清单:

List<GlueLine> glueLines = new List<GlueLine>(); 

我的GlueLine课程中有2 PointFStartPositionEndPosition

如果我得到类似的东西会很好:

if(GlueLines.StartPosition is INSIDE panel && GlueLines.EndPosition is INSIDE panel)
{
    glueLines.Add(gl);
}

1 个答案:

答案 0 :(得分:0)

您已获得构成面板角落的所有Points的位置数据。所以你需要做的就是找出构成面板的矩形形状,然后对线进行位置检查。

创建矩形的示例函数看起来如下所示。请注意,此函数是在假设面板与提供的示例形状相同的情况下创建的,创建一个示例需要更多逻辑其中包含所有变体:

private static Rectangle[] SplitPointsIntoRectangles(Point[] pa)
{
    pa = pa.OrderBy(p => p.X).ToArray();
    Point[] leftmost = pa.Select(p => p).Where(p => p.X == pa[0].X).ToArray();
    Point[] rightmost = pa.Select(p => p).Where(p => p.X == pa[pa.Length - 1].X).ToArray();

    pa = pa.OrderBy(p => p.Y).ToArray();
    Point[] topmost = pa.Select(p => p).Where(p => p.Y == pa[0].Y).ToArray();
    Point[] bottommost = pa.Select(p => p).Where(p => p.Y == pa[pa.Length - 1].Y).ToArray();

    List<Point> edges = new List<Point>();
    edges.AddRange(leftmost);
    edges.AddRange(rightmost);
    edges.AddRange(topmost);
    edges.AddRange(bottommost);

    Point middlePixel = pa.FirstOrDefault(p => !edges.Contains(p));

    Rectangle[] ra = new Rectangle[2];
    ra[0] = new Rectangle(leftmost[0].X, leftmost.Min(p => p.Y), rightmost[0].X - leftmost[0].X, bottommost[0].Y - leftmost[0].Y);
    ra[1] = new Rectangle(topmost.Min(p => p.X), topmost[0].Y, rightmost[0].X - middlePixel.X, middlePixel.Y - topmost[0].Y);

    return ra;
}

一旦我们有了矩形,我们就需要确保线条不在它们之外,为此我们可以使用Rectangle.Intersects方法。为此,我们使用每个胶水线的点来创建一个矩形,就像这样(假设所有这些线都是水平的):

Rectangle glueLineRect = new Rectangle(glueLineStartPoint.X, glueLineStartPoint.Y, glueLineEndPosition.X - glueLineStartPoint.X, 1);

如果以下函数返回一个空矩形,则两个矩形不相交,否则它们会相交。注意:如果矩形部分相交,此函数将返回无空矩形。

Rectangle intersectionRect = Rectangle.Intersect(MainRect, glueLineRect);

然后可以将其扩展为测试面板中包含的所有矩形,如果它们全部失效,则胶水线位于面板外部。

我创建了这个答案以帮助您入门,SplitPointsIntoRectangles方法需要通用。此外,还需要创建循环来测试Glue Lines是否位于面板内部。