2013-03-28 144 views
5

我可以檢測到兩條直線的交點,但是如果我的直線沒有我的屏幕長度,它會檢測到它不應該在的位置。座標中兩條直線之間的交點

這裏預覽:Intersection 所以,它不應該檢測到這個交點,因爲水平線不是那麼長。

代碼:

- (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; 
} 
+0

我不知道你是什麼意思,那條水平線明顯地與一個垂直線相交。 – Tony

+0

當然是,但不是圖形 - 我認爲我必須確定交點是否在這些行中的一行上,如果不是這樣 - 我可以將它繪製到頂部。你知道我的意思? –

回答

25

如果我理解你的問題正確的話,你需要確定兩個線段的交點。這應該與以下方法工作:

- (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]; 
} 
+0

它工作正常(編輯後) - 非常感謝! –

+0

注意:嘗試使用這個,我發現'intersection.y = p1.y + v *(p2.y - p1.y);'需要'intersection.y = p1.y + u *(p2。 y - p1.y);'原來就是這樣。我不知道是誰編輯了'u'作爲'v',但它需要被編輯回去 - 'u'和'v'是沿每個線段的插值 - 每個插值使用兩個不同的插值相同插值的軸是荒謬的。 –

+1

@GeorgesOatesLarsen:你當然是對的。這是我的錯,我沒有仔細檢查「建議的編輯」,我已經回覆了以前版本的答案。謝謝! –

2

這是正確的公式:

+(CGPoint) intersection2:(CGPoint)u1 u2:(CGPoint)u2 v1:(CGPoint)v1 v2:(CGPoint)v2 { 
    CGPoint ret=u1; 
    double t=((u1.x-v1.x)*(v1.y-v2.y)-(u1.y-v1.y)*(v1.x-v2.x)) 
    /((u1.x-u2.x)*(v1.y-v2.y)-(u1.y-u2.y)*(v1.x-v2.x)); 
    ret.x+=(u2.x-u1.x)*t; 
    ret.y+=(u2.y-u1.y)*t; 
    return ret; 
} 

此外,您還可以檢查此庫來計算的直線相交: http://www.cprogramdevelop.com/5045485/

+0

此解決方案不起作用。只是試圖與此值: '線A:(0,0)和(0,20)' '線B:(3,2)和(-5,2)' 給定的結果是0 ,320顯然是錯誤的。 – MatterGoal

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 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)) 
    } 
5

這是一個微笑莫迪fhd版本Hayden Holligan's answer與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)) 
}