Anjali jariwala
Anjali jariwala

Reputation: 445

Get CGPoint if line intersects CGRect

I have one task, which having Floormap sketch. There are different products rack available. I need to draw path from user location to user's Wishlist product's rack.

Currently, I can draw line from source to destination (user location to user's Wishlist product's rack). But its just straight line, I need to draw accurate path like if there is any rack in between line, line does not overlapped.

path drawn from source to destination

Here is my Code :

for (int i = 0; i < arrAllRackPosition.count; i++) {
    if ([self RectContainsLineRect:[arrAllRackPosition[i] CGRectValue] StartPoint:CGPointMake(X + HALF(width) + distance, Y) EndPoint:CGPointMake(destX, destY)]) {

        //check rack point where line intersect
        NSLog(@"Line start point : %@",NSStringFromCGPoint(CGPointMake(X + HALF(width) + distance, Y)));
        NSLog(@"Line end point : %@",NSStringFromCGPoint(CGPointMake(destX, destY)));
        NSLog(@"Path Intersect Rack : %@",NSStringFromCGRect([arrAllRackPosition[i] CGRectValue]));
    }
    else
    {
        NSLog(@"path not intersect");
    }
}

Now I need to get CGPoint where line intersect to rack For better understanding refer image.

If anyone have idea about it, please answer with code example.

Upvotes: 0

Views: 368

Answers (1)

Michael Dautermann
Michael Dautermann

Reputation: 89509

If you're not afraid of using open source code, there's a library that you can take advantage of that does this work for you: MTGeometry

And the function that you want to use is:

CGPoint CGLineIntersectsRectAtPoint(CGRect rect, CGLine line);

This is actually a C function that looks like this:

CGPoint CGLineIntersectsRectAtPoint(CGRect rect, CGLine line)
{
    CGLine top      = CGLineMake( CGPointMake( CGRectGetMinX(rect), CGRectGetMinY(rect) ), CGPointMake( CGRectGetMaxX(rect), CGRectGetMinY(rect) ) );
    CGLine right    = CGLineMake( CGPointMake( CGRectGetMaxX(rect), CGRectGetMinY(rect) ), CGPointMake( CGRectGetMaxX(rect), CGRectGetMaxY(rect) ) );
    CGLine bottom   = CGLineMake( CGPointMake( CGRectGetMinX(rect), CGRectGetMaxY(rect) ), CGPointMake( CGRectGetMaxX(rect), CGRectGetMaxY(rect) ) );
    CGLine left     = CGLineMake( CGPointMake( CGRectGetMinX(rect), CGRectGetMinY(rect) ), CGPointMake( CGRectGetMinX(rect), CGRectGetMaxY(rect) ) );

    // ensure the line extends beyond outside the rectangle
    CGFloat topLeftToBottomRight = CGPointDistance(CGRectTopLeftPoint(rect), CGRectBottomRightPoint(rect));
    CGFloat bottomLeftToTopRight = CGPointDistance(CGRectBottomLeftPoint(rect), CGRectTopRightPoint(rect));
    CGFloat maxDimension = MT_MAX(topLeftToBottomRight, bottomLeftToTopRight);
    CGFloat scaleFactor = maxDimension / MT_MIN(CGLineLength(line), maxDimension);
    CGLine extendedLine = CGLineScale(line, scaleFactor + 3);

    CGPoint points[4] = { CGLinesIntersectAtPoint(top, extendedLine), CGLinesIntersectAtPoint(right, extendedLine), CGLinesIntersectAtPoint(bottom, extendedLine), CGLinesIntersectAtPoint(left, extendedLine) };

    for (int i = 0; i < 4; i++) {
        CGPoint p = points[i];
        if (!CGPointEqualToPoint(p, NULL_POINT)) {
            return p;
        }
    }

    return NULL_POINT;
}

You can potentially simply pick up and drop this function into your own code with some minor modifications (changing the C interface to be Objective-C, define MT_MAX and NULL_POINT), but the easier thing to do would be to simply compile the .c file along with the rest of your project.

Upvotes: 1

Related Questions