ios - 如何发现 2 CGPath roteted rects 是否相交?

标签 ios objective-c cgpath

加载 View Controller 时,我正在构建 2 个矩形,使用 CGPath .可以使用 PanGestureRecognizer 移动矩形.问题是我怎么知道 2 rects 何时相遇?为了不让它们相交?

MainViewController.m

- (void)viewDidLoad
{
    [super viewDidLoad];

    for (int i=0; i< 2; i++) {
        //create rects of CGPath
        CGRectCustomView* randomColorRect = 
                                [[CGRectCustomView alloc]initWithFrame: 
                                CGRectMake(<random place on screen>)];
        //random angle
        randomColorRect.transform = 
                                CGAffineTransformMakeRotation
                                (DegreesToRadians([Shared randomIntBetween:0 and:360]));

        [self.view addSubview:randomColorRect];

    }

}

- (BOOL)areRectsCollide {

      ???How to find this???

}

CGRectCustomView.m:
- (void)drawRect:(CGRect)rect
{
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSetLineWidth(context, 8.0); 
    CGContextStrokePath(context); // do actual stroking
    CGContextSetRGBFillColor(context, <green color>, 1); 
    CGContextFillRect(context, CGRectMake(self.frame.origin.x, self.frame.origin.y, self.frame.size.width, self.frame.size.height)); 
    path = CGContextCopyPath(context);
}

在苹果指南 here ,有一个函数可以判断路径是否包含点
- (BOOL)containsPoint:(CGPoint)point onPath:(UIBezierPath *)path inFillArea:(BOOL)inFil ,

但我有一个矩形,它的点数是无穷无尽的。所以我该怎么做?打破我的头...

最佳答案

找到了!
我使用了描述的算法here .
只有一件事:我在屏幕上移动矩形。所以为了让他们在第一次碰撞后不堆叠,我保存最后一个未碰撞的点,如果碰撞原告,我恢复最后一个位置。

- (void)handlePan:(UIPanGestureRecognizer *)recognizer {
    BOOL rectsColide = NO;

    for (RandomColorRect* buttonRectInStoredRects in arreyOfPaths) {
        if (buttonRectInStoredRects.tag != recognizer.view.tag) {
            if ([self view:buttonRectInStoredRects intersectsWith:recognizer.view]) {
                rectsColide = YES;
            }
        }
    }

    CGPoint translation = [recognizer translationInView:self.view];

    if (!rectsColide) {
        lastPoint = recognizer.view.center;
        recognizer.view.center = CGPointMake(recognizer.view.center.x + translation.x,
                                             recognizer.view.center.y + translation.y);
    }else{
        recognizer.view.center = CGPointMake(lastPoint.x ,lastPoint.y);
    }

    [recognizer setTranslation:CGPointMake(0, 0) inView:self.view];
}



- (void)projectionOfPolygon:(CGPoint *)poly count:(int)count onto:(CGPoint)perp min:(CGFloat *)minp max:(CGFloat *)maxp
{
    CGFloat minproj = MAXFLOAT;
    CGFloat maxproj = -MAXFLOAT;
    for (int j = 0; j < count; j++) {
        CGFloat proj = poly[j].x * perp.x + poly[j].y * perp.y;
        if (proj > maxproj)
            maxproj = proj;
        if (proj < minproj)
            minproj = proj;
    }
    *minp = minproj;
    *maxp = maxproj;
}

-(BOOL)convexPolygon:(CGPoint *)poly1 count:(int)count1 intersectsWith:(CGPoint *)poly2 count:(int)count2
{
    for (int i = 0; i < count1; i++) {
        // Perpendicular vector for one edge of poly1:
        CGPoint p1 = poly1[i];
        CGPoint p2 = poly1[(i+1) % count1];
        CGPoint perp = CGPointMake(- (p2.y - p1.y), p2.x - p1.x);

        // Projection intervals of poly1, poly2 onto perpendicular vector:
        CGFloat minp1, maxp1, minp2, maxp2;
        [self projectionOfPolygon:poly1 count:count1 onto:perp min:&minp1 max:&maxp1];
        [self projectionOfPolygon:poly2 count:count1 onto:perp min:&minp2 max:&maxp2];

        // If projections do not overlap then we have a "separating axis"
        // which means that the polygons do not intersect:
        if (maxp1 < minp2 || maxp2 < minp1)
            return NO;
    }

    // And now the other way around with edges from poly2:
    for (int i = 0; i < count2; i++) {
        CGPoint p1 = poly2[i];
        CGPoint p2 = poly2[(i+1) % count2];
        CGPoint perp = CGPointMake(- (p2.y - p1.y), p2.x - p1.x);

        CGFloat minp1, maxp1, minp2, maxp2;
        [self projectionOfPolygon:poly1 count:count1 onto:perp min:&minp1 max:&maxp1];
        [self projectionOfPolygon:poly2 count:count1 onto:perp min:&minp2 max:&maxp2];

        if (maxp1 < minp2 || maxp2 < minp1)
            return NO;
    }

    // No separating axis found, then the polygons must intersect:
    return YES;
}

- (BOOL)view:(UIView *)view1 intersectsWith:(UIView *)view2
{
    CGPoint poly1[4];
    CGRect bounds1 = view1.bounds;
    poly1[0] = [view1 convertPoint:bounds1.origin toView:nil];
    poly1[1] = [view1 convertPoint:CGPointMake(bounds1.origin.x + bounds1.size.width, bounds1.origin.y) toView:nil];
    poly1[2] = [view1 convertPoint:CGPointMake(bounds1.origin.x + bounds1.size.width, bounds1.origin.y + bounds1.size.height) toView:nil];
    poly1[3] = [view1 convertPoint:CGPointMake(bounds1.origin.x, bounds1.origin.y + bounds1.size.height) toView:nil];

    CGPoint poly2[4];
    CGRect bounds2 = view2.bounds;
    poly2[0] = [view2 convertPoint:bounds2.origin toView:nil];
    poly2[1] = [view2 convertPoint:CGPointMake(bounds2.origin.x + bounds2.size.width, bounds2.origin.y) toView:nil];
    poly2[2] = [view2 convertPoint:CGPointMake(bounds2.origin.x + bounds2.size.width, bounds2.origin.y + bounds2.size.height) toView:nil];
    poly2[3] = [view2 convertPoint:CGPointMake(bounds2.origin.x, bounds2.origin.y + bounds2.size.height) toView:nil];

    return [self convexPolygon:poly1 count:4 intersectsWith:poly2 count:4];
}

关于ios - 如何发现 2 CGPath roteted rects 是否相交?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19074669/

相关文章:

ios - 未收到 GCM 推送通知

ios - 将UIView添加到ScrollView进行分页

iphone - 在sqlite3_step行上崩溃?

ios - 在 UITableViewCell 中使用高分辨率图像进行自定义滑动机制

iphone - 在后台执行 Selector 并获取返回字符串

objective-c - block 和 ARC - 发布版本复制或崩溃(由优化级别引起)

ios - 查找 : "This application is modifying the autolayout engine from a background thread after the engine was accessed from the main thread." 的原因

ios - CAAnimation 期间的位置

iphone - 绘制先前准备好的 CGPath 时,CATiledLayer 崩溃

objective-c - iOS 核心图形 : Draw ONLY shadows of a CGPath