2013-03-28 4 views
5

私は2本の線の交点を検出することができますが、私の線が画面の長さを持たない場合は、座標内の2行の間の交点

ここでプレビュー: 水平線がそれほど長くないので、この交差点を検出してはなりません。

コード:

- (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

私が正しくあなたの質問を理解していれば、あなたは2つの線分の交点を決定する必要があります。これは、以下の方法で動作します:

正しい式です
- (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); 'それはもともとと同じです。私は誰が '' v''を編集したのか分かりませんが、編集する必要があります - 'u'と' v'は各線分に沿った補間値です - それぞれに2つの補間値同じ補間の軸は不合理です。 –

+1

@ GeogesOatesLarsen:あなたはもちろんそうです。 "提案された編集"を慎重にチェックしなかったのは私のせいで、私は以前のバージョンへの答えを元に戻しました。ありがとう! –

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

これは少し修正されていますスウィフト3で動作するようにHayden Holligan's answerのfiedがバージョン:

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)) 
} 
関連する問題