プログラムを解読して、楕円の内外を色で塗る

このQ&Aのポイント
  • このプログラムは、与えられた楕円の内部と外部を色で塗る処理を行います。
  • プログラムの仕組みとしては、中心の座標と楕円の短径・長径を入力し、楕円の方程式を元にして座標ごとに色を塗っていきます。
  • 生成された結果は、指定したファイル名で保存されます。
回答を見る
  • ベストアンサー

このプログラムを解読してください。

これは、楕円の内部と外部に色を塗るプログラムです。 #include <stdio.h> #include <stdlib.h> #include <string.h> #include <math.h> #define MS 200 main() { char fi[50]; int i,j; double x0,y0,a,b; FILE *fp; unsigned short header[13]={0x4d42,54490,1,0,0,26,0,12,0,MS,MS,1,24}; unsigned char bmp[MS][MS][3]; for(i=0;i<=MS-1;i++) { for(j=0;j<=MS-1;j++) { bmp[i][j][0]=0; bmp[i][j][1]=255; bmp[i][j][2]=0; } } printf("中心のx座標:"); fgets(fi,50,stdin); x0=atof(fi); printf("中心のy座標:"); fgets(fi,50,stdin); y0=atof(fi); printf("短径:"); fgets(fi,50,stdin); a=atof(fi); printf("長径:"); fgets(fi,50,stdin); b=atof(fi); for(i=0;i<=MS-1;i++) { for(j=0;j<=MS-1;j++) { if((pow(j-x0,2.0)/pow(a,2.0))+(pow(i-y0,2.0)/pow(b,2.0))<=1) { bmp[i][j][0]=0; bmp[i][j][1]=0; bmp[i][j][2]=255; } } } printf("Input file name:"); fgets(fi,50,stdin); fi[strlen(fi)-1]='\0'; if((fp=fopen(fi,"wb"))==NULL) { fprintf(stderr,"Error: file open [%s].\n",fi); exit(1); } fwrite(header,2,13,fp); fwrite(bmp,1,MS*MS*3,fp); fclose(fp); }

質問者が選んだベストアンサー

  • ベストアンサー
  • salsberry
  • ベストアンサー率69% (495/711)
回答No.3

・stdin: 標準入力のこと。標準入力とは何かを説明し始めると長いので省略。 ・fgets(fi,50,stdin): 標準入力から配列fiに1行分のデータを読み込む。最大50バイトまで。 ・atof(fi): 配列fiに入っている文字列からdouble型の数値データを得る。 ・MSから1を引く理由: C言語の配列の添え字は0から始まる。要素数200(MS)の配列の添え字は0~199(MS-1)だから。for(i=0;i<MS;i++)と書けば1を引かなくてもいい。 ・fopen(fi,"wb")): 配列fiの内容をファイル名として、ファイルをバイナリモードで書き込み用に開く。 ・fwrite(header,2,13,fp): 配列headerから2バイト長のデータを13個、fpで示されるファイルに書き込む。

masak777
質問者

補足

標準入力の意味を教えてください。

その他の回答 (4)

  • D-Matsu
  • ベストアンサー率45% (1080/2394)
回答No.5

> unsigned short header[13]={0x4d42,54490,1,0,0,26,0,12,0,MS,MS,1,24}; これがコメント付きでないという時点でサンプル失格というのは他の方の回答と同じ意見として、これはビットマップファイルのヘッダ情報でしょうね。 標準入力については参考URLを読んだ上で、どこがわからないかを補足願います。 #大雑把な説明としてはこれで十分でしょう

参考URL:
http://ja.wikipedia.org/wiki/%E6%A8%99%E6%BA%96%E3%82%B9%E3%83%88%E3%83%AA%E3%83%BC%E3%83%A0
masak777
質問者

補足

標準入力の意味は分かりました。 今分からないのはfgets(fi,50,stdin)とx0=atof(fi)です。 回答よろしくお願いします。

  • kmee
  • ベストアンサー率55% (1857/3366)
回答No.4

回答が付いているようなので。 > fgets関数の意味が分かりません。 > fgets(fi,50,stdin)とはどういう意味ですか? > atofって何ですか? > x0=atof(fi)とはどういう意味ですか? > if((fp=fopen(fi,"wb"))==NULL)のwbって何ですか? > fwrite(header,2,13,fp);とはどういう意味ですか? これらは全部マニュアルや参考書、解説サイトを読めば書いてあることです。 解説付きで例文が載ってるものもあります。 わからない関数があったらまずはマニュアルを読む、ネットで検索する。これくらいはやりましょう。 その上で、なおわからないことがあったら聞いてみる、くらいでないと上達しません。 まあ、このプログラムは「悪い見本」とも言えるものなので、多少わからなくても仕方無いと思いますが。 例えば > #define MS 200 画像サイズに使ってるけど、MSって名前はどんな意味? > unsigned short header[13]={0x4d42,54490,1,0,0,26,0,12,0,MS,MS,1,24}; 0x4d42とか訳のわかんない数値がコメントも無しにいきなり出てきてるし

masak777
質問者

補足

僕もunsigned short header[13]={0x4d42,54490,1,0,0,26,0,12,0,MS,MS,1,24};の0x4d42の意味が分かりません。

  • kmee
  • ベストアンサー率55% (1857/3366)
回答No.2

あなたがわかっている箇所を、私たちがダラダラ解説しても、お互いにとって無駄でしかありません。 わからない箇所を絞ってもらえませんか? あなたが、御自身の理解度を調べることにもなりますし、答える方にとっても楽なので

masak777
質問者

補足

fgets関数の意味が分かりません。 fgets(fi,50,stdin)とはどういう意味ですか? stdinって何ですか? atofって何ですか? x0=atof(fi)とはどういう意味ですか? printf("中心のy座標:"); for(i=0;i<=MS-1;i++)のMS-1って何ですか? なぜ、MSから1を引いたんですか? if((fp=fopen(fi,"wb"))==NULL)のwbって何ですか? fwrite(header,2,13,fp);とはどういう意味ですか?

回答No.1

どう解読するのでしょうか? >これは、楕円の内部と外部に色を塗るプログラムです。 と云う事は初歩的な解読が終わっているのだと思いますが…

masak777
質問者

補足

一文一文分かりやすく教えてほしいということです。

関連するQ&A

  • プログラムの作成

    Cで、キ-ボ-ドから整数を1個(mとする)、実数を1個(xとする)それぞれ入力し、 S=Σ(n=0からmまで)1/2n+1×(x-1/x+1)^2n+1 の値を求めるプログラムを作ってみたのですが、あってるかどうかわかりますか? #include<stdio.h> #include<math.h> main() { double y=0; int i,m,x; printf(\" Input m: \") scanf(\"%lf\", &m); printf(\" Input x: \") scanf(\"%lf\", &x); for(i=0; i <= m; i++) { y += 1/(2*i+1)*pow((x-1)/(x+1),2*i+1) } printf(\" S = %d\n\", y) }

  • γ関数のプログラム(初心者です)

    以下のようにγ関数のプログラムを組みました。 とりあえず整数値を入力すれば、正しい値は返しているということがprintfの4で確認できました。 もとはfortranで組んだプログラムをCに置き換えました。 ですが、実際走らせてみると、4で値は確認できますがsegmentation faultが出てしまいます。 ですからサブルーチンファイル(ユーザー関数?)として利用できません。 何がいけないのでしょうか? 正しくyが帰ってくるようにどうなおしたらよいのか教えてください。 #include <stdio.h> #include <math.h> double gamma(double x) { double c[8],y,a,r,b,s; int i; a=1.; r=1.; c[1]=5.771916e-01; c[2]=9.882058e-01; c[3]=8.970569e-01; c[4]=9.182068e-01; c[5]=7.567040e-01; c[6]=4.821993e-01; c[7]=1.935278e-01; c[8]=3.586834e-02; printf("0 %f\n",x); while(1){ if(x>2.){ x=x-1.; a=a*x; printf("1 %f %f\n",x,a); } else if(x<1.){ a=a/x; x=x+1.; printf("2 %f %f\n",x,a); } else{ break; } } x=x-1.; for(i=1;i<8;i++){ b=(double)(i); s=(c[i]*((double)(pow(-1,b))) *((double)(pow(x,b)))); printf("3 %d %f\n",i,c[i]); r=r+s; } y=a*(r+(0.03586834*((double)(pow(-1,8)))*((double)(pow(x,8))))); printf("4 %f\n",y); return y; } main() { double x,y; printf("数字を入力してください。"); scanf("%lf",&x); printf("メインプログラム %lf\n",x); y=gamma(x); printf("%f\n",y); }

  • RPGゲームの簡単なプログラムを打ってみたんですがうまく表示されません

    RPGゲームの簡単な初歩的なサンプルプログラムを自分で打ってみたんですが、思った通りに表示されません。 以下のソースのどこかおかしいとこありますでしょうか。 #include<stdio.h> #include<windows.h> #define MAP_SIZE_Y 10 #define MAP_SIZE_X 10 int x = 4,y = 5; int j,i; int map[100][100] = { {1,1,1,1,1,1,1}, {1,0,0,3,0,0,1}, {1,0,0,0,0,0,1}, {1,0,2,0,2,0,1}, {1,0,0,0,0,0,1}, {1,1,1,1,1,1,1}, }; void DrawMap(){ for(j = 0; i < MAP_SIZE_Y; j++){ for(i = 0; i < MAP_SIZE_X; i++){ if(j == y && i == x){ printf("勇"); }else{ switch ( map[j][i]){ case 1: printf("■"); break; case 2: printf("兵"); break; case 3: printf("王"); break; default:printf(" "); break; } } } printf("\n"); } } void main(){ while(1) { system("cls"); DrawMap(); } }

  • プログラムが解読できないです。解読していただける方いませんか?

    以下のプログラムなんですが、各変数の値、および配列がどのように動いているのか、理解できなくて困っています。どなたか解読していただける方いらっしゃいましたら、出来るだけ詳しくお願いします。。 { int triangle[3]={0,1,2}; int nextVertex; int i; /* 三角形の頂点の組を表示 */ printf("Triangle %d : ",1); for(i=0;i<3;i++){ printf("(%f, %f)",x[triangle[i]], y[triangle[i]]); } printf("\n"); /* 各頂点の処理 */ for(nextVertex=3;nextVertex < n; nextVertex++){ double m,k; int side1,side2; /* 傾きが極端に大きくなったときに計算誤差が発生。これが起こらないよう、傾きが1を境に処理をxとyで入れ替える*/ if(y[triangle[2]]-y[triangle[1]]<x[triangle[2]]-x[triangle[1]]){ /* 直線の傾き・切片を計算 */ m=(y[triangle[2]]-y[triangle[1]])/(x[triangle[2]]-x[triangle[1]]); k=y[triangle[2]]-m*x[triangle[2]]; /* side1,side2にはy>mx+kが成り立っていれば0以外、成り立たなければ0がそれぞれ入る */ side1=y[triangle[0]]>m*x[triangle[0]]+k; side2=y[nextVertex]>m*x[nextVertex]+k; }else{ /* xyを入れ替えただけ */ m=(x[triangle[2]]-x[triangle[1]])/(y[triangle[2]]-y[triangle[1]]); k=x[triangle[2]]-m*y[triangle[2]]; side1=x[triangle[0]]>m*y[triangle[0]]+k; side2=x[nextVertex]>m*y[nextVertex]+k; } /* 判別結果によって次の三角形の頂点を選択 */ if(side1^side2){ /* 排他的論理和を使って判別。side1/side2のいずれか一方のみが非0のとき条件成立 */ triangle[0]=triangle[1]; } /* else節はなくても一緒なので略す else{ triangle[0]=triangle[0]; } */ triangle[1]=triangle[2]; triangle[2]=nextVertex; /* 三角形の頂点の組を表示 */ printf("Triangle %d : ",nextVertex-1); for(i=0;i<3;i++){ printf("(%f, %f)",x[triangle[i]], y[triangle[i]]); } printf("\n"); } }

  • C言語のプログラムを見てください

    ある100行の値がx列、y列の2列あるファイルを読み込んでそれを配列に入れ、yの最小値及びそれと同じ行にあるxの値を表示するプログラムを書きたいのですがy列の最小値を表示するプログラムを書き終えた所でコンパイルして実行してみると正しく値が表示されませんでした。それどころか実行するたびに値が変わってしまいます。どこがおかしいのかわからないため、ご指摘のほどよろしくお願いします。また、できれば同じ行にあるx列の値も表示させるプログラムを教えてください。 よろしくお願いします。 #include <stdio.h> #include <stdlib.h> #define N 100 int main(void) { int x[N],i; double y[N],min; FILE *fp; fp=fopen("book.dat","r"); if(fp==NULL){ puts("can't open file!"); exit(-1); } for(i=0;i<N;i++){ fscanf(fp,"%d %lf", &x[N],&y[N]); printf("x=%d\n y=%lf\n",x[N],y[N]); } min=y[0]; for(i=1;i<N;i++){ if(y[i]<min) min=y[i]; } fclose(fp); printf("最小値:%lf\n",min); return 0; }

  • C言語、行列の積を求めるプログラムについて

    「次に示す行列x,yの積を求めるプログラムを作成せよ。   x[2][3]={{1,2,3},{4,5,6}} y=[3][2]={{1,5},{5,3},{81}}」 という問題です。自分ではとりあえず、 #include<stdio.h> int main(void) { int i,j; int x[2][3]={{1,2,3},{4,5,6}}; int y[3][2]={{1,5},{5,3},{8,1}}; int xy[3][3]={0}; for(i=0;i<3;i++) for(j=0;j<3;j++) xy[i][j]=x[i][j]*y[i][j]; for(i=0;i<3;i++){ for(j=0;j<3;j++) printf("%3d",xy[i][j]); putchar('\n'); } return 0; } というプログラムを作ってみましたが、ダメでした。 ちゃんと積の表示が出るようにするにはどこをどう変えるべきでしょうか?

  • ソートプログラム

    ファイルから10個の整数が 29 45 11 2 86 91 33 62 77 59 のように一行に1個の形式で格納されている。このファイルから10個の整数を読み込み、選択法でソートし、この数字を小さい順に表示するプログラムを作成したのですが、ソート部分がうまくできません。どなたかどうすれば改善できるか教えてください。 <プログラム> #include<stdio.h> #include<stdlib.h> #define MAXN 100 int A[MAXN]; main() { _inputdata(); _selectionsort(1,10); _printdata(); } selectionsort(p,q) ___int p, q; { _int i, j, cmin, temp; _for(j = p; j <= q; j++){ __cmin = j; /* A[cmin]が現在の最小値 */ __for(i = j+1; i <= q; i++) ___if(A[cmin] > A[i]) cmin = i; __/* A[j]とA[cmin]との入れ換え操作 */ __swap(j, cmin); _} } swap(int x, int y) { _int temp; _temp = x; _x = y; _y = temp; } inputdata() { _FILE *fp; _if((fp=fopen("integers10.dat", "r"))==NULL) { __printf("ファイルが見つかりません: integers10.dat\n"); __exit(EXIT_FAILURE); _} _printf("データを入力\n"); _while(fscanf(fp, "%s", A)!=EOF) { ____printf("%s\n",A); _} _fclose(fp); } <コンパイル→実行> % gcc -o sort1 sort1.c % ./sort1 データを入力 29 45 11 2 86 91 33 62 77 59 ソート済みデータ 0 0 0 0 0 0 0 0 0 0 %

  • 漸化式のプログラム

    n=100としてn+1個の点(Xj,Yj) (j=1,2,3・・n)はどのようなグラフになるか?ただし、h=1/n, Xj=jh, Y(j+1)=Yj+hYj, Y(0)=1である。 このプログラムを教えてください。 #include <stdio.h> #include <math.h> main() { double pi, x, y; int i; pi=4*atan(1); x=1/100; y=1; for(i = 1; i<=100; ++i){ x=i*1/100; y[n+1]=y[n]+1/100*y[n]; printf("%lf %lf\n", i, x, y,); } } ではだめなんでしょうか?

  • ビットマップ画像を読み込むプログラムがうまく行きません。困ってます…。

    こんにちは。大学4年のyu-tinと申します。 現在、大学の研究で使用するためのプログラムとして、以下の機能を持ったプログラム作りに取り込んでいます。 1)ビットマップ画像(グレースケール、縦480×横640pixel)を読み込み、  その画像の1つ1つの画素の輝度値を表示させる 2)読み込んだビットマップ画像を出力させる しかし、作成したプログラムがうまく行きません。以下の3つの問題が発生しています。 a)0行0列~1行383列までの画素値がおかしい。  (0,0,0,0,1,1,1,0,2,2,2,0,3,3,3,0,…,254,0,255,255,255,0 となっている) b)出力した画像の最上部2行程度に、細くて黒い線が表示される。  (読み込んだ画像と全く同じ画像を出力させたい) c)出力した画像が、”ディスクエラー”によりPhotoshopで開けない。  (ペイントでは開ける) その問題のプログラムは、以下の通りです。 しかし、このプログラムは、他人のプログラムに改良を加えて作成したものです。なので、このプログラム自体、私自身が完璧に理解できていない状況です。 私は、プログラミングに関しては初心者に近いので、丁寧に教えて頂けると大変助かります。 研究が先に進まず、大変困っています…。みなさま、本当に、本当によろしくお願い致します。 //ビットマップ画像に関するプログラム。 //画像の表示と輝度値の表示を行う。 #include<stdio.h> #include<windows.h> #include<stdlib.h> #define X_SIZE 640  //画像の横幅(ピクセル数) #define Y_SIZE 480  //画像の縦幅(ピクセル数) #define Z_SIZE 1    //1つの画素に含まれる色の数 void *malloc(size_t size); void main(void) {  int i, j, k;   //ループ用変数 i…縦の画素用, j…横の画素用, k…色数用  int x=0;    //画像の横幅(ピクセル数)*/  int y=0;     //画像の縦幅(ピクセル数)  FILE *fp; /***********元画像データのメモリ確保*********/  BYTE ***mae;  mae=(BYTE ***)malloc(sizeof(BYTE **)*Y_SIZE);  for(i = 0; i < Y_SIZE; i++){   mae[i]=(BYTE **)malloc(sizeof(BYTE *)*X_SIZE);  }  for(i = 0; i < Y_SIZE; i++){   for(j = 0; j < X_SIZE; j++){    mae[i][j]=(BYTE *)malloc(sizeof(BYTE)*Z_SIZE);   }  } /*******画像の読み込み・輝度値の表示*******/  fp=fopen("sample1.bmp","rb");   //画像”sample1”を開く  BITMAPFILEHEADER bmfh;  BITMAPINFOHEADER bmih;  fread(&bmfh,sizeof(bmfh),1,fp);  fread(&bmih,sizeof(bmih),1,fp);  x=bmih.biWidth;  //インフォヘッダに含まれる画像の幅情報をxに代入  y=bmih.biHeight;  //インフォヘッダに含まれる画像の高さ情報をyに代入  for(i = 0; i < y ;i++){   for(j = 0; j < x; j++){    fread(&mae[i][j][0],sizeof(BYTE),1,fp);    if(i<640 && j<480)printf("%d, %d, %d\n",i, j, mae[i][j][0]);   //輝度値を表示   }  }  fclose(fp); /**************画像の表示*************/  //画像”sample1”を”sample2”という名前で出力する  fp = fopen("sample2.bmp" ,"wb");  //ヘッダの書き込み  fwrite(&bmfh,sizeof(bmfh),1,fp);  fwrite(&bmih,sizeof(bmih),1,fp);  for(i = 0; i < bmih.biHeight; i++){   for(j = 0; j < bmih.biWidth; j++){    fwrite(&mae[i][j][0],sizeof(BYTE),1,fp);   }  }  fclose(fp);  //ファイルをクローズ }

  • ラベリング処理プログラム

    画像のラベリング処理プログラムを作っているんですが どうもうまく実行できません。よければ教えていただけないでしょうか。 #include<stdio.h> #include<stdlib.h> int column, row; unsigned char val[4] = {0,0,0,0}; unsigned char tmp[255]; int pos_y[4] = {-1, 0, 1, 0}; int pos_x[4] = {0, 1, 0, -1}; int i, j, x, y, label, level, label1; int label_count = 1; unsigned char *in, *out; void labeling_main(); void labeling_search(); void labeling_main() { for(i = 0; i < y; i++){ for(j = 0; j < x; j++){ printf("aaa\n"); if(out[i * x + j] == 255){ printf("bbb\n"); fflush(stdout); out[i * x + j] = label_count; labeling_search(label_count, i, j); label_count++; } } } } void labeling_search(int label_count, int x, int y) { for(i = 0; i < 4; i++){ if(out[(pos_y[i] + y) * x + (pos_x[i] + x)] == 255){ out[(pos_y[i] + y) * x + (pos_x[i] + x)] = label_count; labeling_search(label_count,(pos_y[i]+y),(pos_x[i]+x)); } } printf("ccc\n"); } int main(int argc, char *argv[]) { int result; int head, Magic; unsigned char *image, *in, *out, *res, *ros; FILE *fin, *fout; if(argc!=3){ printf("Usage : %s input output\n",argv[0]); exit(1); } fin = fopen(argv[1],"rb"); /* -------------------- ヘッダ取得ここから -------------------- */ fgets(tmp,255,fin); if(tmp[0]!='P') return 0; sscanf(tmp,"P%d",&Magic); if(Magic < 1 || Magic > 6) return 0; do fgets(tmp,255,fin); while(tmp[0]=='#'); sscanf(tmp,"%d %d",&x,&y); if(x < 1 || y < 1) return 0; fgets(tmp,255,fin); sscanf(tmp,"%d",&level); /* ヘッダの確認 */ printf("P%d\n",Magic); printf("%d %d\n",x,y); printf("%d\n",level); /* 画素の読み込み */ in = (unsigned char *)malloc(sizeof(unsigned char) *x*y); fread(in,sizeof(unsigned char),x*y,fin); fout = fopen(argv[2],"wb"); fprintf(fout,"P%d\n",Magic); fprintf(fout,"# My new PGM\n"); fprintf(fout,"%d %d\n",x, y); fprintf(fout,"%d\n",level); fwrite(out, sizeof(unsigned char),x*y, fout); out = (unsigned char *)malloc(sizeof(unsigned char) *x*y); //2値画像 for (i = 0; i < y; i++) { for (j = 0; j < x; j++){ if(in[i * x + j] > 120){ out[i * x + j] = 0; }else if(in[i * x + j] <= 120){ out[i * x + j] = 255; } } } labeling_main(); printf("Max label number:%d\n",label_count); free(in); free(out); fclose(fin); fclose(fout); } コンパイルは通るのですが実行するとlabeling_mainの if文でセグメンテーションが出てしまいます。

専門家に質問してみよう