我正在为Pixelsense创建一个WPF应用程序,我有七个多边形。我可以用触摸来移动它们。目前它们彼此重叠,如下图1所示。
我想要一个形状(形状A)不与另一个形状(形状B)重叠,而是它应该卡入到位(形状A和形状B最终并排或彼此上下)当接近时如下所示。
我已经搜索过类似问题的StackOverflow,但是,我只能找到一些与检查点或鼠标是否在形状内相关的链接。不是为了完整的形状重叠或关于如何将它们卡入到位。
有没有人对我如何做到这一点有任何想法?任何帮助将不胜感激。
答案 0 :(得分:0)
如果我们假设您使用多边形,这里有一些检测重叠的解决方案;
public static bool PointCollectionsOverlap_Slow(PointCollection area1, PointCollection area2)
{
PathGeometry pathGeometry1 = GetPathGeometry(area1);
PathGeometry pathGeometry2 = GetPathGeometry(area2);
bool result = pathGeometry1.FillContainsWithDetail(pathGeometry2) != IntersectionDetail.Empty;
return result;
}
public static PathGeometry GetPathGeometry(PointCollection polygonCorners)
{
List<PathSegment> pathSegments = new List<PathSegment> { new PolyLineSegment(polygonCorners, true) };
PathGeometry pathGeometry = new PathGeometry();
pathGeometry.Figures.Add(new PathFigure(polygonCorners[0], pathSegments, true));
return pathGeometry;
}
更快一点;
public static bool PointCollectionsOverlap_Fast(PointCollection area1, PointCollection area2)
{
for (int i = 0; i < area1.Count; i++)
{
for (int j = 0; j < area2.Count; j++)
{
if (lineSegmentsIntersect(area1[i], area1[(i + 1) % area1.Count], area2[j], area2[(j + 1) % area2.Count]))
{
return true;
}
}
}
if (PointCollectionContainsPoint(area1, area2[0]) ||
PointCollectionContainsPoint(area2, area1[0]))
{
return true;
}
return false;
}
public static bool PointCollectionContainsPoint(PointCollection area, Point point)
{
Point start = new Point(-100, -100);
int intersections = 0;
for (int i = 0; i < area.Count; i++)
{
if (lineSegmentsIntersect(area[i], area[(i + 1) % area.Count], start, point))
{
intersections++;
}
}
return (intersections % 2) == 1;
}
private static double determinant(Vector vector1, Vector vector2)
{
return vector1.X * vector2.Y - vector1.Y * vector2.X;
}
private static bool lineSegmentsIntersect(Point _segment1_Start, Point _segment1_End, Point _segment2_Start, Point _segment2_End)
{
double det = determinant(_segment1_End - _segment1_Start, _segment2_Start - _segment2_End);
double t = determinant(_segment2_Start - _segment1_Start, _segment2_Start - _segment2_End) / det;
double u = determinant(_segment1_End - _segment1_Start, _segment2_Start - _segment1_Start) / det;
return (t >= 0) && (u >= 0) && (t <= 1) && (u <= 1);
}