Ios Objective-C检查旋转UIView的子视图是否相交?

Ios Objective-C检查旋转UIView的子视图是否相交?,ios,objective-c,frame,intersection,separating-axis-theorem,Ios,Objective C,Frame,Intersection,Separating Axis Theorem,我不知道从哪里开始。显然,CGRectIntersectsRect在这种情况下不起作用,您将看到原因 我有一个UIView的子类,其中有一个UIImageView,它位于UIView的正中央: 然后旋转自定义UIView以保持内部UIImageView的框架,同时仍然能够执行CGAffineRotation。生成的帧如下所示: 我需要防止用户使这些UIImageView相交,但我不知道如何检查两个UIImageView之间的相交,因为它们的帧不仅不适用于父UIView,而且它们在旋转时不会影

我不知道从哪里开始。显然,
CGRectIntersectsRect
在这种情况下不起作用,您将看到原因

我有一个UIView的子类,其中有一个UIImageView,它位于UIView的正中央:

然后旋转自定义UIView以保持内部UIImageView的框架,同时仍然能够执行CGAffineRotation。生成的帧如下所示:

我需要防止用户使这些UIImageView相交,但我不知道如何检查两个UIImageView之间的相交,因为它们的帧不仅不适用于父UIView,而且它们在旋转时不会影响其帧

我尝试的唯一结果是没有成功


有什么想法吗?

以下算法可用于检查两个(旋转或变换)视图是否重叠:

  • 使用
    [view convertPoint:point to view:nil]
    转换两个视图的4个边界点 到公共坐标系(窗口坐标)
  • 转换点形成两个凸四边形
  • 使用来检查四边形是否相交
这是另一个包含伪代码的算法描述,更多可以通过谷歌搜索“分离轴定理”找到


更新:我试图为“分离轴定理”创建一个Objective-C方法,这就是我得到的。到目前为止,我只做了一些测试,所以我希望没有太多的错误

- (BOOL)convexPolygon:(CGPoint *)poly1 count:(int)count1 intersectsWith:(CGPoint *)poly2 count:(int)count2;
测试两个凸多边形是否相交。这两个多边形都作为顶点的
CGPoint
数组给出

- (BOOL)view:(UIView *)view1 intersectsWith:(UIView *)view2
测试(如上所述)两个任意视图是否相交

实施:

- (void)projectionOfPolygon:(CGPoint *)poly count:(int)count onto:(CGPoint)perp min:(CGFloat *)minp max:(CGFloat *)maxp
{
    CGFloat minproj = MAXFLOAT;
    CGFloat maxproj = -MAXFLOAT;
    for (int j = 0; j < count; j++) {
        CGFloat proj = poly[j].x * perp.x + poly[j].y * perp.y;
        if (proj > maxproj)
            maxproj = proj;
        if (proj < minproj)
            minproj = proj;
    }
    *minp = minproj;
    *maxp = maxproj;
}

-(BOOL)convexPolygon:(CGPoint *)poly1 count:(int)count1 intersectsWith:(CGPoint *)poly2 count:(int)count2
{
    for (int i = 0; i < count1; i++) {
        // Perpendicular vector for one edge of poly1:
        CGPoint p1 = poly1[i];
        CGPoint p2 = poly1[(i+1) % count1];
        CGPoint perp = CGPointMake(- (p2.y - p1.y), p2.x - p1.x);

        // Projection intervals of poly1, poly2 onto perpendicular vector:
        CGFloat minp1, maxp1, minp2, maxp2;
        [self projectionOfPolygon:poly1 count:count1 onto:perp min:&minp1 max:&maxp1];
        [self projectionOfPolygon:poly2 count:count1 onto:perp min:&minp2 max:&maxp2];

        // If projections do not overlap then we have a "separating axis"
        // which means that the polygons do not intersect:
        if (maxp1 < minp2 || maxp2 < minp1)
            return NO;
    }

    // And now the other way around with edges from poly2:
    for (int i = 0; i < count2; i++) {
        CGPoint p1 = poly2[i];
        CGPoint p2 = poly2[(i+1) % count2];
        CGPoint perp = CGPointMake(- (p2.y - p1.y), p2.x - p1.x);

        CGFloat minp1, maxp1, minp2, maxp2;
        [self projectionOfPolygon:poly1 count:count1 onto:perp min:&minp1 max:&maxp1];
        [self projectionOfPolygon:poly2 count:count1 onto:perp min:&minp2 max:&maxp2];

        if (maxp1 < minp2 || maxp2 < minp1)
            return NO;
    }

    // No separating axis found, then the polygons must intersect:
    return YES;
}

- (BOOL)view:(UIView *)view1 intersectsWith:(UIView *)view2
{
    CGPoint poly1[4];
    CGRect bounds1 = view1.bounds;
    poly1[0] = [view1 convertPoint:bounds1.origin toView:nil];
    poly1[1] = [view1 convertPoint:CGPointMake(bounds1.origin.x + bounds1.size.width, bounds1.origin.y) toView:nil];
    poly1[2] = [view1 convertPoint:CGPointMake(bounds1.origin.x + bounds1.size.width, bounds1.origin.y + bounds1.size.height) toView:nil];
    poly1[3] = [view1 convertPoint:CGPointMake(bounds1.origin.x, bounds1.origin.y + bounds1.size.height) toView:nil];

    CGPoint poly2[4];
    CGRect bounds2 = view2.bounds;
    poly2[0] = [view2 convertPoint:bounds2.origin toView:nil];
    poly2[1] = [view2 convertPoint:CGPointMake(bounds2.origin.x + bounds2.size.width, bounds2.origin.y) toView:nil];
    poly2[2] = [view2 convertPoint:CGPointMake(bounds2.origin.x + bounds2.size.width, bounds2.origin.y + bounds2.size.height) toView:nil];
    poly2[3] = [view2 convertPoint:CGPointMake(bounds2.origin.x, bounds2.origin.y + bounds2.size.height) toView:nil];

    return [self convexPolygon:poly1 count:4 intersectsWith:poly2 count:4];
}
-(void)projectionOfPolygon:(CGPoint*)多边形计数:(int)计数到:(CGPoint)perp min:(CGFloat*)minp max:(CGFloat*)maxp
{
CGFloat minproj=最大浮点;
CGFloat maxproj=-maxploat;
对于(int j=0;j最大项目)
maxproj=proj;
如果(项目<最小项目)
minproj=proj;
}
*minp=minproj;
*maxp=maxproj;
}
-(BOOL)凸多边形:(CGPoint*)poly1计数:(int)计数1与:(CGPoint*)poly2计数:(int)计数2相交
{
对于(int i=0;i
太棒了!非常感谢你@MartinR I根据这个问题/答案提出了一个新问题。“想知道你是否可以看一看吗?”马丁纳解释得很好。刚刚实现的代码,它的工作非常完美。谢谢!跟进问题。如何计算旋转UIView与非旋转UIView重叠的百分比?对不起,我没有答案。但我不认为有一个简单的公式。