C# 如何检测多边形的角点?

C# 如何检测多边形的角点?,c#,polygon,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 =

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

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);
}
注意:这些点不是实际点,它们仅用于演示目的。我正在从文本文件中读取点。

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

角落有标记。我需要在左侧水平延伸标有黑色的角,另一个在右侧延伸,直到它接触到线

附上一张截图


提前感谢

据我所知,您是在尝试延伸边缘,而不是角落。
程序可以是:

  • 枚举边(每两个相邻点定义一条边)
  • 对于每一条边,找出它是垂直的还是水平的(
    abs(x1-x2)>abs(y1-y2)
  • 确定边缘是否可以延伸,水平(左/右)和垂直(上/下)

    布尔检查水平扩展性右(点[]曲线点,点角) { 返回曲线点.Any(cp=>cp.Y

  • 据我所知,您是在尝试延伸边缘,而不是角落。
    程序可以是:

  • 枚举边(每两个相邻点定义一条边)
  • 对于每一条边,找出它是垂直的还是水平的(
    abs(x1-x2)>abs(y1-y2)
  • 确定边缘是否可以延伸,水平(左/右)和垂直(上/下)

    布尔检查水平扩展性右(点[]曲线点,点角) { 返回曲线点.Any(cp=>cp.Y

  • 试试这个例子,看看你是否能适应它来解决你的问题

    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);
            }
        }
    }
    
    使用系统图;
    使用System.Windows.Forms;
    命名空间Windows窗体应用程序
    {
    公共部分类Form1:Form
    {
    专用结构线段
    {
    私有点F_a,_b;
    公共点f A{get{return{u A;}}
    公共点B{get{return_B;}
    公共线段(点F a、点F b)
    {
    _a=a;_b=b;
    }
    公共浮点GetLengthSquared()
    {
    var dx=_a.X-_b.X;
    变量dy=_a.Y-_b.Y;
    返回dx*dx+dy*dy;
    }
    公共布尔值(点F a)
    {
    var x=a.x;
    变量y=a.y;
    var-x1=_a.X;
    变量y1=_a.Y;
    var x2=_b.X;
    变量y2=_b.Y;
    返回(x1
    试试这个例子,看看你是否可以调整它来解决你的问题

    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);
            }
        }
    }
    
    使用系统图;
    使用System.Windows.Forms;
    命名空间Windows窗体应用程序
    {
    公共部分类Form1:Form
    {
    专用结构线段
    {
    私有点F_a,_b;
    公共点{