C# 多边形中的点,包括边距为c的边案例#
我正在使用Unity3D,我有一个多边形(Vector2数组)以及要检查的点。 在过去的几天里,我一直在寻找解决方案,包括pnpoly和其他算法。问题是,我的精确度高达0.001f,因为我在使用TransformPoint(获取网格顶点的世界位置)之后,通过与四元数相乘,将3D面投影到2D平面上 我对多边形一无所知,因为它们是由许多网格三角形组成的——它们可以有任何形状 我如何处理这种极端的不精确性,并找到多边形边界内或边界上的所有点C# 多边形中的点,包括边距为c的边案例#,c#,unity3d,polygon,C#,Unity3d,Polygon,我正在使用Unity3D,我有一个多边形(Vector2数组)以及要检查的点。 在过去的几天里,我一直在寻找解决方案,包括pnpoly和其他算法。问题是,我的精确度高达0.001f,因为我在使用TransformPoint(获取网格顶点的世界位置)之后,通过与四元数相乘,将3D面投影到2D平面上 我对多边形一无所知,因为它们是由许多网格三角形组成的——它们可以有任何形状 我如何处理这种极端的不精确性,并找到多边形边界内或边界上的所有点 public static bool IsInsid
public static bool IsInsidePolygon(Vector2[] vertices, Vector2 checkPoint)
{
float[] vertX = new float[vertices.Length];
float[] vertY = new float[vertices.Length];
for (int i = 0; i < vertices.Length; i++)
{
vertX[i] = vertices[i].x;
vertY[i] = vertices[i].y;
}
return IsInsidePolygon(vertices.Length, vertX, vertY, checkPoint.x, checkPoint.y);
}
public static bool IsInsidePolygon3(int nvert, float[] vertx, float[] verty, float testx, float testy)
{
int i, j = 0;
bool c = false;
for (i = 0, j = nvert - 1; i < nvert; j = i++)
{
if (((verty[i] > testy) != (verty[j] > testy)) &&
(testx < (vertx[j] - vertx[i]) * (testy - verty[i]) / (verty[j] - verty[i]) + vertx[i]))
c = !c;
}
return c;
}
public static bool IsInsidePolygon(向量2[]顶点,向量2检查点)
{
float[]vertX=新的float[vertex.Length];
float[]vertY=新的float[顶点.长度];
对于(int i=0;itesty)!=(verty[j]>testy))&&
(testx<(vertx[j]-vertx[i])*(testy-verty[i])/(verty[j]-verty[i])+vertx[i]))
c=!c;
}
返回c;
}
解决方案是找到与多边形最近的距离,如果距离在边距内,则返回true,以下是完整的代码:
'''
公共静态浮点距离PointLine2D(矢量2点、矢量2线起点、矢量2线终点)
{
返回(ProjectPointLine2D(点、线起点、线终点)-点);
}
公共静态Vector2项目点Line2D(Vector2点、Vector2线起点、Vector2线终点)
{
矢量2 rhs=点-线起点;
Vector2 Vector2=lineEnd-lineStart;
浮动幅度=矢量2.0幅度;
Vector2 lhs=Vector2;
如果(震级>1E-06f)
{
lhs=(矢量2)(lhs/量级);
}
float num2=数学钳位(矢量2点(左、右)、0f、幅值);
返回(lineStart+((Vector2)(lhs*num2));
}
公共静态浮点闭合距离拓扑多边形(矢量2[]顶点,矢量2点)
{
int nvert=垂直长度;
int i,j=0;
浮点数距离=数学无穷大;
对于(i=0,j=nvert-1;i 如果(((verty[i]解决方案是找到与多边形最近的距离,如果距离在边距内,则返回true,以下是整个代码:
'''
公共静态浮点距离PointLine2D(矢量2点、矢量2线起点、矢量2线终点)
{
返回(ProjectPointLine2D(点、线起点、线终点)-点);
}
公共静态Vector2项目点Line2D(Vector2点、Vector2线起点、Vector2线终点)
{
矢量2 rhs=点-线起点;
Vector2 Vector2=lineEnd-lineStart;
浮动幅度=矢量2.0幅度;
Vector2 lhs=Vector2;
如果(震级>1E-06f)
{
lhs=(矢量2)(lhs/量级);
}
float num2=数学钳位(矢量2点(左、右)、0f、幅值);
返回(lineStart+((Vector2)(lhs*num2));
}
公共静态浮点闭合距离拓扑多边形(矢量2[]顶点,矢量2点)
{
int nvert=垂直长度;
int i,j=0;
浮点数距离=数学无穷大;
对于(i=0,j=nvert-1;i 如果(((verty[i]除了边的情况外,你的代码现在还能工作吗?是的。除了多边形边和角上的点(或稍微偏离0.001f)之外,其他一切都可以正常工作。如果您的点最初有错误,则无法确定它们是否在多边形中。我的点没有错误-我会一步一步地显示它们(通过使用协程、Debug.Break()和Debug.DrawLine())它们被正确地投影到地板上。但是你提到投影后的2d点有~0.001的误差?你的代码除了边缘情况外现在还能工作吗?是的。一切都很好
public static float DistancePointLine2D(Vector2 point, Vector2 lineStart, Vector2 lineEnd)
{
return (ProjectPointLine2D(point, lineStart, lineEnd) - point).magnitude;
}
public static Vector2 ProjectPointLine2D(Vector2 point, Vector2 lineStart, Vector2 lineEnd)
{
Vector2 rhs = point - lineStart;
Vector2 vector2 = lineEnd - lineStart;
float magnitude = vector2.magnitude;
Vector2 lhs = vector2;
if (magnitude > 1E-06f)
{
lhs = (Vector2)(lhs / magnitude);
}
float num2 = Mathf.Clamp(Vector2.Dot(lhs, rhs), 0f, magnitude);
return (lineStart + ((Vector2)(lhs * num2)));
}
public static float ClosestDistanceToPolygon(Vector2[] verts, Vector2 point)
{
int nvert = verts.Length;
int i, j = 0;
float minDistance = Mathf.Infinity;
for (i = 0, j = nvert - 1; i < nvert; j = i++)
{
float distance = DistancePointLine2D(point, verts[i], verts[j]);
minDistance = Mathf.Min(minDistance, distance);
}
return minDistance;
}
public static bool IsInsidePolygon(Vector2[] vertices, Vector2 checkPoint, float margin = 0.01f)
{
if(ClosestDistanceToPolygon(vertices, checkPoint) < margin)
{
return true;
}
float[] vertX = new float[vertices.Length];
float[] vertY = new float[vertices.Length];
for (int i = 0; i < vertices.Length; i++)
{
vertX[i] = vertices[i].x;
vertY[i] = vertices[i].y;
}
return IsInsidePolygon(vertices.Length, vertX, vertY, checkPoint.x, checkPoint.y);
}
public static bool IsInsidePolygon(int nvert, float[] vertx, float[] verty, float testx, float testy)
{
bool c = false;
int i, j = 0;
for (i = 0, j = nvert - 1; i < nvert; j = i++)
{
if ((((verty[i] <= testy) && (testy < verty[j])) ||
((verty[j] <= testy) && (testy < verty[i]))) &&
(testx < (vertx[j] - vertx[i]) * (testy - verty[i]) / (verty[j] - verty[i]) + vertx[i]))
c = !c;
}
return c;
}