2012-06-27 50 views
1

我有一般形式a x + b y + c = 0中的二維直線方程,我需要將它轉換爲合適的斜率截距形式;正確的我的意思是我可以選擇y = m x + qx = m y + q如何在C++中將一般形式的二維直線方程轉換爲斜率截取形式

我的想法是檢查該行是否出現「更多」水平或垂直,並因此選擇兩個斜率截距表單中的一個。

這是一個示例代碼:

#include <iostream> 
#include <cmath> 

void abc2mq(double a, double b, double c, double& m, double& q, bool& x2y) 
{ 
    if (fabs(b) >= fabs(a)) { 
     x2y = true; 
     m = -a/b; 
     q = -c/b; 
    } else { 
     x2y = false; 
     m = -b/a; 
     q = -c/a; 
    } 
} 

void test(double a, double b, double c) 
{ 
    double m,q; 
    bool x2y; 
    abc2mq(a, b, c, m, q, x2y); 
    std::cout << a << " x + " << b << " y + " << c << " = 0\t"; 
    if (x2y) { 
     std::cout << "y = " << m << " x + " << q << "\n"; 
    } else { 
     std::cout << "x = " << m << " y + " << q << "\n"; 
    } 
} 

int main(int argc, char* argv[]) 
{ 
    test(0,0,0); 
    test(0,0,1); 
    test(0,1,0); 
    test(0,1,1); 
    test(1,0,0); 
    test(1,0,1); 
    test(1,1,0); 
    test(1,1,1); 

    return 0; 
} 

這是輸出

0 x + 0 y + 0 = 0  y = -1.#IND x + -1.#IND 
0 x + 0 y + 1 = 0  y = -1.#IND x + -1.#INF 
0 x + 1 y + 0 = 0  y = -0 x + -0 
0 x + 1 y + 1 = 0  y = -0 x + -1 
1 x + 0 y + 0 = 0  x = -0 y + -0 
1 x + 0 y + 1 = 0  x = -0 y + -1 
1 x + 1 y + 0 = 0  y = -1 x + -0 
1 x + 1 y + 1 = 0  y = -1 x + -1 

任何不同的或更好的主意嗎?特別是,我如何處理前兩個「退化」線?

+0

你爲什麼需要這樣做? –

+0

@AndreasBrinck我需要繪製線條,並且用於繪製線條的遺留代碼可以接受兩種斜率截取形式,所以我需要選擇合適的一種。不幸的是我不能改變遺留代碼。 –

回答

2

你快完成了,只是處理退化的情況。 將a和b的檢查添加爲非零。

if(fabs(a) > DBL_EPSILON && fabs(b) > DBL_EPSILON) 
{ 
    ... non-degenerate line handling 
} else 
{ 
    // both a and b are machine zeros 
    degenerate_line = true; 
} 

然後添加參數 'degenerate_line':

void abc2mq(double a, double b, double c, double& m, double& q, bool& x2y, bool& degenerate_line) 
{ 
    if(fabs(a) > DBL_EPSILON && fabs(b) > DBL_EPSILON) 
    { 
     if (fabs(b) >= fabs(a)) { 
      x2y = true; 
      m = -a/b; 
      q = -c/b; 
     } else { 
      x2y = false; 
      m = -b/a; 
      q = -c/a; 
     } 

     degenerate_line = false; 
    } else 
    { 
     degenerate_line = true; 
    } 
} 

,然後檢查線是空集:

void test(double a, double b, double c) 
{ 
    double m,q; 
    bool x2y, degenerate; 
    abc2mq(a, b, c, m, q, x2y, degenerate); 
    std::cout << a << " x + " << b << " y + " << c << " = 0\t"; 
    if(!degenerate) 
    { 
     if (x2y) { 
      std::cout << "y = " << m << " x + " << q << std::endl; 
     } else { 
      std::cout << "x = " << m << " y + " << q << std::endl; 
     } 
    } else 
    { 
     if(fabs(c) > DBL_EPSILON) 
     { 
      std::cout << "empty set" << std::endl 
     } else 
     { 
      std::cout << "entire plane" << std::endl 
     } 
    } 
} 

如果你需要的是劃清界線,只需使用Thorsten的建議 - 改爲使用光柵化算法。

4

如果您正在尋找繪製這些線條的好方法,我建議您使用Bresenham's algorithm而不是採樣行方程的斜截式結果。如果這不是你正在做的事,道歉。

+0

+1,感謝您記住Bresenham的線條算法。 –

1

對應於兩個退化情況的方程不分別代表直線,而是全平面(ℝ)和空集(∅)。正確的做法可能是放棄它們或拋出錯誤。

對於非退化情況,您已經正確處理它們。

+0

+1,感謝您的精簡。 –

相關問題