2017-01-27 25 views
3

私はSFMLライブラリを使ってC++でグラフ作成プログラムを作成しています。これまで私は画面に機能を描くことができました。私は途中で2つの問題に遭遇しました。 最初は、私の機能の終わりから飛行機の原点に戻るような線です。不正な行がウィンドウに描画される

あなたはこの画像でそれを見ることができます。

あなたは、この「ならず者」の行は、それが原点に近づくにつれて色が変化するようで見ることができるように。私の最初の質問は、この行とは何ですか私はどのように私の窓からそれを根絶することができますか?

わずかに無関係と複数の数学的である第二の問題は、この画像で見ることができる。

enter image description here

もしグラフが連続未定義または非ある点である漸近線が描画されて見ることができるように。これは私に2番目の質問につながります:漸近線を特定し、それをウィンドウに描画しない方法(コード内)はありますか?

ウィンドウに描かれた何のための私のコードは次のとおりです。

VertexArray axis(Lines, 4); 
VertexArray curve(PrimitiveType::LinesStrip, 1000); 

axis[0].position = Vector2f(100000, 0); 
axis[1].position = Vector2f(-100000, 0); 
axis[2].position = Vector2f(0, -100000); 
axis[3].position = Vector2f(0, 100000); 

float x; 

for (x = -pi; x < pi; x += .0005f) 
{ 
    curve.append(Vertex(Vector2f(x, -tan(x)), Color::Green)); 
} 

私は非常に任意の入力をお願い申し上げます。)

更新:多数の人々これの入力に

感謝コードは漸近問題を修正する上でうまくいくようです:

for (x = -30*pi; x < 30*pi; x += .0005f) 
{ 
    x0 = x1; y0 = y1; 
    x1 = x; y1 = -1/sin(x); 
    a = 0; 
    a = fabs(atan2(y1 - y0, x1 - x0)); 
    if (a > .499f*pi) 
    { 
     curve.append(Vertex(Vector2f(x1, y1), Color::Transparent)); 
    } 
    else 
    { 
     curve.append(Vertex(Vector2f(x1, y1), Color::Green)); 
    } 
} 

アップデート2:次のコードは、不正な行を取り除きます

VertexArray curve(Lines, 1000); 
float x,y; 
for (x = -30 * pi; x < 30 * pi; x += .0005f) 
{ 
    y = -asin(x); 
    curve.append(Vertex(Vector2f(x, y))); 
} 
for (x = -30 * pi + .0005f; x < 30 * pi; x += .0005f) 
{ 
    y = -asin(x); 
    curve.append(Vertex(Vector2f(x, y))); 
} 
+0

不正な行が白く見えます。白い線を含むコードを投稿できますか? – user3853544

+1

@ user3853544あなたが参照する白い線は、軸です。そのコードは私の記事の最後のセクションに含まれています。 "axis [n] .pos ..."の部分です。 – billy606

+0

原点の南西の最初のイメージでは、軸の一部ではない小さな白い線があるように見えます。 2つの不正な行に緑色と白いものがあるかもしれないかのように見えます – user3853544

答えて

3

最初の問題は間違ったポリライン/曲線の取り扱いのように見えます。 APIレンダリングに使用していますが、GDIのようなものは、penの位置を正しく開始する必要があります。たとえば、あなたはこのように描く場合:

Canvas->LineTo(x[0],y[0]); 
Canvas->LineTo(x[1],y[1]); 
Canvas->LineTo(x[2],y[2]); 
Canvas->LineTo(x[3],y[3]); 
... 

は、その後あなたの代わりにこれを行う必要があります場合は

Canvas->MoveTo(x[0],y[0]); 
Canvas->LineTo(x[1],y[1]); 
Canvas->LineTo(x[2],y[2]); 
Canvas->LineTo(x[3],y[3]); 
... 

あなたとあなたはそれが最後の位置が使用されている設定されていないMoveToコマンドを必要とAPI(またはデフォルトの(0,0))、最後の描画またはデフォルトのペン位置からの直線でカーブの開始点を接続します。あなたはその結果としてy値をチェックすることにより、しきい値漸近線または不連続をすることができ、連続データで

第二の問題

。あなたの曲線は、このようなルックスをレンダリングする場合:

Canvas->MoveTo(x[0],y[0]); 
for (i=1;i<n;i++) Canvas->LineTo(x[i],y[i]); 

は、その後、あなたはこのような何かにそれを変更することができます。

y0=y[0]+2*threshold; 
for (i=0;i<n;i++) 
{ 
if (y[1]-y0>=threshold) Canvas->MoveTo(x[i],y[i]); 
    else     Canvas->LineTo(x[i],y[i]); 
y0=y[i]; 
} 

問題がしきい値の選択であることがxサンプリング点の密度とに依存しているので、 yデータの最初の導出でx(傾斜角)

さらに多くの関数を積み重ねると、カーブを追加すると不要な行が作成されます。代わりに各データをs

double x0,y0,x1,y1,a; 
for (e=1,x = -pi; x < pi; x += .0005f) 
    { 
    // last point 
    x0=x1; y0=y1; 
    // your actual point 
    x1=x; y1=-tan(x); 
    // test discontinuity 
    if (e) { a=0; e=0; } else a=fabs(atan2(y1-y0,x1-x0)); 
    if (a>0.499*M_PI) curve.append(Vertex(Vector2f(x1,y1), Color::Black)); 
    else    curve.append(Vertex(Vector2f(x1,y1), Color::Green)); 
    } 

0.499*M_PIがより近いが0.5*M_PIにあるあなたのしきい値です:eparate私はこの(偽スプリット)のようにそれを参照してください[EDIT1]

を描くか

それらの間にMoveToコマンドを入れますそれが検出された大きなジャンプ...私は曲線を黒色(背景)で分割して、軸の交差点に(透明度が使用されていない限り)ギャップを作成してしまいました...しかし、曲線のリストは必要ありません...

+3

彼は[SFML] (http://sfml-dev.org/)タグが示すように、SFMLの 'sf :: VertexArray'をラインストリップとして使用すると、「move to」コマンドをエミュレートする一般的な方法はありません。 2回目のドローコール。 – Mario

+0

@Mario私はSFMLを使用しませんが、ほとんどの頂点配列の実装は、OpenGLのようなエッジフラグ配列を知っています。ここで、 'MoveTo'をエンコードすることができます。 – Spektre

+0

あなたのコードをありがとう。それは漸近線問題を完全に修正した。 – billy606

2

これらのアーティファクトは、sf::PrimitiveType::LinesStripの動作(またはより特定のラインストリップ)のためです。

2番目の例では、y = -tan(x)を視覚化すると、正の無限大から負の無限大にジャンプしています。これは見ているラインです。別のプリミティブ型を使用している場合やレンダリングを複数の描画呼び出しに分割している場合を除き、これを取り除くことはできません。

プッシュピン(頂点を表す)で固定している1つの長いスレッドとしてラインストリップを想像してください。これらのアーティファクトなしで、正の無限大から負の無限大に移動する(安全な)方法はありません。もちろん、目に見える領域の外側に移動することもできますが、もう一度これは実際にこの1つの機能に特有のものです。

+0

ラインストーンなしで私を残すLinesStripのような別の種類のプリミティブ型(私はそれがハハだと思います)がありますか? – billy606

+0

@ billy606 'sf :: PrimitiveType :: Lines'しかし、これは各セグメントの開始点と終了点を提出する必要があります。つまり、頂点数が倍になります。 – Mario

関連する問題