こんにちは、C言語においてグラフを表示することで質問があります。
いま、時間で変化していくある値を(x、y)をfprintfで出力し、datファイルに保存しました。それをwgnuplotで表示すると、きちんと表示することができました。そこで質問なんですが、
時間T=0のときに、X=1、Y=1。 T=1のときに、X=2、Y=2とY=Xの関係で変化していったとすると、直線であらわされますよね?
それを、グラフ上で時間が経過していくと、点として右上に動いて行くように、視覚的に見ることはできるんでしょうか?
いろいろとフリーソフトなどを探したのですが、よくわかりませんでした。。何か知っていたらお願いします。あるいは、C言語では逐次的に表現などできないとか、そういったアドバイスもあればお願いします。
すぐに返信できないかもしれませんが。よろしくお願いします。
No.11ベストアンサー
- 回答日時:
あぁ、魚の群れの行動というのだから、たとえば、魚一匹ごとに3次元の点であらわして、それを gnuplot で描画してみようってことですよね、たぶん^^
以下のプログラムをコンパイル・リンクして実行ファイル(myprogram.exe という名前だったとします)を作成し、
myprogram | pgnuplot
とコマンドラインで打ち込むと、点のかたまりが3次元で動いていくように見えると思います。
===
#include <stdio.h>
#include <unistd.h>
typedef struct Point {
float x, y, z;
} Point;
void advance(size_t n, Point points[], Point *v)
{
size_t i;
for (i = 0; i < n; ++i) {
points[i].x += v->x;
points[i].y += v->y;
points[i].z += v->z;
}
}
int main(void)
{
Point points[] = {
{ 0.0, 0.0, 0.0 },
{ 0.0, 0.0, 1.0 },
{ 0.0, 1.0, 0.0 },
{ 1.0, 0.0, 0.0 },
{ 0.0, 1.0, 1.0 },
{ 1.0, 0.0, 1.0 },
{ 1.0, 1.0, 0.0 },
{ 1.0, 1.0, 1.0 },
};
size_t n = sizeof points / sizeof points[0];
const int m = 90;
int i, j;
Point v = { .1, .1, .1 };
puts("set xrange [0:10]");
puts("set yrange [0:10]");
puts("set zrange [0:10]");
for (i = 0; i < m; ++i, advance(n, points, &v)) {
puts("splot \'-\' with point");
for (j = 0; j < n; ++j)
printf("%f %f %f\n", points[j].x, points[j].y, points[j].z);
puts("e");
fflush(stdout);
sleep(1);
}
return 0;
}
この回答への補足
すいません。変換ミスです。群行動が正しいです。
私は、VC++を使ってC言語をくんでいますが、
実行すると、#include <unistd.h>がどうもひっかかるみたいでした。
そこで、ヘッダファイルを適当に?どうにかしてみたところ。
(人が作っていたものをコピーして、インクルードフォルダにコピペしてみた)
実行をすることができました!!
ただ、コマンドラインで打ち込む方法がわからなかったので、
myproglam | pgnuplot をできませんでした・・・汗
アクセサリからコマンドプロントを探し、プログラムのあるファイルに移動して、myproglam | pgnuplotとは
入力してみたのですが、うまくいかなかったようです。
実行ファイルはプログラムとは違うところに保存されるのでしょうか。
実行して同じフォルダにできた拡張子をみてみると、
プロジェクトファイル、ncb,,opt,と書いてありました。
そこで、LINUXで動かしたのですが、gccでコンパイルして、
みると、a.out と言うのができたのですが。
myproglam | pgnuplot と打ってもcannot found しかでませんでした。
この↑記述の意味がよくわからないので、、、
a | pgnuplot とか、、、いろいろしてみたのですが、、ダメでした。
今からもう少し調べてみようと思っています。お返事ありがとうございます。
すいません。
myprogram.exeの実行ファイルは簡単に、みつかりました。
debugフォルダの中にありました。
ただ、myprogram | pgnuplotとうったんですが、
pgnuplotは内部コマンド、または、外部コマンド、操作可能なプログラムまたは、パッチファイルとして認識されません。と表示されてしまいました。
どのようにしたらいいでしょうか。
No.19
- 回答日時:
理解できてよかったですね^^
サンプルプログラムの adavance で、次の表示時刻の魚群の位置を設定しておけば、とりあえず、魚一匹を一点で表現した魚群の動いている様子を見せることができると思います。
プレゼンテーションなどで、それっぽい魚を描いたり、水中を再現した背景にしたいなど、もっときれいに見せたいというなら、それ相応のグラフィックライブラリを使うのがいいと思います。Linux 環境などでは、vtk を使うとか、もっと凝りたいなら OpenGL(Mesaなど)で直接コーディングするとか(そこまで凝る必要があるのかとは思いますが…笑)。わたしはグラフィックスはぜんぜん詳しくないので、もし凝りたくて、ご自分で探して見つけられないというのであれば、グラフィック専門のところへ、「どういうツール・ライブラリがいいのか」、質問するのがいいんじゃないかと思います。
gnuplot でも結構いろいろなことができるので、gnuplot の demo フォルダにある all.dem を動かして、どんなことができるのか、一度、見てみるのもいいかもしれません。「じゃあ、こうしよう♪」というインスピレーションが沸くかもしれませんしね。では、研究がんばってください。
この回答への補足
そうですか!!ありがとうございますw
せっかくなので凝ったものにしてみたいとおもいます。
ただ、まだ魚たちがうまく、群行動してくれないのでそこを直す必要がありますが・・・汗
本当にありがとうございました。
No.18
- 回答日時:
あぁ、あとそれから、splot コマンドの間に sleep() を入れていないというのならば、gnuplot へ splot コマンド が間断なく指示されるので、描画が一瞬で終わって、動いているように見えないかもしれません。
もし、そちらの環境で、sleep() のようなものがなければ(sleep(n)を実行するというのは n秒間お休みするみたいなもの)、たとえば、
fprintf(stderr, "input something: ");
do { int c; while ((c = getchar()) != EOF) if (c == '\n') break; } while (0);
を、sleep(1) の代わりに入れて、実行時に splot コマンド発行ごとに、端末から何か入力するまで、次の splot コマンドを発行させないようにするなどの方法を取ればよいでしょう。
No.17
- 回答日時:
もう一つ追加:
サンプルプログラムをコンパイル・リンクして(myprogram.exe とする)、コマンドプロンプトから実行したときに、コマンドプロンプト上に出力されるものがすべて gnuplot への入力となります。
No.16
- 回答日時:
それから、gnuplot と C言語は別のものなので、C言語の本に gnuplot のことは書いてないのが普通です。
gnuplot のことは、gnuplot のヘルプなどを見て勉強するか、検索エンジンで gnuplot というキーワードで検索すると、簡単な使い方が書いてあるHPなどはすぐに見つかるでしょう。No.15
- 回答日時:
n は points の配列長になります。
sizeof points で配列全体のバイト数が出ます。sizeof points[0] で配列要素のバイト数が出ます。なのでsizeof points / sizeof points[0] で、配列の長さが計算できます。配列数は、初期値の個数で決まるようにしていて、初期値を付け足したり、間引いたりしても、sizeof points や sizeof points[0] などは、コンパイラが処理しますから、他の部分のコードを修正しなくてよいので、配列の長さを数字そのままで扱っているより便利だから書いているだけです。配列サイズを直接指定したいというなら、Point points[10] = { { 0, 0, 0 }, .... };
size_t n = 10;
としてもかまいません。m は何回か描画させるために適当に決めた数字をいれているだけです。この場合は、90 回 gnuplot が描画します。
あとは、gnuplot のコマンドの文法ですね。。。
splot '-'
0.0 0.0 0.0
1.0 1.0 1.0
e
というのは、
=== ここから、data.txt
0.0 0.0 0.0
1.0 1.0 1.0
=== ここまで、data.txt
というファイル data.txt があるとすると、
splot 'data.txt'
と同じ意味です。文字 "e" は入力データの終了を splot に指示するものです。
やっと理解することができました!!
今までポインタから逃げてきた人間だったので、
今回再勉強によりだいぶ進化したような気がします。
おかげさまで、毎日C言語三昧ですw
size tを使った方法はとても便利ですね!!
たいへん参考になりました!
No.14
- 回答日時:
ありゃ。
。。もううまく言ってた訳ですね。よかったよかった。プログラムは適当に使えるものは利用して、研究をしっかりとがんばってください(笑)
この回答への補足
ありがとうございます!
途中でカレントフォルダから相対パス・・・
と書いてあるところを読んで気づきました!!!
実行することはできたのですが、プログラムの解釈が難しいです。
ためしに、似たようなプログラムを作ったりしているのですが、
どうも違います。うまく表示されなかったり、一つの点しか表示されなかったりといったことがあります。
puts("")の中で直接、pgnuplotに指示を出しているんですよね?
自分の持っている、C言語の本にはあまり深く書いてないので、
少し理解が難しいです。for文の回す範囲や、nの導出の仕方が特にです。
もしよろしければ解説していただけないでしょうか?
No.13
- 回答日時:
あっ、そうそう^^ unistd.h って、Unix 環境のヘッダだから、Windows ではないかもしれません(POSIX 対応のがあればあるのかもしれないけど、詳しくない^^;)。
unistd.h は sleep() を使うために include してるだけなので、もし、sleep() を使うことでリンクエラーになるなら、sleep() のところを削除してもかまいません(点の動きが早くて、描画状態がわからないかもしれませんけどね^^)。
No.12
- 回答日時:
パスの通し方がわからなければ、すべて、カレントディレクトリからの相対パスで書けばいいんじゃないですか?わたしの場合は、たとえば、
> "..\home\watashi\work\c\myprogram" | "d:\downloads\gnuplot\gnuplot\bin\pgnuplot"
と打つと、うまくいきます。絶対パスで指定してもいいですけど、パスを通しておくのが簡単ですけどね(笑)
No.10
- 回答日時:
> 自分で描画を行う場合には、わざわざ外部ファイルに…
それはそのとおりだと思います。自作の描画機能で、わざわざ外部ファイルに出力するように設計する人は、まれでしょう^^
まぁ、kenpanch7さんは、学生さんで、研究の補助として「動いている」ように見える描画機能がほしいだけみたいで、そこそこ動けばよいようですし、「暇なときに見てみます」って回答なので、そんなにまじめに作るほど重要でもないんでしょう(笑)それに「あるものは使えばいい」し、「自分で探して見つからなければ、人に聞くのもいい」でしょ。
連続投稿すいません、、、
実行ファイルとpgnuplotを同じフォルダにおけばできました。
本当にありがとうございました!!やっとみれたのでけっこう感動しました!!!
ただ、次は自分のプログラムにどうつかうかですね。
ありがとうございます。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・街中で見かけて「グッときた人」の思い出
- ・「一気に最後まで読んだ」本、教えて下さい!
- ・幼稚園時代「何組」でしたか?
- ・激凹みから立ち直る方法
- ・1つだけ過去を変えられるとしたら?
- ・【あるあるbot連動企画】あるあるbotに投稿したけど採用されなかったあるある募集
- ・【あるあるbot連動企画】フォロワー20万人のアカウントであなたのあるあるを披露してみませんか?
- ・映画のエンドロール観る派?観ない派?
- ・海外旅行から帰ってきたら、まず何を食べる?
- ・誕生日にもらった意外なもの
- ・天使と悪魔選手権
- ・ちょっと先の未来クイズ第2問
- ・【大喜利】【投稿~9/7】 ロボットの住む世界で流行ってる罰ゲームとは?
- ・推しミネラルウォーターはありますか?
- ・都道府県穴埋めゲーム
- ・この人頭いいなと思ったエピソード
- ・準・究極の選択
- ・ゆるやかでぃべーと タイムマシンを破壊すべきか。
- ・歩いた自慢大会
- ・許せない心理テスト
- ・字面がカッコいい英単語
- ・これ何て呼びますか Part2
- ・人生で一番思い出に残ってる靴
- ・ゆるやかでぃべーと すべての高校生はアルバイトをするべきだ。
- ・初めて自分の家と他人の家が違う、と意識した時
- ・単二電池
- ・チョコミントアイス
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
Minecraft 統合版(PC)の描画距...
-
VB6,リストボックスの特定行の...
-
CScrollViewの使用方法について
-
VBAにGDI+を参照させる方法
-
OnDrawが呼び出されません
-
StretchBlt関数について
-
GDI+で高速な描画
-
アプリケーションのデザイン
-
Windowのちらつき防止
-
VB2010で、チャートコントロー...
-
NVIDIAのシェーダーキャッシュ
-
SHGetFileInfoでアイコンが取得...
-
フラッシュで正六角形を作る方法
-
画面全体を再描画させたい
-
ダイアログのボタンコントロー...
-
ワードで文章の横に写真を添付...
-
WM_PAINTとWM_MOVEで同じ事をし...
-
GDI+について
-
ワイプ表示について。
-
物理シミュレーションの可視化(C#)
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
VB6,リストボックスの特定行の...
-
word
-
NVIDIAのシェーダーキャッシュ
-
MFCでOnPaintのタイミング
-
Minecraft 統合版(PC)の描画距...
-
google Colabでmatplotlibの描...
-
TextBoxに文字を書いても表示さ...
-
[VB.net] DataGridViewの列ヘッ...
-
UpdateData( FALSE); による文...
-
OneNote 2010 文字と描画がずれる
-
Labelの文字をスクロールする際...
-
InvalidateRectの使い方について
-
VB.netでのライン描画方法がわ...
-
CStaticコントロールの静的イメ...
-
VC++プログラムをつかったBMP画...
-
WM_SIZEとWM_SIZINGの違い (Win...
-
エクセルでガンチャートを作成...
-
c言語を使いダイアログにbmpを...
-
WM_PAINT
-
MFCのタイマーのつかい方を教え...
おすすめ情報