Какао (не сенсорный) обнаружение столкновения двух кругов - PullRequest
2 голосов
/ 24 февраля 2011

Я пытаюсь обнаружить столкновение двух кругов. Процесс работает, когда пользователь создает круги (нажатие кнопки), а затем щелкает мышью один из кругов, чтобы активировать его. Если щелкнуть мышью в любом месте за пределами активного круга, он будет перемещен по оси x, y щелчка мыши. Что я хочу сделать, так это остановить движение, если на пути активного круга есть еще один круг.

NSPoint P = щелчок мыши (передается через центр уведомлений)
activeView = выбранный круг (подкласс NSView)

Мой процесс состоит в том, чтобы получить точку для перемещения, определить направление движения на основе начальной и конечной точек, а также количество приращений для x начальной и конечной точек, выполнить цикл по шагам, использовать метод аниматора NSView для перемещения вида, переберите все неактивные виды (все остальные круги) и сравните их положение с текущей позицией активного вида, используя формулу ((x1 * x2) + (x1 * x2)) + (y1 * y2) + (y1 * y2) и сравнивая с квадратом радиуса обоих кругов (круги в прямоугольнике 30x30 с 4-пиксельным штрихом на кругах, поэтому я использовал 26 для проверки радиуса (26 * 26) .

У меня есть пара вопросов (помимо моего желания заново изобрести колесо: D - это для меня учебное упражнение):

1: часть кода движения действительно работает отлично. Тем не менее, я хотел бы получить центральную точку круга при щелчке мыши, сейчас круг останавливается, так что содержащая его NSRect (30x30) x, y координата находится при щелчке мыши (это не переворачивается, поэтому его нижний левый).

2: Я получаю определенное обнаружение столкновений, но, похоже, это происходит только тогда, когда пересекаются x, y обоих содержащих рец, а не ребер окружности.

3: Я не имею отношения ко всему этому, у меня есть NSColor для содержащих ректов, установленный на clearColor, и они изначально запускаются таким образом, но затем, когда я перемещаю их, они возвращаются к цвету по умолчанию (этот серый цвет). Нужно ли присваивать clearColor каждый раз, когда представление перерисовывается?

Спасибо за помощь.

  hasCollision = NO;

   //get point clicked  value
   NSValue* pVal = [[notification userInfo] objectForKey:@"dataPoint"];

   //convert value to point (end point)
   NSPoint p = [pVal pointValue];

   //get activeView frame
   NSRect avFrame = [activeView frame];
   float startX = avFrame.origin.x; //x1
   float startY = avFrame.origin.y; //y1
   float endX = p.x; //x2
   float endY = p.y; //y2

   //set direction of activeView movement
   if (endX > startX && endY > startY) { 
          //NSLog(@"endXY > startXY");
          cStart = startX;
          cCheck  =endX;
           distanceX = endX - startX;
            incrementY = (endY - startY)/distanceX;
   } else if (endX < startX && endY > startY) {
           //NSLog(@"endX<startX, endY>startY");
           cStart = endX;
           cCheck  =startX;
           distanceX = startX - endX;
           incrementY = (endY - startY)/distanceX;
   } else if (endX < startX && endY < startY) { 
           //NSLog(@"endX<startX, endY<startY");
           cStart = endX;
           cCheck  =startX;
           distanceX = startX - endX;
           incrementY = (startY - endY)/distanceX;
   } else { 
           //NSLog(@"endX>startX, endY<startY");
           cStart = startX;
           cCheck  =endX;
          distanceX = endX - startX;
           incrementY = (startY - endY)/distanceX;
   }


   //NSLog(@"Start:%f:%f:End%f:%f:::distance=%f:::Y Increment=%f", startX, startY, endX, endY, distanceX, incrementY);

   float currentX = startX;
   float currentY = startY;

   for(int c=cStart; c<cCheck; c++) {

    //get move coordinates
    if (endX > startX && endY > startY) { 
        currentX++;
        currentY = currentY + incrementY;
    } else if (endX < startX && endY > startY) { 
        currentX--;
        currentY = currentY + incrementY;
    } else if (endX < startX && endY < startY) { 
        currentX--;
        currentY = currentY - incrementY;
    } else { 
        currentX++;
        currentY = currentY - incrementY;
    }

    //move view
    [[activeView animator] setFrame:NSMakeRect(currentX, currentY, avFrame.size.width, avFrame.size.height)];

    //make a rect for each object
    NSRect avRect = [activeView frame];

    //store previous positions
    prevPos = [activeView frame];

    //check for collisions
    for(int v=0; v<[createdViewsDict count]; v++) {

        //get the id of the view in the dict
        NSString* nextNum = [NSString stringWithFormat:@"circle_%i", v+1];
        //init a view and assign it to the next view in the dict
        NSView* thisView = [createdViewsDict objectForKey:nextNum];
        //make sure this view is not our active view
        if (thisView != activeView) { 
            NSRect tvRect = [thisView frame];

            //get the xy coordinates to compare
            float x1 = avRect.origin.x;
            float y1 = avRect.origin.y;
            float x2 = tvRect.origin.x;
            float y2 = tvRect.origin.y;

            float radius = 26.0;

            float dx = x2-x1;
            float dy = y2-y1;
            float radii = radius + radius; 
            if ( ( dx * dx )  + ( dy * dy ) < radii * radii ) {
                hasCollision = YES;
                //[[activeView animator] setFrame:NSMakeRect(prevPos.origin.x, prevPos.origin.y, avFrame.size.width, avFrame.size.height)];
                NSLog(@"Collision!!Moving object coords:x=%f,y=%f,:::::::::Stationary object coords:x=%f,y=%f", avRect.origin.x, avRect.origin.y, tvRect.origin.x, tvRect.origin.y);
            }

            /*
             //check for collision
            NSRect collisionRect = NSIntersectionRect(avRect, tvRect);
            //move circle to previous
            if ( !NSIsEmptyRect(collisionRect) ) {
                hasCollision = YES;
                [[activeView animator] setFrame:NSMakeRect(prevPos.origin.x, prevPos.origin.y, avFrame.size.width, avFrame.size.height)];
                NSLog(@"Collision!!Moving object coords:x=%f,y=%f,:::::::::Stationary object coords:x=%f,y=%f", avRect.origin.x, avRect.origin.y, tvRect.origin.x, tvRect.origin.y);
            }
             */
        }
    }

    if(hasCollision == YES) {
        [[activeView animator] setFrame:NSMakeRect(prevPos.origin.x - 20.0, prevPos.origin.y - 20.0, avFrame.size.width, avFrame.size.height)];
        hasCollision = NO;
        break;
    }
   }
...