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)
)据我所知,您是在尝试延伸边缘,而不是角落。
程序可以是:
abs(x1-x2)>abs(y1-y2)
)试试这个例子,看看你是否能适应它来解决你的问题
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;
公共点{