gpt4 book ai didi

ios - 检测旋转的 UIView 之间的碰撞

转载 作者:塔克拉玛干 更新时间:2023-11-02 20:07:47 27 4
gpt4 key购买 nike

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

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

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

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

然而,正如您可能知道的那样,这有一个问题。这是一个截图: enter image description here

在这种情况下,检测到碰撞,即使它们显然没有接触。我环顾四周,但似乎找不到真正的代码来检测这种碰撞。如何才能做到这一点?在这种情况下检测碰撞的工作代码将不胜感激!或者除了 UIView 之外还有更好的类可供使用吗?

最佳答案

当您旋转 View 时,它的边界不会改变但它的框架会改变。

所以,对于我的 backgroundColor blue View ,
我设置的初始帧是

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

但是旋转45度之后,frame变成了

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

screenshot of running app showing frame of blue view with black border

Because the frame always return the smallest enclosing rectangle of that view.

因此,在您的情况下,即使看起来两个 View 不相交,但它们的框架相交。

要解决这个问题,您可以使用分离轴测试。如果你想学习它,link here

我尝试解决,终于得到了解决方案。如果您想检查,下面是代码。将以下代码复制粘贴到一个空项目中以进行检查。

在.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;
}

希望这对您有所帮助。

关于ios - 检测旋转的 UIView 之间的碰撞,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21758271/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com