2014-02-13 2 views
2

Я два UIViews, один из которых вращают каждый .01 второй, используя следующий код:Обнаружения столкновений между повернутым UIViews

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

Теперь я хочу, чтобы иметь возможность сказать, если другой UIView, называется видом, пересекает прямоугольник. Я использовал этот код:

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

Существует, однако, проблема с этим, как вы, вероятно, знаете. Вот скриншот: enter image description here

В этом случае обнаружено столкновение, хотя очевидно, что они не касаются друг друга. Я огляделся, но я не могу найти реальный код для обнаружения этого столкновения. Как это может быть сделано? Будет полезен рабочий код для обнаружения столкновения в этом случае! Или, может быть, будет лучший класс для использования, кроме UIView?

+0

Я не знаю ответа, но причина, вероятно, сводится к тому, что никакие преобразования, применяемые к представлению, не подвержены кадру представления. – Jasarien

+0

Ok @Jasarien, знаете ли вы о лучшем классе, который я мог бы использовать, кроме UIView? –

+0

Я думаю, вы должны использовать какую-то фреймворк OpenGL, если вы планируете делать много чего.Если это случайно, вы все равно можете сделать некоторую арифметику. Но этот вид уже выполняется в большинстве игровых платформ. – AncAinu

ответ

2

при повороте вида, его граница не изменится 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}};

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

Поскольку кадр всегда возвращает маленьких вшита прямоугольника этой точки зрения.

Итак, в вашем случае, даже если хотя бы оба вида не пересекаются, их кадры пересекаются.

Для решения этой проблемы вы можете использовать, разделительная ось test. Если вы хотите узнать об этом, 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; 
} 

Надеется, что это помогает.

+0

Ничего себе. Больше, чем я мог надеяться. Я бы проголосовал за это миллион раз, если мог. БЛАГОДАРИМ ВАС ТАК БОЛЬШЕ @santhu! –

Смежные вопросы