检测旋转UIViews之间的冲突

我有两个UIViews,其中之一是旋转每0.01秒使用以下代码:

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

现在,我想知道另一个名为view的UIView是否与rectView相交。 我用这个代码:

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

但是,你可能知道有一个问题。 这是一个截图: 在这里输入图像说明

在这种情况下,检测到碰撞,尽pipe显然他们没有碰触。 我环顾四周,但我似乎无法find真正的代码来检测这种冲突。 如何才能做到这一点? 在这种情况下检测碰撞的工作代码将不胜感激! 或者也许会有比UIView更好的类使用?

当你旋转一个视图时,其边界将不会改变, but its frame changes.

所以,对于我的看法与backgroundColor蓝色,
我设定的最初的框架是

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

但是在旋转了45度之后,框架变成了

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

运行应用程序的屏幕截图显示蓝色视图的框架与黑色边框

因为该框架总是返回该视图的最小包围矩形

所以,在你的情况下,即使 – 虽然看起来两个视图不相交,他们的帧相交。

要解决它可以使用, 分离轴testing 。 如果你想了解它,请链接到这里

我试图解决它,并最终得到解决scheme。 如果你想检查,下面是代码。 将下面的代码复制粘贴到一个空的项目中来检查它。

在.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); px = -px;py=-py; CGPoint tL =CGPointApplyAffineTransform(p, t); tL.x +=rotatedView.center.x; tL.y +=rotatedView.center.y; px = -px; CGPoint tR =CGPointApplyAffineTransform(p, t); tR.x +=rotatedView.center.x; tR.y +=rotatedView.center.y; py=-py; CGPoint bR =CGPointApplyAffineTransform(p, t); bR.x +=rotatedView.center.x; bR.y +=rotatedView.center.y; px = -px; 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; } 

希望这可以帮助。