2014-06-26 61 views
0

這個方法應該告訴你一個點是否在給定的行上。目前,只要沒有方向矢量的分量是0(我正在使用線的參數表示),它就可以正常工作。沒有0,如果點在線上,我應該得到xResult = yResult = zResult。如果方向矢量中有一個0,那麼這三個中至少有一個是0,因此不等於所有其他的,但該點仍然可以在線上。檢查一個點是否在三維線上

如何找到一個點是否在給定的行上處理零情況的最佳方法是什麼?

/// <summary> 
    /// Returns true if the passed point is on the line, false otherwise 
    /// </summary> 
    /// <param name="passedPoint"></param> 
    /// <returns></returns> 
    public Boolean IsOnLine(Line passedLine) 
    { 
     Boolean pointIsOnLine = false; 

     //Get components of this point 
     Dimension xPoint = new Dimension(DimensionType.Millimeter, X.Millimeters); 
     Dimension yPoint = new Dimension(DimensionType.Millimeter, Y.Millimeters); 
     Dimension zPoint = new Dimension(DimensionType.Millimeter, Z.Millimeters); 

     //Get components of the base point of the line 
     Dimension xBasePoint = new Dimension(DimensionType.Millimeter, passedLine.BasePoint.X.Millimeters); 
     Dimension yBasePoint = new Dimension(DimensionType.Millimeter, passedLine.BasePoint.Y.Millimeters); 
     Dimension zBasePoint = new Dimension(DimensionType.Millimeter, passedLine.BasePoint.Z.Millimeters); 

     //Find difference between passed point and the base point 
     Dimension xDifference = xPoint - xBasePoint; 
     Dimension yDifference = yPoint - yBasePoint; 
     Dimension zDifference = zPoint - zBasePoint; 

     DimensionGenerator dg = new DimensionGenerator(DimensionType.Millimeter); 

     //Instantiate the 3 result variables 
     Dimension xResult = dg.MakeDimension(-1); 
     Dimension yResult = dg.MakeDimension(-1); 
     Dimension zResult = dg.MakeDimension(-1); 


     //Solve for the multiplier using each direction and make sure they are all equal. 
     //If any component of the direction vector is 0, the result will be zero and should therefore be directly assigned to 0 to avoid dividing by 0 
     if(passedLine.XComponentOfDirection.Millimeters == 0) 
     { 
      xResult = dg.MakeDimension(0); 
     } 

     if(passedLine.YComponentOfDirection.Millimeters == 0) 
     { 
      yResult = dg.MakeDimension(0); 

     } 

     if(passedLine.ZComponentOfDirection.Millimeters == 0) 
     { 
      zResult = dg.MakeDimension(0); 
     } 

     else 
     { 

      xResult = dg.MakeDimension(xDifference.Millimeters/passedLine.XComponentOfDirection.Millimeters); 
      yResult = dg.MakeDimension(yDifference.Millimeters/passedLine.YComponentOfDirection.Millimeters); 
      zResult = dg.MakeDimension(zDifference.Millimeters/passedLine.ZComponentOfDirection.Millimeters); 

     } 


     //If the 3 results are equal, the point is on the line. If they are not, the point is not on the line. 
     if (xResult == yResult && xResult == zResult) 
     { 
      pointIsOnLine = true; 
     } 
     else 
     { 
      pointIsOnLine = false; 
     } 

     return pointIsOnLine; 
+0

XML文檔和函數名稱與傳遞的參數相矛盾。 –

回答

2

如果你正在處理不精確的數字,比較平等是一個壞主意。我會嘗試以下方法:從線的基點到該點的矢量,並採取線的方向矢量。計算他們的交叉產品。如果該點位於線上,則兩個向量將是共線的,並且它們的叉積將是零向量。因此,計算矢量的平方長度(以避免不必要的平方根),如果低於某個閾值,則您的觀點位於所討論的線上。

但是,如果你想更接近你自己的代碼,請注意,你有三個if後跟一個else。所以如果第一個條件中的一個適用,else塊仍然會被執行。這可能會導致你的麻煩。另請注意,如果您以毫米爲單位執行所有計算,則只需處理原始數字即可節省大量代碼。

1

我會建議去做這個不同的方式。使用數學。如果任何兩個矢量之間的角度爲0,則矢量「共享一條線」。 cos(θ)=(U * V)/(| U | * | V |)(點積)。

應用到你的代碼:

double inverse = ((xPoint*xBasePoint) + (yPoint*yBasePoint) + (zPoint*zBasePoint))/((sqrt(xPoint^2 +yPoint^2 + zPoint^2) + sqrt(xBasePoint^2 + yBasePoint^2 + zBasePoint^2)); 

    if(inverse == 1) 
     //points are on the same line 
    else 
     //points are not on the same line or one point is (0,0,0) 

另外,看看你是否else語句分配xresult,yresult和zresult時。如果傳遞的Line.Z不是0(轉到else語句),那麼您擁有它的方式仍然可以最終除以零。

+0

在這裏使用'Math.ArcCos'不是必須的,你可以將反比作爲1。 – Kyle

+0

你是對的,謝謝你,我會修復它 – TheBlindSpring

+1

這兩個向量'U'和'V',應該是該行的方向(即'XComponentOfDirection'和朋友),另一個*基點和輸入點之間的差*。然而,如果其中之一爲零,即如果輸入點等於基點,則仍然存在問題。這就是我更喜歡我的解決方案的原因之一。 – MvG

相關問題