如何在完整多边形的两点之间的某处添加一个点
How to add a point in somewhere between two points of a complete polygon
我有一个点列表。我取第一个点和下一个点(第二点)并在第一点和第二点之间画一条线。
我想在现有点之间添加另一个顶点。
这是我的方法。
当用户双击在线时,应该在那里添加一个点。
找到由多边形生成的所有形状点。
检查 e.Location 是否在点列表中。
如果存在则检查该点的下限和上限。
在下限旁边插入 e.Location。
使用更新的列表重新绘制线条。
我正在计算直线的所有点。通过使用 y = mx + c。
我的问题是我能够获得所有垂直点 x = a、一些对角线点和水平点,但不是全部。我需要知道是什么原因以及如何解决它?
我正在创建由 ICImaging video grabber library.So 提供的位图叠加层,我只能通过整数点在屏幕上绘制。
private void btnAddPoint_Click(object sender, EventArgs e)
{
//IsLineSelected = true;
Debug.Print("Current Points in List ");
foreach (System.Drawing.Point P in PathPoints)
{
Debug.Print(P.ToString());
}
for (int IndexI = 0; IndexI != PathPoints.Count - 1; IndexI++)
{
if (IndexI == PathPoints.Count-1)
{
break;
}
else
{
Debug.Print("P1:" + PathPoints[IndexI].ToString() + "P2:"+ PathPoints[IndexI+1].ToString());
ShapeDirectory.AllLinePoints(PathPoints[IndexI], PathPoints[IndexI + 1]);
}
}
foreach (System.Drawing.Point P in ShapeDirectory.LinePoints)
{
PathPoints3.Add(P);
}
drawLinePoints = true;
}
public static void AllLinePoints(Point p1, Point p2)
{
double YDiff = p2.Y - p1.Y;
double XDiff = p2.X - p1.X;
double SlopM = Math.Round(Math.Abs(YDiff / XDiff));
double YinterceptB = Math.Round(Math.Abs(p1.Y - (SlopM * p1.X)));
Debug.Print("Slop: " + SlopM.ToString() + "Y Intercept: " + YinterceptB.ToString());
if (SlopM == 0)
{
}
if (Double.IsNegativeInfinity(SlopM) || Double.IsPositiveInfinity(SlopM))
{
int LowerBoundX = 0;
int LowerBoundY = 0;
int upperBoundX;
int upperBoundY;
double distanceBetwwenP1andp2 = GetDistanceBetween2points(p1, p2);
if (p1.X == p2.X )
{
LowerBoundX = p1.X;
upperBoundX = p2.X;
}
if (p1.Y <= p2.Y)
{
LowerBoundY = p1.Y;
upperBoundY = p2.Y;
}
else
{
LowerBoundY = p2.Y;
upperBoundY = p1.Y;
}
//Vertical
for (int YIndex = LowerBoundY; YIndex <= upperBoundY; YIndex++)
{
TempLinePoint.X = LowerBoundX;
TempLinePoint.Y = YIndex;
//Debug.Print("Current Line Points X: " + XIndex.ToString() + "Y: " + YIndex.ToString());
LinePoints.Add(TempLinePoint);
}
}
else
{
int LowerBoundX;
int LowerBoundY;
int upperBoundX;
int upperBoundY;
double distanceBetwwenP1andp2 = GetDistanceBetween2points(p1, p2);
if (p1.X <= p2.X && p1.Y <= p2.Y)
{
LowerBoundX = p1.X;
upperBoundX = p2.X;
LowerBoundY = p1.Y;
upperBoundY = p2.Y;
}
else
{
LowerBoundX = p2.X;
upperBoundX = p1.X;
LowerBoundY = p2.Y;
upperBoundY = p1.Y;
}
//if Vertical
for (int YIndex = LowerBoundY; YIndex <= upperBoundY; YIndex++)
{
for (int XIndex = LowerBoundX; XIndex <= upperBoundX; XIndex++)
{
if (YIndex == (SlopM * XIndex) + YinterceptB)
{
TempLinePoint.X = XIndex;
TempLinePoint.Y = YIndex;
//Debug.Print("Current Line Points X: " + XIndex.ToString() + "Y: " + YIndex.ToString());
LinePoints.Add(TempLinePoint);
}
}
}
}
编辑
我改变了方法。
计算中心点。
将新的 MouseDoubleClicked e.Location 添加到 PathPoint 列表。
找出多边形每个顶点的角度。
按升序排列列表。
插入列表末尾的第一个 Point 以完成多边形。
代码在答案中。
public static double GetAngleBetweenPoints(Point p1, Point p2)
{
double xDiff = p2.X - p1.X;
double yDiff = p1.Y - p2.Y;
double Angle = Math.Atan2(yDiff, xDiff) * (180 / Math.PI);
if (Angle < 0.0)
Angle = Angle + 360.0;
return Angle;
}
public static GenericList<Point> PointAddingByAngle(GenericList<Point> LinePoints2)
{
List<int> AnglefromCenterPointsofShapePoint = new List<int>();
List<Point> Linepoints3 = new List<Point>(LinePoints2);
List<Point> LinePoints = Linepoints3.Distinct().ToList();
Point CenterPoint = new Point();
CenterPoint.X = PolygonCenterX;
CenterPoint.Y = PolygonCenterY;
for (int index = 0; index < LinePoints.Count; index++)
{
AnglefromCenterPointsofShapePoint.Add((int) Math.Round(GetAngleBetweenPoints(CenterPoint, LinePoints[index])));
}
AnglefromCenterPointsofShapePoint.Sort();
int currentPointAngle = 0;
for (int AngleListIndex = 0; AngleListIndex < AnglefromCenterPointsofShapePoint.Count; AngleListIndex++)
{
currentPointAngle = AnglefromCenterPointsofShapePoint[AngleListIndex];
for (int index = 0; index < LinePoints.Count; index++)
{
if ((Math.Round(GetAngleBetweenPoints(CenterPoint, LinePoints[index]))) == currentPointAngle)
{
SortedPoints.Add(LinePoints[index]);
break;
}
}
}
SortedPoints.Add(SortedPoints[0]);
return SortedPoints;
}
private void pictureBox_MouseDoubleClick(object sender, MouseEventArgs e)
{
if (PathPoints.Count > 2)
{
PathPoints.Add(PathPoints[0]);
IsPathComplete = true;
IsPointSelected = false;
StartingPoint = PathPoints[0];
EndingPoint = PathPoints[PathPoints.Count - 1];
}
if (IsPathComplete && NewPointAdd)
{
System.Drawing.Point Centerpoint = new System.Drawing.Point();
PathPoints.Add(e.Location);
MinMaxFinder(PathPoints);
Centerpoint.X = PolygonCenterX;
Centerpoint.Y = PolygonCenterY;
lblAngle.Text = Convert.ToString(Math.Round(ShapeDirectory.GetAngleBetweenPoints(Centerpoint, e.Location)));
PathPoints3.Clear();
PathPoints3 = ShapeDirectory.PointAddingByAngle(PathPoints);
PathPoints.Clear();
foreach (System.Drawing.Point p in PathPoints3)
{
PathPoints.Add(p);
}
PathPoints.Add(PathPoints3[0]);
NewPointAddDraw = true;
}
}
我有一个点列表。我取第一个点和下一个点(第二点)并在第一点和第二点之间画一条线。
我想在现有点之间添加另一个顶点。
这是我的方法。
我正在计算直线的所有点。通过使用 y = mx + c。
我的问题是我能够获得所有垂直点 x = a、一些对角线点和水平点,但不是全部。我需要知道是什么原因以及如何解决它?
我正在创建由 ICImaging video grabber library.So 提供的位图叠加层,我只能通过整数点在屏幕上绘制。
private void btnAddPoint_Click(object sender, EventArgs e)
{
//IsLineSelected = true;
Debug.Print("Current Points in List ");
foreach (System.Drawing.Point P in PathPoints)
{
Debug.Print(P.ToString());
}
for (int IndexI = 0; IndexI != PathPoints.Count - 1; IndexI++)
{
if (IndexI == PathPoints.Count-1)
{
break;
}
else
{
Debug.Print("P1:" + PathPoints[IndexI].ToString() + "P2:"+ PathPoints[IndexI+1].ToString());
ShapeDirectory.AllLinePoints(PathPoints[IndexI], PathPoints[IndexI + 1]);
}
}
foreach (System.Drawing.Point P in ShapeDirectory.LinePoints)
{
PathPoints3.Add(P);
}
drawLinePoints = true;
}
public static void AllLinePoints(Point p1, Point p2)
{
double YDiff = p2.Y - p1.Y;
double XDiff = p2.X - p1.X;
double SlopM = Math.Round(Math.Abs(YDiff / XDiff));
double YinterceptB = Math.Round(Math.Abs(p1.Y - (SlopM * p1.X)));
Debug.Print("Slop: " + SlopM.ToString() + "Y Intercept: " + YinterceptB.ToString());
if (SlopM == 0)
{
}
if (Double.IsNegativeInfinity(SlopM) || Double.IsPositiveInfinity(SlopM))
{
int LowerBoundX = 0;
int LowerBoundY = 0;
int upperBoundX;
int upperBoundY;
double distanceBetwwenP1andp2 = GetDistanceBetween2points(p1, p2);
if (p1.X == p2.X )
{
LowerBoundX = p1.X;
upperBoundX = p2.X;
}
if (p1.Y <= p2.Y)
{
LowerBoundY = p1.Y;
upperBoundY = p2.Y;
}
else
{
LowerBoundY = p2.Y;
upperBoundY = p1.Y;
}
//Vertical
for (int YIndex = LowerBoundY; YIndex <= upperBoundY; YIndex++)
{
TempLinePoint.X = LowerBoundX;
TempLinePoint.Y = YIndex;
//Debug.Print("Current Line Points X: " + XIndex.ToString() + "Y: " + YIndex.ToString());
LinePoints.Add(TempLinePoint);
}
}
else
{
int LowerBoundX;
int LowerBoundY;
int upperBoundX;
int upperBoundY;
double distanceBetwwenP1andp2 = GetDistanceBetween2points(p1, p2);
if (p1.X <= p2.X && p1.Y <= p2.Y)
{
LowerBoundX = p1.X;
upperBoundX = p2.X;
LowerBoundY = p1.Y;
upperBoundY = p2.Y;
}
else
{
LowerBoundX = p2.X;
upperBoundX = p1.X;
LowerBoundY = p2.Y;
upperBoundY = p1.Y;
}
//if Vertical
for (int YIndex = LowerBoundY; YIndex <= upperBoundY; YIndex++)
{
for (int XIndex = LowerBoundX; XIndex <= upperBoundX; XIndex++)
{
if (YIndex == (SlopM * XIndex) + YinterceptB)
{
TempLinePoint.X = XIndex;
TempLinePoint.Y = YIndex;
//Debug.Print("Current Line Points X: " + XIndex.ToString() + "Y: " + YIndex.ToString());
LinePoints.Add(TempLinePoint);
}
}
}
}
编辑
我改变了方法。
代码在答案中。
public static double GetAngleBetweenPoints(Point p1, Point p2)
{
double xDiff = p2.X - p1.X;
double yDiff = p1.Y - p2.Y;
double Angle = Math.Atan2(yDiff, xDiff) * (180 / Math.PI);
if (Angle < 0.0)
Angle = Angle + 360.0;
return Angle;
}
public static GenericList<Point> PointAddingByAngle(GenericList<Point> LinePoints2)
{
List<int> AnglefromCenterPointsofShapePoint = new List<int>();
List<Point> Linepoints3 = new List<Point>(LinePoints2);
List<Point> LinePoints = Linepoints3.Distinct().ToList();
Point CenterPoint = new Point();
CenterPoint.X = PolygonCenterX;
CenterPoint.Y = PolygonCenterY;
for (int index = 0; index < LinePoints.Count; index++)
{
AnglefromCenterPointsofShapePoint.Add((int) Math.Round(GetAngleBetweenPoints(CenterPoint, LinePoints[index])));
}
AnglefromCenterPointsofShapePoint.Sort();
int currentPointAngle = 0;
for (int AngleListIndex = 0; AngleListIndex < AnglefromCenterPointsofShapePoint.Count; AngleListIndex++)
{
currentPointAngle = AnglefromCenterPointsofShapePoint[AngleListIndex];
for (int index = 0; index < LinePoints.Count; index++)
{
if ((Math.Round(GetAngleBetweenPoints(CenterPoint, LinePoints[index]))) == currentPointAngle)
{
SortedPoints.Add(LinePoints[index]);
break;
}
}
}
SortedPoints.Add(SortedPoints[0]);
return SortedPoints;
}
private void pictureBox_MouseDoubleClick(object sender, MouseEventArgs e)
{
if (PathPoints.Count > 2)
{
PathPoints.Add(PathPoints[0]);
IsPathComplete = true;
IsPointSelected = false;
StartingPoint = PathPoints[0];
EndingPoint = PathPoints[PathPoints.Count - 1];
}
if (IsPathComplete && NewPointAdd)
{
System.Drawing.Point Centerpoint = new System.Drawing.Point();
PathPoints.Add(e.Location);
MinMaxFinder(PathPoints);
Centerpoint.X = PolygonCenterX;
Centerpoint.Y = PolygonCenterY;
lblAngle.Text = Convert.ToString(Math.Round(ShapeDirectory.GetAngleBetweenPoints(Centerpoint, e.Location)));
PathPoints3.Clear();
PathPoints3 = ShapeDirectory.PointAddingByAngle(PathPoints);
PathPoints.Clear();
foreach (System.Drawing.Point p in PathPoints3)
{
PathPoints.Add(p);
}
PathPoints.Add(PathPoints3[0]);
NewPointAddDraw = true;
}
}