アプリ版:「スタンプのみでお礼する」機能のリリースについて

こんにちは、C言語においてグラフを表示することで質問があります。

いま、時間で変化していくある値を(x、y)をfprintfで出力し、datファイルに保存しました。それをwgnuplotで表示すると、きちんと表示することができました。そこで質問なんですが、
時間T=0のときに、X=1、Y=1。 T=1のときに、X=2、Y=2とY=Xの関係で変化していったとすると、直線であらわされますよね?
それを、グラフ上で時間が経過していくと、点として右上に動いて行くように、視覚的に見ることはできるんでしょうか?
いろいろとフリーソフトなどを探したのですが、よくわかりませんでした。。何か知っていたらお願いします。あるいは、C言語では逐次的に表現などできないとか、そういったアドバイスもあればお願いします。

すぐに返信できないかもしれませんが。よろしくお願いします。

A 回答 (19件中1~10件)

あぁ、魚の群れの行動というのだから、たとえば、魚一匹ごとに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 とか、、、いろいろしてみたのですが、、ダメでした。


今からもう少し調べてみようと思っています。お返事ありがとうございます。

補足日時:2007/08/28 17:19
    • good
    • 0
この回答へのお礼

すいません。
myprogram.exeの実行ファイルは簡単に、みつかりました。
debugフォルダの中にありました。
ただ、myprogram | pgnuplotとうったんですが、
pgnuplotは内部コマンド、または、外部コマンド、操作可能なプログラムまたは、パッチファイルとして認識されません。と表示されてしまいました。
どのようにしたらいいでしょうか。

お礼日時:2007/08/28 17:47

理解できてよかったですね^^



サンプルプログラムの adavance で、次の表示時刻の魚群の位置を設定しておけば、とりあえず、魚一匹を一点で表現した魚群の動いている様子を見せることができると思います。

プレゼンテーションなどで、それっぽい魚を描いたり、水中を再現した背景にしたいなど、もっときれいに見せたいというなら、それ相応のグラフィックライブラリを使うのがいいと思います。Linux 環境などでは、vtk を使うとか、もっと凝りたいなら OpenGL(Mesaなど)で直接コーディングするとか(そこまで凝る必要があるのかとは思いますが…笑)。わたしはグラフィックスはぜんぜん詳しくないので、もし凝りたくて、ご自分で探して見つけられないというのであれば、グラフィック専門のところへ、「どういうツール・ライブラリがいいのか」、質問するのがいいんじゃないかと思います。

gnuplot でも結構いろいろなことができるので、gnuplot の demo フォルダにある all.dem を動かして、どんなことができるのか、一度、見てみるのもいいかもしれません。「じゃあ、こうしよう♪」というインスピレーションが沸くかもしれませんしね。では、研究がんばってください。

この回答への補足

そうですか!!ありがとうございますw
せっかくなので凝ったものにしてみたいとおもいます。
ただ、まだ魚たちがうまく、群行動してくれないのでそこを直す必要がありますが・・・汗

本当にありがとうございました。

補足日時:2007/08/29 17:12
    • good
    • 0

あぁ、あとそれから、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 コマンドを発行させないようにするなどの方法を取ればよいでしょう。
    • good
    • 0

もう一つ追加:



サンプルプログラムをコンパイル・リンクして(myprogram.exe とする)、コマンドプロンプトから実行したときに、コマンドプロンプト上に出力されるものがすべて gnuplot への入力となります。
    • good
    • 0

それから、gnuplot と C言語は別のものなので、C言語の本に gnuplot のことは書いてないのが普通です。

gnuplot のことは、gnuplot のヘルプなどを見て勉強するか、検索エンジンで gnuplot というキーワードで検索すると、簡単な使い方が書いてあるHPなどはすぐに見つかるでしょう。
    • good
    • 0

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 に指示するものです。
    • good
    • 0
この回答へのお礼

やっと理解することができました!!
今までポインタから逃げてきた人間だったので、
今回再勉強によりだいぶ進化したような気がします。
おかげさまで、毎日C言語三昧ですw
size tを使った方法はとても便利ですね!!
たいへん参考になりました!

お礼日時:2007/08/29 13:43

ありゃ。

。。もううまく言ってた訳ですね。よかったよかった。

プログラムは適当に使えるものは利用して、研究をしっかりとがんばってください(笑)

この回答への補足

ありがとうございます!
途中でカレントフォルダから相対パス・・・
と書いてあるところを読んで気づきました!!!

実行することはできたのですが、プログラムの解釈が難しいです。
ためしに、似たようなプログラムを作ったりしているのですが、
どうも違います。うまく表示されなかったり、一つの点しか表示されなかったりといったことがあります。
puts("")の中で直接、pgnuplotに指示を出しているんですよね?
自分の持っている、C言語の本にはあまり深く書いてないので、
少し理解が難しいです。for文の回す範囲や、nの導出の仕方が特にです。
もしよろしければ解説していただけないでしょうか?

補足日時:2007/08/28 20:24
    • good
    • 0

あっ、そうそう^^ unistd.h って、Unix 環境のヘッダだから、Windows ではないかもしれません(POSIX 対応のがあればあるのかもしれないけど、詳しくない^^;)。



unistd.h は sleep() を使うために include してるだけなので、もし、sleep() を使うことでリンクエラーになるなら、sleep() のところを削除してもかまいません(点の動きが早くて、描画状態がわからないかもしれませんけどね^^)。
    • good
    • 0

パスの通し方がわからなければ、すべて、カレントディレクトリからの相対パスで書けばいいんじゃないですか?わたしの場合は、たとえば、



 > "..\home\watashi\work\c\myprogram" | "d:\downloads\gnuplot\gnuplot\bin\pgnuplot"

と打つと、うまくいきます。絶対パスで指定してもいいですけど、パスを通しておくのが簡単ですけどね(笑)
    • good
    • 0

> 自分で描画を行う場合には、わざわざ外部ファイルに…



それはそのとおりだと思います。自作の描画機能で、わざわざ外部ファイルに出力するように設計する人は、まれでしょう^^

まぁ、kenpanch7さんは、学生さんで、研究の補助として「動いている」ように見える描画機能がほしいだけみたいで、そこそこ動けばよいようですし、「暇なときに見てみます」って回答なので、そんなにまじめに作るほど重要でもないんでしょう(笑)それに「あるものは使えばいい」し、「自分で探して見つからなければ、人に聞くのもいい」でしょ。
    • good
    • 0
この回答へのお礼

連続投稿すいません、、、
実行ファイルとpgnuplotを同じフォルダにおけばできました。
本当にありがとうございました!!やっとみれたのでけっこう感動しました!!!
ただ、次は自分のプログラムにどうつかうかですね。
ありがとうございます。

お礼日時:2007/08/28 18:07

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!