检测旋转的UIView之间的冲突

塞缪尔·诺耶斯(Samuel Noyes)

我有两个UIView,其中的一个使用以下代码每0.01秒旋转一次:

    self.rectView.transform = CGAffineTransformRotate(self.rectView.transform, .05);

现在,我想知道另一个UIView(称为view)是否与rectView相交。我使用了以下代码:

if(CGRectIntersectsRect(self.rectView.frame, view.frame)) {
    //Intersection
}

如您所知,这是有问题的。这是屏幕截图:在此处输入图片说明

在这种情况下,即使很明显它们没有接触,也会检测到碰撞。我环顾四周,但似乎找不到真正的代码来检测此冲突。如何才能做到这一点?在这种情况下,用于检测碰撞的工作代码将不胜感激!或者,也许还有比UIView更好的类可以使用?

桑图

旋转视图时,其范围不会改变 but its frame changes.

因此,对于我使用backgroundColor blue的视图,
我设置为的初始帧是

框架=(30,150,150,35);
bounds = {{0,0},{150,35}};

但旋转45度后,框架变为

框架=(39.5926 102.093; 130.815 130.815);
bounds = {{0,0},{150,35}};

正在运行的应用程序的屏幕快照,显示带有黑色边框的蓝色视图框架

因为框架始终返回该视图最小封闭矩形

因此,就您而言,即使看起来两个视图都不相交,它们的框架也相交。

为了解决这个问题,您可以使用分离轴测试如果您想学习,请在这里链接

我试图解决它,最后得到了解决方案。如果您想检查,下面是代码。复制以下代码,将其粘贴到一个空项目中以将其签出。

在.m文件中

@implementation ViewController{
    UIView *nonRotatedView;
    UIView *rotatedView;
}

- (void)viewDidLoad
{
    [super viewDidLoad];
    nonRotatedView =[[UIView alloc] initWithFrame:CGRectMake(120, 80, 150, 40)];
    nonRotatedView.backgroundColor =[UIColor blackColor];
    [self.view addSubview:nonRotatedView];

    rotatedView =[[UIView alloc] initWithFrame:CGRectMake(30, 150, 150, 35)];
    rotatedView.backgroundColor =[UIColor blueColor];
    [self.view addSubview:rotatedView];
    CGAffineTransform t=CGAffineTransformMakeRotation(M_PI_4);
    rotatedView.transform=t;

    CAShapeLayer *layer =[CAShapeLayer layer];
    [layer setFrame:rotatedView.frame];
    [self.view.layer addSublayer:layer];
    [layer setBorderColor:[UIColor blackColor].CGColor];
    [layer setBorderWidth:1];

    CGPoint p=CGPointMake(rotatedView.bounds.size.width/2, rotatedView.bounds.size.height/2);

    p.x = -p.x;p.y=-p.y;
    CGPoint tL =CGPointApplyAffineTransform(p, t);
    tL.x +=rotatedView.center.x;
    tL.y +=rotatedView.center.y;

    p.x = -p.x;
    CGPoint tR =CGPointApplyAffineTransform(p, t);
    tR.x +=rotatedView.center.x;
    tR.y +=rotatedView.center.y;

    p.y=-p.y;
    CGPoint bR =CGPointApplyAffineTransform(p, t);
    bR.x +=rotatedView.center.x;
    bR.y +=rotatedView.center.y;

    p.x = -p.x;
    CGPoint bL =CGPointApplyAffineTransform(p, t);
    bL.x +=rotatedView.center.x;
    bL.y +=rotatedView.center.y;


    //check for edges of nonRotated Rect's edges
    BOOL contains=YES;
    CGFloat value=nonRotatedView.frame.origin.x;
    if(tL.x<value && tR.x<value && bR.x<value && bL.x<value)
        contains=NO;
    value=nonRotatedView.frame.origin.y;
    if(tL.y<value && tR.y<value && bR.y<value && bL.y<value)
        contains=NO;
    value=nonRotatedView.frame.origin.x+nonRotatedView.frame.size.width;
    if(tL.x>value && tR.x>value && bR.x>value && bL.x>value)
        contains=NO;
    value=nonRotatedView.frame.origin.y+nonRotatedView.frame.size.height;
    if(tL.y>value && tR.y>value && bR.y>value && bL.y>value)
        contains=NO;

    if(contains==NO){
        NSLog(@"no intersection 1");
        return;
    }
    //check for roatedView's edges
    CGPoint rotatedVertexArray[]={tL,tR,bR,bL,tL,tR};

    CGPoint nonRotatedVertexArray[4];
    nonRotatedVertexArray[0]=CGPointMake(nonRotatedView.frame.origin.x,nonRotatedView.frame.origin.y);
    nonRotatedVertexArray[1]=CGPointMake(nonRotatedView.frame.origin.x+nonRotatedView.frame.size.width,nonRotatedView.frame.origin.y);
    nonRotatedVertexArray[2]=CGPointMake(nonRotatedView.frame.origin.x+nonRotatedView.frame.size.width,nonRotatedView.frame.origin.y+nonRotatedView.frame.size.height);
    nonRotatedVertexArray[3]=CGPointMake(nonRotatedView.frame.origin.x,nonRotatedView.frame.origin.y+nonRotatedView.frame.size.height);

    NSInteger i,j;
    for (i=0; i<4; i++) {
        CGPoint first=rotatedVertexArray[i];
        CGPoint second=rotatedVertexArray[i+1];
        CGPoint third=rotatedVertexArray[i+2];
        CGPoint mainVector =CGPointMake(second.x-first.x, second.y-first.y);
        CGPoint selfVector =CGPointMake(third.x-first.x, third.y-first.y);
        BOOL sign;
        sign=[self crossProductOf:mainVector withPoint:selfVector];
        for (j=0; j<4; j++) {
            CGPoint otherPoint=nonRotatedVertexArray[j];
            CGPoint otherVector = CGPointMake(otherPoint.x-first.x, otherPoint.y-first.y);
            BOOL checkSign=[self crossProductOf:mainVector withPoint:otherVector];
            if(checkSign==sign)
                break;
            else if (j==3)
                contains=NO;
        }
        if(contains==NO){
            NSLog(@"no intersection 2");
            return;
        }
    }
    NSLog(@"intersection");
}


-(BOOL)crossProductOf:(CGPoint)point1 withPoint:(CGPoint)point2{
    if((point1.x*point2.y-point1.y*point2.x)>=0)
         return YES;
    else
        return NO;
}

希望这可以帮助。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

检测旋转的UIView之间的冲突

来自分类Dev

在UIView子类中检测自动旋转

来自分类Dev

检测数组中对象之间的冲突

来自分类Dev

Android,如何检查两个旋转视图之间的冲突

来自分类Dev

如何检测DOM可拖动对象与FabricJS形状之间的冲突

来自分类Dev

如何检测两个阵列之间的冲突?

来自分类Dev

如何检测SKSpriteNode和SKView SpriteKit之间的冲突

来自分类Dev

具有不同父级的对象之间的JavaFX冲突检测

来自分类Dev

检测 PNG 图片和矩形 JavaScript 之间的冲突

来自分类Dev

使用CSS动画旋转的图像之间的碰撞检测

来自分类Dev

在两个不同的数组之间检测并使用冲突检测以删除它们的实例

来自分类Dev

Python冲突检测

来自分类Dev

文字冲突检测

来自分类Dev

文字冲突检测

来自分类Dev

JavaScript冲突检测的优化

来自分类Dev

如何使用Three.js检测JavaScript中两个对象之间的冲突?

来自分类Dev

如何检测许多中的任何两个jQuery可拖动div之间的元素冲突?

来自分类Dev

在Swift 3.0中检测到两个对象之间的冲突?

来自分类Dev

使用CGAffineTransformMakeRotation旋转UIView

来自分类Dev

旋转后平移UIView

来自分类Dev

UIView 在旋转时消失

来自分类Dev

Android屏幕旋转检测

来自分类Dev

检测旋转的车辆图像

来自分类Dev

如何检测旋转的弧度?

来自分类Dev

检测哪个uiview被触摸

来自分类Dev

点击事件之间的冲突

来自分类Dev

协议之间的实现冲突

来自分类Dev

处理颜色冲突检测(java)

来自分类Dev

HHVM检测到的冲突配置