Objective-C检查旋转的UIView的子视图是否相交? [英] Objective-C check if subviews of rotated UIViews intersect?

查看:81
本文介绍了Objective-C检查旋转的UIView的子视图是否相交?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我不知道从哪里开始.显然,CGRectIntersectsRect在这种情况下不起作用,您会明白为什么.

I don't know where to start with this one. Obviously CGRectIntersectsRect will not work in this case, and you'll see why.

我有一个UIView的子类,该子类中有一个UIImageView,它位于UIView的确切中心:

I have a subclass of UIView that has a UIImageView inside it that is placed in the exact center of the UIView:

然后,我旋转自定义UIView来维护内部UIImageView的框架,同时仍然能够执行CGAffineRotation.结果框架看起来像这样:

I then rotate the custom UIView to maintain the frame of the inner UIImageView while still being able to perform a CGAffineRotation. The resulting frame looks something like this:

我需要防止用户使这些UIImageViews相交,但是我不知道如何检查两个UIImageViews之间的相交,因为它们的框架不仅不适用于父级UIView,而且还可以旋转而不会影响它们他们的框架.

I need to prevent users from making these UIImageViews intersect, but I have no idea how to check intersection between the two UIImageViews, since not only do their frames not apply to the parent UIView, but also, they are rotated without it affecting their frames.

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

The only results from my attempts have been unsuccessful.

有什么想法吗?

推荐答案

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

The following algorithm can be used to check if two (rotated or otherwise transformed) views overlap:

  • 使用[view convertPoint:point toView:nil]转换两个视图的4个边界点 到通用坐标系(窗口坐标).
  • 转换后的点形成两个凸四边形.
  • 使用 SAT(分离轴定理)检查四边形是否相交.
  • Use [view convertPoint:point toView:nil] to convert the 4 boundary points of both views to a common coordinate system (the window coordinates).
  • The converted points form two convex quadrilaterals.
  • Use the SAT (Separating Axis Theorem) to check if the quadrilaterals intersect.

此: http://www.geometrictools.com/Documentation/MethodOfSeparatingAxes.pdf 是对包含伪代码的算法,可以通过谷歌搜索分离轴定理"找到更多的方法.

This: http://www.geometrictools.com/Documentation/MethodOfSeparatingAxes.pdf is another description of the algorithm containing pseudo-code, more can be found by googling for "Separating Axis Theorem".

更新:我试图为分离轴定理"创建一个Objective-C方法,这就是我所得到的.到现在为止,我只进行了几次测试,所以希望不会出现太多错误.

Update: I have tried to create a Objective-C method for the "Separating Axis Theorem", and this is what I got. Up to now, I did only a few tests, so I hope that there are not too many errors.

- (BOOL)convexPolygon:(CGPoint *)poly1 count:(int)count1 intersectsWith:(CGPoint *)poly2 count:(int)count2;

测试2个凸多边形是否相交.这两个多边形均以顶点的CGPoint数组形式给出.

tests if 2 convex polygons intersect. Both polygons are given as a CGPoint array of the vertices.

- (BOOL)view:(UIView *)view1 intersectsWith:(UIView *)view2

测试(如上所述)两个任意视图是否相交.

tests (as described above) if two arbitrary views intersect.

实施:

- (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];
}

这篇关于Objective-C检查旋转的UIView的子视图是否相交?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆