1

一般形式の2D線の方程式があり、a x + b y + c = 0それを適切な勾配切片形式に変換する必要があります。適切な場合は、との間y = m x + qで選択できることを意味しますx = m y + q

私の考えは、線が「より」水平または垂直に表示されるかどうかを確認し、その結果、2つのスロープインターセプトフォームのいずれかを選択することです。

これはサンプルコードです:

#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

別のまたはより良いアイデアはありますか?特に、最初の2つの「縮退」行をどのように処理できますか?

4

3 に答える 3

4

これらの線を描く良い方法を探している場合は、線方程式の傾き切片形式の結果をサンプリングする代わりに、ブレゼンハムのアルゴリズムを使用することをお勧めします。これがあなたがやろうとしていることではない場合は、お詫び申し上げます。

于 2012-06-27T09:57:28.483 に答える
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のアドバイスを使用してください。代わりにラスタライズアルゴリズムを使用してください。

于 2012-06-27T10:07:39.540 に答える
1

2つの縮退した場合に対応する方程式は、線ではなく、それぞれ全平面(ℝ<sup> 2)と空集合(∅)を表します。正しいことは、おそらくそれらを破棄するか、エラーをスローすることです。

非縮退の場合は、すでに適切に処理されています。

于 2012-06-27T10:13:27.447 に答える