ページ 11

sinのグラフについて

Posted: 2007年1月26日(金) 13:12
by にゃんこ
はじめまして。大学の課題なんですがどんなに考えてもまったく分からないので教えてください(>△<)

1. 時間tを変数とする正弦波y=20*sin(g(t))を考える。g(t)は、角度変化を表し、g(t)=t-180.0[deg]とする。t=0から360まで1刻みでyの値(データと呼ぶ)を求める。その角度とデータをそれぞれ配列に保存する。配列に保存した角度とデータの数値をモニタに表示する。

2. 1.のデータをスペースとアスタリスクを用いて表示するプログラムを作成せよ。ただし、横軸を角度、縦軸をデータとする。(ただし、グラフの縦軸と横軸はそれぞれ適切に設定せよ)また、グラフを描画する部分は必ず関数化すること。

1.の方は以下のような感じで作ってみたのですが、2.がまったく分かりません。。よろしくお願いします。

#include<stdio.h>
#include<math.h>

#define theta 360

main()
{
double y,f,b[theta];
int t,g,a[theta];

printf("配列の添字(時間) "
"角度を保存する配列 "
"データを保存する配列\n");

for(t=0; t<=theta; t++){
g = t - 180;
f = g*M_PI/180;
y = 20*sin(f);
a[t] = g;
b[t] = y;

printf("\t%d",t);
printf("\t\t%d",a[t]);
printf("\t\t\t%.3f",b[t]);
printf("\n");
}
}

Re:sinのグラフについて

Posted: 2007年1月26日(金) 13:56
by box
> 1.の方は以下のような感じで作ってみたのですが、2.がまったく分かりません。。よろしくお願いします。

tが360の場合までを扱うためには、配列の大きさは361でなければなりません。
a[361]と定義して、a[0]~a[360]の361個の値を扱ってください。bも同じです。

さて、サインカーブの表示の件です。
画面の縦方向を角度、横方向を関数値にすると、プログラミングが楽です。
そうすると、横方向の値の範囲は-20~20となります。縦方向は0~360の361行です。
パソコン画面の横方向が80桁分あるとして、仮に横幅全体を使ってサインカーブを
表示するとしたら、
-20→1桁目に'*'を表示する
(中略)
+20→80桁目に'*'を表示する
ことになります。
つまり、「関数値」から「画面上の桁数」への変換ができればよいことになります。

Re:sinのグラフについて

Posted: 2007年1月26日(金) 15:20
by 管理人
↑クリックで画像が拡大します↑

まず、簡単なグラフから書いてみましょう。
boxさんのおっしゃっているグラフを
水平方向をy,鉛直方向をxとして考えます。

y=x^2のグラフはどんな形になるか想像できますね。

今それが-90度傾いた形になるはずです。

xの値を1つずつ動かしながら、そのつどyの値を計算し、
yの値分だけスペースを表示します。

以下のプログラムを見て、仕組みを理解してください。
#include <stdio.h>
int main(){
	int i,x,y;
	for(x=-7;x<=7;x++){
		y=x*x;
		for(i=0;i<y;i++)
			printf(" ");
		printf("*\n");
	}
	return 0;
}

実行結果は添付画像のようになります。

Re:sinのグラフについて

Posted: 2007年1月26日(金) 15:20
by にゃんこ
回答ありがとうございます♪♪
ご指摘のところはそのように直してみます。


画面の縦方向を角度、横方向を関数値にするとプログラミングが楽とのことですが、問題文で「横軸を角度、縦軸をデータ」と指定されているのですが、そうするとまた考え方も変わってくるのでしょうか??

Re:sinのグラフについて

Posted: 2007年1月26日(金) 15:40
by 管理人
すみません、そういう指定があるんですね。
それでしたら先ほどのような考え方はふさわしくないので、
もろ関数として解きましょう。

次にサンプルを示しますね。


ちなみにコンソール画面の画面のバッファサイズ、フォントサイズは
上のバー上で右クリックすることで「規定値」から変更できますので
バッファサイズ、画面サイズを大きくして、フォントサイズを小さくすると
グラフが見やすくなります。

Re:sinのグラフについて

Posted: 2007年1月26日(金) 15:52
by 管理人
↑クリック↑

このグラフは普通のグラフです。

このプログラムは、yが0~25、xが-5~5としてループさせてグラフを書いています。
格子点を1つずつ全て進んでいき、その値が「x*x」と一致したところでは*を表示し、
一致しなかったところでは、スペースを表示しています。

例えば、yは25からはじまりますね。xは-5から始まりますね。
今y=25,x=-5において、25は-5*-5と一致するから*を出力します。
次y=25,x=-4において、25は-4*-4と一致しませんからスペースを出力します。
水平方向が全部すんだら改行・・・。

これを全部やるとグラフのようになります。

サンプルはこちらです。
#include <stdio.h>
int main(){
	int i,x,y;
	for(y=25;y>=0;y--){
		for(x=-5;x<=5;x++){
			if(y==x*x)
				printf("*");
			else
				printf(" ");
		}
		printf("\n");
	}
	return 0;
}

これをdouble型で解く場合は、その判定において、適合する範囲を決めましょう。

Re:sinのグラフについて

Posted: 2007年1月26日(金) 16:08
by 管理人
↑クリック↑

上記プログラムを利用して普通のsin波作ってみたんですけど、完成品はこんな感じになりました。

Re:sinのグラフについて

Posted: 2007年1月26日(金) 21:33
by にゃんこ
何度も何度もすいません。
管理人さんのおっしゃっているy=x^2のグラフについては理解できました。。
ですが、それを利用してsinのグラフを作ってみようとしても、どうしてもうまくいきません。
申し訳ありませんがもう少し教えてください(>_<)
お願いします。

Re:sinのグラフについて

Posted: 2007年1月26日(金) 21:59
by box
> ですが、それを利用してsinのグラフを作ってみようとしても、どうしてもうまくいきません。

では、現時点のソースコードを見せてください。

Re:sinのグラフについて

Posted: 2007年1月26日(金) 23:21
by にゃんこ
中途半端なトコまでですいませんが、現在はこんな感じです↓↓

int main(){

int x,y;
double f,y1;

for(y=-20; y<=20; y++){
for(x=0; x<=80; x++){
f = x*360/80-180;
y1 = 20*sin(f*M_PI/180);

Re:sinのグラフについて

Posted: 2007年1月27日(土) 03:26
by 管理人
私の書いたとおりにかけば出来るはずですよ。

ちなみに普通のサイン波のプログラムはこちらです。

お書きになったプログラムはif文による*の出力が無いので表示されないと思います。

振幅は-1~1で、角度は4πまでとしています。0.1刻みですすめていますので、

判定する範囲は、今の場所プラスマイナス0.05ということになります。
#include <stdio.h>
#include <math.h>

#define PI 3.141592

int main(){
	double i,x,y;
	for(y=1.0;y>=-1.0;y-=0.1){
		for(x=0;x<=4.0*PI;x+=0.1){
			if(y-0.05<=sin(x) && sin(x)<y+0.05)
				printf("*");
			else
				printf(" ");
		}
		printf("\n");
	}
	return 0;
}

Re:sinのグラフについて

Posted: 2007年1月28日(日) 12:13
by にゃんこ
回答ありがとうございました☆★
おかげで何とか課題も進められそうです(*^_^*)
本当にありがとうございました。。