0

以下は、2本の線が交差するかどうかを推測するためのプログラムの断片です。 2本の線のうちの1本の始点と終点を示すオブジェクトですP and P2CPoint

double m1,m2;  //slopes
double b1,b2;     //y-intercepts
double y,x;     //intersection point

m1=(max(P.y,P2.y) - min(P.y,P2.y)) /( max(P.x,P2.x) - min(P.x,P2.x) );

どういうわけか私はいつもなりつつm1あります0。なんで?

4

2 に答える 2

1

クラスが整数座標のポイントである場合、CPoint目的の結果を得るには、ここで変換を行う必要があります。次の問題のデモンストレーションを参照してください。P = (1, 4)2つのポイントを考慮してくださいP2 = (5, 3)

m1=( max(P.y,P2.y) - min(P.y,P2.y) ) / ( max(P.x,P2.x) - min(P.x,P2.x) );
     ^^^^^^^^^^^^^   ^^^^^^^^^^^^^       ^^^^^^^^^^^^^   ^^^^^^^^^^^^^
           4               3                    5               1
   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
                   1                                   4

ただし、整数除算で1 / 40、はですが、結果は。になります0.25。結果変数にタイプがあるという事実は、式double値(およびタイプ)を変更しません。

この問題を解決するには、式の一部を非整数と見なされることが適切になる直前にキャストする必要があります。あなたの場合、これは除算のオペランドであるため、浮動小数点除算になります。(分割の結果をキャストすることも役に立ちません。)

m1 = static_cast<double>( max(P.y,P2.y) - min(P.y,P2.y) )
   / static_cast<double>( max(P.x,P2.x) - min(P.x,P2.x) );

double / int常に浮動小数点除算を使用するため、2番目のオペランドのキャストはオプションであることに注意してください。

また、式が勾配の絶対値を計算することにも注意してください。符号付き勾配を計算することをお勧めします。


コードで改善できる点(これでは上記の問題は解決されません):差の最大値の最小値を引く代わりに、差の絶対値を取得します。

m1 = static_cast<double>( abs(P.y - P2.y) )
   / static_cast<double>( abs(P.x - P2.x) );

C ++ではabsテンプレート関数であるため(Cではマクロです...)、明示的なテンプレートタイプを使用して結果タイプを強制することもできます。

m1 = abs<double>(P.y - P2.y)
   / abs<double>(P.x - P2.x);

CPointまた、与えられた2つのポイント間の勾配の計算は一般的に使用される関数のように思われるため、これを2つのsに独立した関数として実装できます。

double absoluteSlope(const CPoint & p, const CPoint & q) {
    return abs<double>(p.y - q.y) / abs<double>(p.x - q.x);
}

xさらに良いことに、C ++テンプレートを利用するには、メンバーとy:を持つジェネリッククラスに実装します。

template<class T>
double absoluteSlope(const T & p, const T & q) {
    return abs<double>(p.y - q.y) / abs<double>(p.x - q.x);
}

このソリューションはCPoint、整数座標を持つインスタンスと、float / double座標を持つ(おそらく今後の)CPointFクラスで機能するようになりました。

上ですでに警告したように、これは絶対勾配を計算します。これを数学的に正しい(符号付き)勾配に変更するには、次のように置き換えabsますstatic_cast

template<class T>
double slope(const T & p, const T & q) {
    return static_cast<double>(p.y - q.y) / static_cast<double>(p.x - q.x);
}
于 2013-01-23T17:28:27.290 に答える
0

分割A/BはA/(double)Bである必要があります。これをコードで使用します。腹筋の代わりにファブも。

于 2013-01-23T18:10:54.360 に答える