2014-01-21 67 views
1

這是一個相當平凡的算法問題,但我的實現留下了速度和簡單性。我有兩個Line對象,每個對象都擁有{unsigned int x, unsigned int y}形式的兩個座標結構。這個第一個座標位置是該行的開始位置,第二個座標位置是它的結束位置。假設線條只能在網格上是垂直或水平的,我怎麼能檢查兩條線平行重疊或垂直相交。優選地,這是作爲行中的方法實現的:如何檢查兩條線在網格上相交/重疊?

- (BOOL)intersectsLine:(Line)otherLine; 

感謝!

+1

這是一個代數問題,或者你知道數學,並且難以將它轉換爲Objective-C嗎? (爲什麼座標沒有簽名......?) – nhgrif

+0

那麼我以非數學方式實現它,並且我在數學上不夠精通以使我的方法更好。 –

+0

座標未簽名,因爲我的網格只需要在第一象限中。網格的左上角在我的程序中是{0,0}。 –

回答

2

由於我們只談論水平線或垂直線,因此第一步我會檢查線是否具有相同的方向。

​​

因此,考慮到兩個點的線條......

LineOrientation line1orientation; 
LineOrientation line2orientation;  

if (a.x1 == a.x2) { 
    line1orientation = HorizontalLine; 
} else { 
    line1orientation = VerticalLine; 
} 

if (b.x1 == b.x2) { 
    line2orientation = VerticalLine; 
} else { 
    line2orientation = Horizontal; 
} 

現在,我們需要檢查他們是否是兩個水平,無論垂直或每一個,然後測試特定值:

if (line1orientation == line2orientation) { 
    if (line1orientation == VerticalLine) { 
     if (a.x1 != b.x1) { 
      return false; 
     } else { 
      if (a.y1 < a.y2) { 
       return ((b.y1 > a.y1 && b.y1 < a.y2) || 
        (b.y2 > a.y1 && b.y2 < a.y2)); 
      } else { 
       return ((b.y1 > a.y2 && b.y1 < a.y1) || 
        (b.y2 > a.y2 && b.y2 < a.y1)); 
      } 
     } 
    } else { 
     if (a.y1 != b.y1) { 
      return false; 
     } else { 
      if (a.x1 < a.x2) { 
       return ((b.x1 > a.x1 && b.x1 < a.x2) || 
        (b.x2 > a.x1 && b.x2 < a.x2)); 
      } else { 
       return ((b.x1 > a.x2 && b.x1 < a.x1) || 
        (b.x2 > a.x2 && b.x2 < a.x1)); 
      } 
     } 
    } 
} else { 
    if (line1orientation == VerticalLine) { 
     if (a.y1 < a.y2) { 
      return (((b.y1 > a.y1) && (b.y1 < a.y2)) && ((b.x1 > a.x1 && b.x2 
       < a.x1) || (b.x2 > a.x1 && b.x1 < a.x1))); 
     } else { 
      return (((b.y1 > a.y2) && (b.y1 < a.y1)) && ((b.x1 > a.x1 && b.x2 
       < a.x1) || (b.x2 > a.x1 && b.x1 < a.x1))) 
     } 
    } else { 
     if (a.x1 < a.x2) { 
      return (((b.x1 > a.x1) && (b.x1 < a.x2)) && ((b.y1 > a.y1 && b.y2 
       < a.y2) || (b.y2 > a.y1 && b.y1 < a.y1))); 
     } else { 
      return (((b.x1 > a.x2) && (b.x1 < a.x1)) && ((b.y1 > a.y1 && b.y2 
       < a.y2) || (b.y2 > a.y1 && b.y1 < a.y1))); 
    } 
} 

如果您開始檢查以確保行不是同一行,這可能會更有效。

+0

我認爲這是正確的......它看起來很複雜,但實際上應該運行得相當快,特別是與檢查數組中的幾個點相比。 – nhgrif