グラフの伸縮 – プログラミング – Home

通知
すべてクリア

グラフの伸縮


borrel
 borrel
(@borrel)
ゲスト
結合: 18年前
投稿: 29
Topic starter  

リアルタイムで外部測定器から入力したデータを折れ線グラフに表示する
プログラムを作成しています。

大まかな開発環境は以下の通りです。

OS: Windows XP
Visual C++6.0 (MFC使用)

現在のプラグラムでは、メモリDCに描画したグラフをデバイスコンテキストに
転送していますが、StretchBltを使用すると、プロット(折れ線)がひずんでしまい、
きれいに描画できません。
StretchBltについて調べましたが、この関数では限界があるため、
使用するのをやめました。

また、単純に物理ファクタを変更すると、データ収集量に比例してCPUへの負荷が
相当なもの(100%)になります。

CPUへの負荷が重くなりすぎず、グラフを伸縮する方法がありましたら
教えていただけないでしょうか?


引用解決済
トピックタグ
仲澤@失業者
(@uncle_kei)
Prominent Member
結合: 5年前
投稿: 828
 

まず、モニタ画面はせいぜいX=2000ピクセル程度だと仮定すると
グラフのプロット点は1000あれば十分だと言えます。

サンプリング数が1000を超えたらスクロールするようにすれば
グラフ描画の線の本数は999本になります。
この程度なら今のPCは軽く描画できるはずです。
この場合、縦横の拡大率とオフセット演算を行っても余裕のよっちゃん
のはずで、CPUが100%になることはないはずです。

これでも100%になるようなら別の原因を疑うべきだと思います。


返信引用
borrel
 borrel
(@borrel)
ゲスト
結合: 18年前
投稿: 29
Topic starter  

回答ありがとうございます。

X軸(時間軸)に関しては、スクロール機能を持たせていますので、
画面上に描画しているプロット数は、1000にも満たないと思います。
しかし、今回のプログラムでは、過去のデータもスクロールで閲覧可能にしていますの

画面上に描画されていないデータを考慮すると、相当数のデータが存在しています。
1秒間隔で24時間のデータを30チャンネルで収集した場合、260万ほどのデータが
蓄積されますので、この時にY軸の伸縮を行うと、CPUがとても重くなってしまいま
す。
これは仕方ないんでしょうか。


返信引用
仲澤@失業者
(@uncle_kei)
Prominent Member
結合: 5年前
投稿: 828
 

ものの考え方によりますが、「表示しているデータは元のデータの
一つの表現結果にすぎない」と考えるべきではないでしょうか。

従って、拡大縮小などの「表現上」の修飾は、「表示しているデータ
に対してのみ行う」べきだと考えます。
260万もの、全てのデータに対して無用な演算を施すべきでは
ありません。


返信引用
bun
 bun
(@bun)
ゲスト
結合: 24年前
投稿: 761
 

なんとなくですが、[描画している]=[画面に見えている]と考えていませんでしょうか?
実は画面に見えていない部分に、
MoveTo(), LineTo(), Rectangle(), BitBlt(), StretchBlt(), ...
などをしても、きちんとCPUを消費し、処理時間がかかっています。
ただ、最終的に画面に表示される直前で捨てられている(クリッピング)だけです。

それに、
MoveTo(), LineTo(), Rectangle(), BitBlt(), StretchBlt(), ...
には座標値の指定が必要なはずですが、座標値の取得処理(場合によっては計算処理を含
む)をあなたのアプリケーションで行っているはずで、その時間も取り戻せません。

結論としては、画面に見えていない部分は、何の処理もしないことです。
(正確には無効領域だけを描画、スクロール時は画面全体が無効領域とはなりませんの
で、見えているところ全部でも無駄な描画が存在します)
それだけで、(X軸が長い場合には)劇的に速くなります。

なお、厳密にどこまでが画面に見えているかの判断は難しいので、確実に画面外のみの
描画になる場合だけ、処理をやめれば十分です。


返信引用
PATIO
(@patio)
Famed Member
結合: 3年前
投稿: 2660
 

簡単に書いてしまうと書く必要のない部分は処理しない
する必要のない処理はしないと言うのが高速化の基本です。
あと、一回しておけば良い処理は結果を保存して何回もしないとか。

画面外にはいっさい書かないとまでする必要はないでしょうけれど、
明らかに画面外とわかるものまで処理するのは時間の無駄になります。


返信引用
borrel
 borrel
(@borrel)
ゲスト
結合: 18年前
投稿: 29
Topic starter  

皆さんありがとうございます。

高速スクロール時の負荷を下げたいという考えもありましたが、それはあきらめて
実画面上のグラフ部分だけ処理するようにプログラムを作成してみます。

ただ、グラフの時間軸を圧縮してものすごいデータ数を処理する必要が有る場合は、
データの間引きか何かをした方がいいかもしれないですね。VGAのディスプレイに
何万ものポイントは表示されないですし。


返信引用
仲澤@失業者
(@uncle_kei)
Prominent Member
結合: 5年前
投稿: 828
 

>ただ、グラフの時間軸を圧縮してものすごいデータ数を処理する必要が有る場合は、
>データの間引きか何かをした方がいいかもしれないですね。VGAのディスプレイに

そのような場合は、間引くのではなく、その間のサンプルデータ群の

 1.ピーク(最大/最小値)をとって代表値とする
 2.平均値をとって代表値とする

のようにしたほうが、違和感が和らぎます。
検討してみてください。


返信引用

返信する

投稿者名

投稿者メールアドレス

タイトル *

プレビュー 0リビジョン 保存しました
共有:
タイトルとURLをコピーしました