可可(不碰)碰撞检测两个圆圈

时间:2011-02-24 17:33:04

标签: objective-c cocoa collision-detection

我正在尝试检测两个圆圈的碰撞。当用户创建圆圈(按钮单击),然后在其中一个圆圈上单击鼠标以激活它时,该过程将起作用。鼠标单击活动圆圈外的任何位置都会将圆圈移动到鼠标单击的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:我正在进行一些碰撞检测,但这似乎只有当两个包含rects的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;
    }
   }

0 个答案:

没有答案