如何检测多边形的角落?

时间:2016-11-20 13:46:30

标签: c# polygon

我正在制作一个自动平面图生成桌面应用程序。在这里,我首先使用这种方法在点上绘制多边形

public void DrawPolygonPointF(PaintEventArgs e) {

// Create pen.
Pen blackPen = new Pen(Color.Black, 3);

// Create points that define polygon.
PointF point1 = new PointF(50.0F,  50.0F);
PointF point2 = new PointF(100.0F,  25.0F);
PointF point3 = new PointF(200.0F,   5.0F);
PointF point4 = new PointF(250.0F,  50.0F);
PointF point5 = new PointF(300.0F, 100.0F);
PointF point6 = new PointF(350.0F, 200.0F);
PointF point7 = new PointF(250.0F, 250.0F);
PointF[] curvePoints =
         {
             point1,
             point2,
             point3,
             point4,
             point5,
             point6,
             point7
         };

// Draw polygon curve to screen.
e.Graphics.DrawPolygon(blackPen, curvePoints);
}

注意:这些点不是实际点,它们仅用于演示目的。我正在阅读文本文件中的要点。

现在我需要生成一种特殊类型的网格。 在生成网格时,第一步是检测角落并延伸角线。 如何检测多边形的角落,以便进入生成网格的下一步?

标记了角落。我需要在水平左侧延伸标记为黑色的角落,而另一个则在右侧延伸直至触及该线。

附上截图。

CORNERS ARE MARKED WITH BLACK AND RED

提前致谢

2 个答案:

答案 0 :(得分:0)

根据我的理解,你试图扩展边缘,而不是角落 程序可以是:

  1. 枚举边(每2个相邻点定义边)
  2. 对于每条边,找到它是垂直还是水平(abs(x1-x2) > abs(y1-y2)
  3. 查找是否可以扩展边缘,水平(左/右)和垂直(上/下)

    bool CheckHorizo​​ntalExtensibilityToRight(Point [] curvePoints,Point corner) {     return curvePoints.Any(cp => cp.Y< corner.Y&& cp.X< corner.X); }

答案 1 :(得分:0)

试试这个例子,看看你是否可以调整它来解决你的问题......

using System.Drawing;
using System.Windows.Forms;

namespace WindowsFormsApplication
{
    public partial class Form1 : Form
    {
        private struct LineSegment
        {
            private PointF _a, _b;

            public PointF A { get { return _a; } }
            public PointF B { get { return _b; } }

            public LineSegment(PointF a, PointF b)
            {
                _a = a; _b = b;
            }

            public float GetLengthSquared()
            {
                var dx = _a.X - _b.X;
                var dy = _a.Y - _b.Y;
                return dx * dx + dy * dy;
            }

            public bool RectContains(PointF a)
            {
                var x = a.X;
                var y = a.Y;
                var x1 = _a.X;
                var y1 = _a.Y;
                var x2 = _b.X;
                var y2 = _b.Y;
                return (x1 < x2 ? x1 <= x && x2 >= x : x2 <= x && x1 >= x) && (y1 < y2 ? y1 <= y && y2 >= y : y2 <= y && y1 >= y);
            }

            public bool ExtendToIntersectWith(LineSegment b)
            {
                var x1 = _a.X;
                var y1 = _a.Y;
                var x2 = _b.X;
                var y2 = _b.Y;

                var x3 = b._a.X;
                var y3 = b._a.Y;
                var x4 = b._b.X;
                var y4 = b._b.Y;

                var a1 = y2 - y1;
                var b1 = x1 - x2;
                var c1 = x1 * y2 - x2 * y1;

                var a2 = y4 - y3;
                var b2 = x3 - x4;
                var c2 = x3 * y4 - x4 * y3;

                var d = a1 * b2 - b1 * a2;
                if (d == 0)
                    return false;

                var x = (c1 * b2 - b1 * c2) / d;
                var y = (a1 * c2 - c1 * a2) / d;
                var p = new PointF(x, y);

                if (b.RectContains(p) && !RectContains(p))
                {
                    if (new LineSegment(_a, p).GetLengthSquared() < new LineSegment(_b, p).GetLengthSquared())
                        _a = p;
                    else
                        _b = p;
                    return true;
                }

                return false;
            }
        }

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Paint(object sender, PaintEventArgs e)
        {
            PointF[] curvePoints =
            {
                /*
                new PointF(50.0F,  50.0F),
                new PointF(100.0F,  25.0F),
                new PointF(200.0F,   5.0F),
                new PointF(250.0F,  50.0F),
                new PointF(300.0F, 100.0F),
                new PointF(350.0F, 200.0F),
                new PointF(250.0F, 250.0F)
                */
                new PointF(30F,  10F),
                new PointF(60F,  10F),
                new PointF(60F,  20F),
                new PointF(90F,  20F),
                new PointF(90F,  60F),
                new PointF(10F,  60F),
                new PointF(10F,  40F),
                new PointF(30F,  40F),
            };
            int n = curvePoints.Length;
            LineSegment[] lineSegments = new LineSegment[n];
            int i = 0;
            for (; i < n - 1; ++i)
                lineSegments[i] = new LineSegment(curvePoints[i], curvePoints[i + 1]);
            lineSegments[i] = new LineSegment(curvePoints[i], curvePoints[0]);
            for (i = 0; i < n; ++i)
                for (int j = 0; j < n; ++j)
                    lineSegments[i].ExtendToIntersectWith(lineSegments[j]);
            for (i = 0; i < n; ++i)
            {
                var lineSegment = lineSegments[i];
                e.Graphics.DrawLine(Pens.Black, lineSegment.A, lineSegment.B);
            }
            //e.Graphics.DrawPolygon(Pens.Black, curvePoints);
        }
    }
}