2015-11-05 55 views
0

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

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

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

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

Example of drawlines

我需要某种形式的检查,如果point是我的等值线/面板里面我可以得出它在其他不画它。我怎样才能做到这一点?

编辑:

我从列表绘制这些线因此这将是巨大的,如果我可以删除(或不添加的话)从我的名单是我的面板外gluelines。

我得配点属于contourpoints列表:

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

而且我已经得到了与胶线列表:

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

GlueLine类有2 PointF在它,StartPositionEndPosition

,如果我得到的东西像这将是很好:

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

您使用Windows Forms吗?如果是这样,只需设置['Graphics.Clip'](https://msdn.microsoft.com/en-us/library/system.drawing.graphics.clip%28v=vs.110%29.aspx)区域做任何绘画。 (对于WPF图形,有一个等价的方法。) –

+0

但是砖需要绘制,即使它在面板外面,所以我不能屏蔽所有的绘图 – Bart

+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方法需要通用。此外,需要创建循环以测试胶水线是否位于面板内部。

+0

当我使用ur代码时,'RectangleF intersectionRect2 = RectangleF.Intersect(a_ContourRects [1],glueLineRect);'返回一个包含'0'的所有东西的矩形。仍然感谢帮助,我现在可以自己找出一些东西 – Bart

+0

@Bart如果它返回一个空矩形,这意味着这些矩形不相交 – TheLethalCoder

+0

@Bart如果这有助于您自由地上传和/或标记为答案所以未来的游客可以看到 – TheLethalCoder