初めまして。
c言語で関数ポインタを使って点を表示させ、グラフを書きたいのですが点を表示させる関数のところが分かりません。
具体的には配列を作ってx座標ごとにy座標を計算して保存、これを上から表示してぐグラフに見せたいのですがどうやって書いていいのか行き詰っています。
この関数外のプログラムは以下のように書きました。
どなたか教えてください。
#include <stdio.h> #include <math.h> int draw(int,int,int); int keisan( int ); int main(){ int max_x = 40; int max_y = 40; //x,y軸の最大値 draw( max_x, max_y, keisan ); } int draw(){ //この中が分かりません } int keisan( int x ){ /return x*x; }
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答5件
0
別回答を一つ。
そのグラフを描画するエリア分の文字型の2次元配列を確保しておき、予めスペースで埋めておきます
まず、軸を配列に描画(代入、というのが正しいか)していき、次に、グラフ本体を描画します
あとはその配列の内容を文字列として1行づつ出力します
いったんこうしたグラフ描画をパターン化しておけば、他のグラフを書くのにも使いまわしができますね
と、書いてからkazuma_sさんの回答とかぶってるのに気がついて、もうちょっと追加を。
私が作るなら、
- 二次元配列をスペースで埋める
- 軸を描画
- グラフの描画
- 二次元配列を1行づつ出力
と分けて、それぞれ一つの関数として実行できるようにさせます
各関数は引数に、二次元配列のアドレス、Xサイズ、Yサイズ、を取るようにしておきます
そうしておけば、他のグラフを書きたいときには、3つ目の関数を差し替えるだけでいけます
投稿2020/07/17 00:34
編集2020/07/17 00:40総合スコア88042
0
方法論がやっつけ感ですが,何かの参考になれば.
座標(x,y)に関して,曲線とのx方向あるいはy方向の距離がThresh
以下となる場合,(x,y)の場所に*
を表示するようにしています.
x方向あるいはy方向のどちらを用いるのかは関数df(曲線の傾き)の値によって決めています.
- 面倒なので,y軸は下向を正としています.
- 上記の方法のために,関数f(x)だけでなく,その一階導関数df(x)と,f(x)の逆関数inv_f(y)も定義しています.
- 質問コードに見られた
x*x
という関数だと,xの増加に対してyの値がすごい勢いで増えていってしまうので,適当な係数alpha
を乗じています.
C++
1const double alpha = 1.0 / 32; //coefficient 2double f( int x ){ return alpha * x * x; } //y = f(x) 3double df( int x ){ return 2 * alpha * x; } //df(x)/dx 4double inv_f( int y ){ return sqrt( y / alpha ); } // x = inverse_of_f(y) 5 6void draw( int max_x, int max_y, double Thresh ) 7{ 8 for( int y=0; y<=max_y; ++y ) 9 { 10 char DefaultChar = ( y==0 ? '-' : ' ' ); 11 for( int x=0; x<=max_x; ++x ) 12 { 13 double d = fabs( df(x)<=1.0 ? ( y-f(x) ) : ( x-inv_f(y) ) ); 14 char OutChar = ( (d <= Thresh) ? '*' : ( x==0 ? (y==0 ? '+' : '|') : DefaultChar ) ); 15 printf( "%c", OutChar ); 16 } 17 printf( y==0 ? ">\n" : "\n" ); 18 } 19} 20 21int main() 22{ 23 int max_x = 40; int max_y = 40; //x,y軸の最大値 24 draw( max_x, max_y, 0.5 ); 25 return 0; 26}
表示結果の一部(yのでかい側が切れています).
一番左上が原点(0,0)です.
*
が固まって並んで「太く」見えてしまう場所が生じますが…
投稿2020/07/17 01:56
編集2020/07/17 01:58総合スコア11996
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
関数 f(x) のグラフを書きます。a <= x < b です。
C
1#include <stdio.h> // printf 2#include <string.h> // memset 3#include <math.h> // sqrt, exp, log, sin 4 5#define A 0.0 // -1.0 6#define B 25.0 // A <= x < B 7 8double f(double x) 9{ 10 return (x - 1) * (x - 11) * (x - 21); 11 // return x; 12 // return sqrt(x); 13 // return sqrt(25*25 - x*x); 14 // return exp(x * 0.1); 15 // return log(x + 1); 16 // return sin(x * 0.3); 17} 18 19#define H 25 20#define W 80 21#define FMT "%.79s\n" 22 23void draw(int n, double a, double b, double *y) 24{ 25 char scr[H][W]; // screen 26 memset(scr, ' ', sizeof scr); 27 double min_y = 1e99, max_y = -1e99; 28 for (int i = 0; i < n; i++) { 29 if (y[i] < min_y) min_y = y[i]; 30 if (y[i] > max_y) max_y = y[i]; 31 } 32 double h = max_y - min_y, w = b - a; 33 int x = -W * a / w, z = -H * min_y / h; 34 if (x >= 0 && x < W) 35 for (int i = 0; i < H; i++) scr[i][x] = '|'; 36 if (z >= 0 && z < H) { 37 for (int i = 0; i < W; i++) scr[z][i] = '-'; 38 scr[z][W-2] = '>'; 39 } 40 if (x >= 0 && x < W && z >= 0 && z < H) scr[z][x] = '+'; 41 42 for (int j = 0; j < n; j++) { 43 int i = (y[j] - min_y) * H / h; 44 if (i >= 0 && i < H && j >= 0 && j < W) scr[i][j] = '*'; 45 } 46 for (int i = H; --i >= 0; ) printf(FMT, scr[i]); 47} 48 49int main(void) 50{ 51 int n = W; 52 double a = A, b = B, d = (b - a) / n, y[W]; 53 54 for (int i = 0; i < n; i++) { 55 double x = a + d * i; 56 y[i] = f(x); 57 } 58 draw(n, a, b, y); 59}
追記
char scr[H][W]; をローカル変数にし、initScreen() を削除しました。
投稿2020/07/16 20:17
編集2020/07/17 00:25総合スコア8224
0
C言語はグラフを描画するのに適していない言語です。一般にはpython, R, gnuplot, Oxyplot(C#などの.NET系)が用いられます。
Cでよく見るのはCからgnuplotを叩く例でしょうか。
いずれにせよ根本的にやり方を見なお方がいいと思います。
投稿2020/07/16 14:14
総合スコア5852
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/07/16 14:20
2020/07/16 15:04
2020/07/16 16:19
2020/07/16 16:38
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。