Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Intersection between two lines in coordinates

I can detect the intersection point of two lines, but if my line don't has the length of my screen, it detects the point, where it shouldn't be.

Here a preview: Intersection So, it shouldn't detect this intersection because the horizontal line isn't that long.

Code:

- (NSMutableArray *) intersectWithLines:(CGPoint)startPoint andEnd:(CGPoint)endPoint {
    NSMutableArray *intersects = [[NSMutableArray alloc] init];

    for(GameLine *line in [_lineBackground getLines]) {

        double lineStartX = line.startPos.x;
        double lineStartY = line.startPos.y;
        double tempEndX = line.endPos.x;
        double tempEndY = line.endPos.y;

        double d = ((startPoint.x - endPoint.x)*(lineStartY - tempEndY)) - ((startPoint.y - endPoint.y) * (lineStartX - tempEndX));

        if(d != 0) {            
            double sX = ((lineStartX - tempEndX) * (startPoint.x * endPoint.y - startPoint.y * endPoint.x) - (startPoint.x - endPoint.x) * (lineStartX * tempEndY - lineStartY * tempEndX)) / d;
            double sY = ((lineStartY - tempEndY) * (startPoint.x * endPoint.y - startPoint.y * endPoint.x) - (startPoint.y - endPoint.y) * (lineStartX * tempEndY - lineStartY * tempEndX)) / d;


            if([self isValidCGPoint:CGPointMake(sX, sY)]) {
                [intersects addObject:[NSValue valueWithCGPoint:CGPointMake(sX, sY)]];
            }            
        }
    }

    return intersects;
}
like image 532
Christian 'fuzi' Orgler Avatar asked Mar 28 '13 19:03

Christian 'fuzi' Orgler


3 Answers

If I understand your question correctly, you need to determine the intersection point of two line segments. This should work with the following method:

- (NSValue *)intersectionOfLineFrom:(CGPoint)p1 to:(CGPoint)p2 withLineFrom:(CGPoint)p3 to:(CGPoint)p4
{
    CGFloat d = (p2.x - p1.x)*(p4.y - p3.y) - (p2.y - p1.y)*(p4.x - p3.x);
    if (d == 0)
        return nil; // parallel lines
    CGFloat u = ((p3.x - p1.x)*(p4.y - p3.y) - (p3.y - p1.y)*(p4.x - p3.x))/d;
    CGFloat v = ((p3.x - p1.x)*(p2.y - p1.y) - (p3.y - p1.y)*(p2.x - p1.x))/d;
    if (u < 0.0 || u > 1.0)
        return nil; // intersection point not between p1 and p2
    if (v < 0.0 || v > 1.0)
        return nil; // intersection point not between p3 and p4
    CGPoint intersection;
    intersection.x = p1.x + u * (p2.x - p1.x);
    intersection.y = p1.y + u * (p2.y - p1.y);

    return [NSValue valueWithCGPoint:intersection];
}
like image 100
Martin R Avatar answered Oct 21 '22 03:10

Martin R


This is a slightly modified version of Hayden Holligan's answer to work with Swift 3:

func getIntersectionOfLines(line1: (a: CGPoint, b: CGPoint), line2: (a: CGPoint, b: CGPoint)) -> CGPoint {

    let distance = (line1.b.x - line1.a.x) * (line2.b.y - line2.a.y) - (line1.b.y - line1.a.y) * (line2.b.x - line2.a.x)
    if distance == 0 {
        print("error, parallel lines")
        return CGPoint.zero
    }

    let u = ((line2.a.x - line1.a.x) * (line2.b.y - line2.a.y) - (line2.a.y - line1.a.y) * (line2.b.x - line2.a.x)) / distance
    let v = ((line2.a.x - line1.a.x) * (line1.b.y - line1.a.y) - (line2.a.y - line1.a.y) * (line1.b.x - line1.a.x)) / distance

    if (u < 0.0 || u > 1.0) {
        print("error, intersection not inside line1")
        return CGPoint.zero
    }
    if (v < 0.0 || v > 1.0) {
        print("error, intersection not inside line2")
        return CGPoint.zero
    }

    return CGPoint(x: line1.a.x + u * (line1.b.x - line1.a.x), y: line1.a.y + u * (line1.b.y - line1.a.y))
}
like image 22
sutherlandahoy Avatar answered Oct 21 '22 03:10

sutherlandahoy


Swift version

func getIntersectionOfLines(line1: (a: CGPoint, b: CGPoint), line2: (a: CGPoint, b: CGPoint)) -> CGPoint {
        let distance = (line1.b.x - line1.a.x) * (line2.b.y - line2.a.y) - (line1.b.y - line1.a.y) * (line2.b.x - line2.a.x)
        if distance == 0 {
            print("error, parallel lines")
            return CGPointZero
        }

        let u = ((line2.a.x - line1.a.x) * (line2.b.y - line2.a.y) - (line2.a.y - line1.a.y) * (line2.b.x - line2.a.x)) / distance
        let v = ((line2.a.x - line1.a.x) * (line1.b.y - line1.a.y) - (line2.a.y - line1.a.y) * (line1.b.x - line1.a.x)) / distance

        if (u < 0.0 || u > 1.0) {
            print("error, intersection not inside line1")
            return CGPointZero
        }
        if (v < 0.0 || v > 1.0) {
            print("error, intersection not inside line2")
            return CGPointZero
        }

        return CGPointMake(line1.a.x + u * (line1.b.x - line1.a.x), line1.a.y + u * (line1.b.y - line1.a.y))
    }
like image 30
Hayden Holligan Avatar answered Oct 21 '22 01:10

Hayden Holligan