質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
多次元配列

1次元配列内にさらに配列を格納している配列を、多次元配列と呼びます。

プログラミング言語

プログラミング言語はパソコン上で実行することができるソースコードを記述する為に扱う言語の総称です。

関数

関数(ファンクション・メソッド・サブルーチンとも呼ばれる)は、はプログラムのコードの一部であり、ある特定のタスクを処理するように設計されたものです。

保存

保存(save)とは、特定のファイルを、ハードディスク等の外部記憶装置に記録する行為を指します。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

5回答

3517閲覧

c言語によるグラフ作成

bayberry

総合スコア0

多次元配列

1次元配列内にさらに配列を格納している配列を、多次元配列と呼びます。

プログラミング言語

プログラミング言語はパソコン上で実行することができるソースコードを記述する為に扱う言語の総称です。

関数

関数(ファンクション・メソッド・サブルーチンとも呼ばれる)は、はプログラムのコードの一部であり、ある特定のタスクを処理するように設計されたものです。

保存

保存(save)とは、特定のファイルを、ハードディスク等の外部記憶装置に記録する行為を指します。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

0クリップ

投稿2020/07/16 14:05

編集2020/07/16 14:19

!(e2c1eca5ebd75df8e1d68fb78bb32d44.png)
初めまして。
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ページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答5

0

別回答を一つ。

そのグラフを描画するエリア分の文字型の2次元配列を確保しておき、予めスペースで埋めておきます
まず、軸を配列に描画(代入、というのが正しいか)していき、次に、グラフ本体を描画します

あとはその配列の内容を文字列として1行づつ出力します

いったんこうしたグラフ描画をパターン化しておけば、他のグラフを書くのにも使いまわしができますね


と、書いてからkazuma_sさんの回答とかぶってるのに気がついて、もうちょっと追加を。

私が作るなら、

  • 二次元配列をスペースで埋める
  • 軸を描画
  • グラフの描画
  • 二次元配列を1行づつ出力

と分けて、それぞれ一つの関数として実行できるようにさせます
各関数は引数に、二次元配列のアドレス、Xサイズ、Yサイズ、を取るようにしておきます

そうしておけば、他のグラフを書きたいときには、3つ目の関数を差し替えるだけでいけます

投稿2020/07/17 00:34

編集2020/07/17 00:40
y_waiwai

総合スコア87747

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

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
fana

総合スコア11654

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

fana

2020/07/17 02:03

Threshを小さくすると,グラフの線が途切れ途切れになります. Threshを大きくすると,この方法論の良くない点が浮き彫りになります.(真面目にやるなら「点(x,y)と曲線との距離」を用いるべきところだが,xあるいはyの差を用いているので,結果が「変」になる)
guest

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
kazuma-s

総合スコア8224

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

bayberry

2020/07/17 11:12

コメントありがとうございます。HとWはなにか教えてほしいです。
kazuma-s

2020/07/17 18:42

height(高さ), width(幅) の意味ですが、row(行), col(列) のほうが良かったかもしれません。 screen(画面) の縦横のサイズです。
guest

0

環境に依存しますがcursesが使えるかもしれません。

投稿2020/07/16 14:29

can110

総合スコア38262

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

C言語はグラフを描画するのに適していない言語です。一般にはpython, R, gnuplot, Oxyplot(C#などの.NET系)が用いられます。

Cでよく見るのはCからgnuplotを叩く例でしょうか。

いずれにせよ根本的にやり方を見なお方がいいと思います。

投稿2020/07/16 14:14

yumetodo

総合スコア5850

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

bayberry

2020/07/16 14:20

回答ありがとうございます。 質問に掲載したように簡単なグラフです。今回はどうしてもc言語で書きたいのですが何か方法はありませんか?
yumetodo

2020/07/16 15:04

やってやれなくはないでしょうが、どう考えてもCでは必要なデータを吐き出すだけにして他の言語でプロットするのが圧倒的に幸せだと思います。楽だしきれいなグラフがサクッと作れるし。プログラマーは怠惰であるべきです。
Daregada

2020/07/16 16:19

どうしてもというくらいなので、おそらく「そういう課題」なのでしょう。課題は自分でやりましょう。 とりあえず、グラフにすることは置いておいて、「xが 0 からmax_x (40) まで1ずつ変化するときのyの値を配列に保存する」あたりから書いてみればいいのでは。
yumetodo

2020/07/16 16:38

というか自分で > 具体的には配列を作ってx座標ごとにy座標を計算して保存 と書いているのですから、あとはその二次元配列を上下逆にアクセスしながらprintしていけばそれっぽいものはできますよね。 つまりなにかというと、 int draw(int,int,int); int keisan( int ); という関数分けをするのはいいけど引数がおかしい。keisanは描画対象の数学的関数を表現した関数ポインタと二次元配列へのポインタを受け取るべきだろうし、drawは二次元配列を受け取るべき。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問