• 締切済み

このプログラムのelse以降についての書き方

以下のプログラムで、else以降についての書き方がわからず困っています。 このプログラムは、ランダムに与えられた点配置でx座標の小さい順からまず、三つ取り出し、三角形を作っていくのですが、最後のif文の点から点、辺から辺、辺から三角形など参照しているところで行き詰まっています。個々の配列の番号と=1とか2などの意味だけでも、分かる方いたら教えてください。よろしくお願いします。 --------------------------------------------------- #include <stdio.h> #include <stdlib.h> #define TRUE 1 #define FALSE 0 #define MAXV 100 #define MAXL 100 #define MAXT 100 #define OUTSIDE 0 int vs[MAXL]; /*始点のxyインデクス*/ int ve[MAXL]; /*終点のxyインデクス*/ int lscw[MAXL]; /*始点のclockwise line*/ int lecw[MAXL]; /*終点のclockwise line*/ int lscc[MAXL]; /*始点のcounter clockwise line*/ int lecc[MAXL]; /*終点のcounter clockwise line*/ int lt[MAXL]; /* left triangle */ int rt[MAXL]; /* right triangle */ int lfromv[MAXV]; /* any line from the vertex */ int lfromt[MAXT]; /* any line from the triangle */ double x[MAXV],y[MAXV]; int nxy; //頂点の数 int nvcurrent; /* 現時点での頂点数 */ int nline; /* number of lines */ int ntriangle /* number of triangles */ void makepoints(int *nxy,double *x,double *y); int tdet(int a1, int b1, int c1, int a2, int b2, int c2, int a3, int b3, int c3){ int retvalp, retvaln; retvalp = a1*b2*c3+a2*b3*c1+a3*b1*c2; retvaln = a1*b3*c2+a2*b1*c3+a3*b2*c1; return retvalp-retvaln; } int leftside(int vertex1, int vertex2, int vertex3)/*次の点が右側にあるか左側にあるか判定*/{ int a1, b1, c1, a2, b2, c2, a3, b3, c3; a1 = 1.0 ; b1 = x[vertex1]; c1 = y[vertex1]; a2 = 1.0 ; b2 = x[vertex2]; c2 = y[vertex2]; a3 = 1.0 ; b3 = x[vertex3]; c3 = y[vertex3]; if(tdet(a1, b1, c1, a2, b2, c2, a3, b3, c3)>0){ return TRUE; }else{ return FALSE; }; } void first_t(){ /* first 3 points are 1, 2 and 3 . */ if(leftside(1, 2, 3)==FALSE){ vs[1]= 1; ve[1]=2; vs[2]= 2; ve[2]=3; vs[3]= 3; ve[3]=1; lscc[1]=3 ; lscw[1]=3 ; lecc[1]=2 ; lecw[1]=2 ; lscc[2]=1 ; lscw[2]=1 ; lecc[2]=3 ; lecw[2]=3 ; lscc[3]=2 ; lscw[3]=2 ; lecc[3]=1 ; lecw[3]=1 ; lt[1]= OUTSIDE ; rt[1]= 1; lt[2]= OUTSIDE ; rt[2]= 1; lt[3]= OUTSIDE ; rt[3]= 1; lfromv[1]=1; lfromv[2]=2; lfromv[3]=3; lfromt[1]=1; nvcurrent =3; nline =3; ntriangle =1; }else/*leftside(1, 2, 3)==TRUE*/{ }; return; }

みんなの回答

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

> 「なんで三角形なのにどちらも3とつながるの?」「片方は2じゃないの?」とか考えてしまっています。 辺の始点(または終点)から見て左回り/右回りなので、その部分は不思議ではないです。一番最初の状態では頂点1に接している辺は辺1の他に辺3しかないので、辺2が現れることはありません。 納得がいかないようなら、そのコードを書いた人に尋ねてください。

atcrny374
質問者

お礼

返答遅れてすみません。 そうですね、ごめんなさい。理解できました。ありがとうございました。

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

> 個々の配列の番号と=1とか2などの意味だけでも、分かる方いたら教えてください。 データ構造を設計した人に聞くのが一番早いです。 vs[i]とve[i]はペアで、i番目の辺を表しているのであろうことは見当がつきます。つまり、 > vs[1]= 1; ve[1]=2; は辺1のの始点は頂点1、終点は頂点2という意味になるのでしょう。 vsとveは別々の変数にしないで、辺を表す構造体を作ってその中に始点と終点を入れたほうが良さそうな気がしますが。頂点を表すxとyも同様。 以下全くの当てずっぽうです。鵜呑みにしないでください。 > lscc[1]=3 ; lscw[1]=3 ; 辺1の始点において、辺1の隣(反時計回り)にあるのは辺3。同じく、辺1の隣(時計回り)にあるのも辺3。以下同様。 三角形が増えていったら、反時計回り側にある辺と時計回り側にある辺が別のものになる場合が出てくるだろうと思います。 > lt[1]= OUTSIDE ; rt[1]= 1; 辺1の左側には三角形がない。辺1の右側にあるのは三角形1。 > lfromv[1]=1; 頂点1には辺1が接している。 > lfromt[1]=1; 三角形1を構成する辺の一つは辺1。 lfromvとlfromtの意味は変数宣言のところのコメントから推測しましたが、間違っていても悪しからず。 では、first_t()のelse以下をどう書けばいいかというと、上記の推測が全て正しいなら、lt[]に1を代入してrt[]にはOUTSIDEを代入するように変えて他は全部同じでいいのではないでしょうか。頂点1→頂点2→頂点3→頂点1と回ったときに右回りになるか左回りになるかの違いだけでしょうから。 あと、配列の添字が1から始まっているのはC言語では気持ち悪いです。

atcrny374
質問者

お礼

返答ありがとうございます。助かります。 しかし正直、 > lscc[1]=3 ; lscw[1]=3 ; の所がまだ少しよくわからないです;;私もここはsalsberryさんと同じように考えたのですが、「なんで三角形なのにどちらも3とつながるの?」「片方は2じゃないの?」とか考えてしまっています。 添え字に関しては、気持ちは悪いですが、それを一点目と解釈した時、その方がいいと思ったので、そのままにしています。

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

質問番号5492814で指摘した ー leftside()の変数a1~c3の型はintなのにdoubleの値を代入している は放置されているみたいですね。 配列xやyの型がdoubleなのに、int型で計算してtdet()がまともな結果を返すとは思えません。

atcrny374
質問者

補足

すいません、直しておきます。質問した点については何か分かりませんか?

関連するQ&A

  • この先のプログラムの書き方

    以下のプログラムは、x座標の小さい順に整列された点(このプログラムは文字数の関係で省略)を結び、三角形で分割するプログラムです。 質問なんですが、プログラム冒頭の構造体Inを定義し、辺を表す構造体のメンバとして保持しています。そして辺構造体の配列でキューを構成して、辺から端点を参照し、正しく凸方の三角形分割に分割できるようにしようとしたのですが、それでは不十分らしく、その下に書いてあるように、「辺から隣の辺」「辺から三角形」「点から辺」も参照できなければいけません。(一応この定義だけはしました) この後どうすればよいでしょうか。文字数の関係でうまく説明できなくすみません。回答よろしくお願いします。 ------------------------------------- #include <stdio.h> #include <stdlib.h> typedef struct In{ int vs; /*始点のxyインデクス*/ int ve; /*終点のxyインデクス*/ } LINE_V; typedef struct In2{ int lscw; /*始点のclockwise line*/ int lecw; /*終点のclockwise line*/ int lscc; /*始点のcounter clockwise line*/ int lecc; /*終点のcounter clockwise line*/ } LINE_L; typedef struct In3{ int lt; /* left triangle */ int rt; /* right triangle */ } LINE_T; typedef struct In4{ int lt; /* any line from the vertex */ } VTX_L; double x[100],y[100]; int nxy; //頂点の数 LINE_V *sgln;//辺のキュー int msg=100; //キューの寸法 int nsg=0; //辺の数 void makepoints(int *nxy,double *x,double *y); LINE_V *enqueseg(int vs,int ve); int tdet(int a1, int b1, int c1, int a2, int b2, int c2, int a3, int b3, int c3){ int retvalp, retvaln; retvalp = a1*b2*c3+a2*b3*c1+a3*b1*c2; retvaln = a1*b3*c2+a2*b1*c3+a3*b2*c1; return retvalp-retvaln; } int leftside(int vertex1, int vertex2, int vertex3){ int a1, b1, c1, a2, b2, c2, a3, b3, c3; a1 = 1.0 ; b1 = x[vertex1]; c1 = y[vertex1]; a2 = 1.0 ; b2 = x[vertex2]; c2 = y[vertex2]; a3 = 1.0 ; b3 = x[vertex3]; c3 = y[vertex3]; return tdet(a1, b1, c1, a2, b2, c2, a3, b3, c3); } int main() {int v0=0,v1=1,v2=2; int vnxt; makepoints(&nxy, x, y); //辺のキューを初期確保 sgln=(LINE_V*)malloc(sizeof(LINE_V)*msg); /* 三角形の頂点の組を表示 */ printf("Triangle 1 : %d %d %d\n,v0,v1,v2 "); //辺をキューに登録 sgln[0].vs = v0; sgln[0].ve = v1; sgln[1].vs = v1; sgln[1].ve = v2; sgln[2].vs = v2; sgln[2].ve = v0; nsg = 3; /* 各頂点の処理 */ for(vnxt=3;vnxt<nxy;vnxt++){ double m,k; int side1,side2; /* 傾きが極端に大きくなったときに計算誤差が発生。これが起こらないよう、傾きが1を境に処理をxとyで入れ替える*/ side1=leftside(v1, v2, v0); side2=leftside(v1, v2, vnxt); /* 判別結果によって次の三角形の頂点を 選択 */ if(side1^side2) {v0=v1; /* 排他的論理和を使って判別。side1/side2のいずれか一方のみが非0のとき条件成立 */ } /* else節はなくても一緒なので略す else{ triangle[0]=triangle[0]; } */ v1=v2; v2=vnxt; /* 三角形の頂点の組を表示 */ printf("Triangle_%d_:_%d_%d_%d\n",vnxt-1,v0,v1,v2); //3辺を追加登録 sgln = enqueseg(v0,v1); sgln = enqueseg(v1,v2); sgln = enqueseg(v2,v0); } LINE_V *enqueseg(int vs,int ve){ int k; int hit; int va,vb; //キューの拡張:倍々サイズ if(nsg==msg){ msg *= 2; sgln=(LINE_V*)realloc(sgln,sizeof(LINE_V)*msg); if(sgln==NULL){ //エラーメッセージと、exit(0); } } //重複登録チェック for(k=0;k<nsg;k++){ va = sgln[k].vs; vb = sgln[k].ve; hit = (va==vs&&vb==ve)||(va==ve&&vb==vs); if(hit) break; } //重複なし:新規登録 if(k==nsg){ sgln[nsg].vs = vs; sgln[nsg].ve = ve; nsg++; } return sgln; }

  • ドロネー三角形分割のプログラムを作成中なのですが、参考プログラムが読めなく困っています。

    ドロネー三角形分割のプログラムを作成中なのですが、参考プログラムが読めなく困っています。 ソースコードは以下の様になります。 -------------------------------------------------- bool incircle(point a, point b, point c, point p) { a -= p; b -= p; c -= p; return norm(a) * cross(b, c) + norm(b) * cross(c, a) + norm(c) * cross(a, b) >= 0; // < : inside, = cocircular, > outside } #define SET_TRIANGLE(i, j, r) \ E[i].insert(j); em[i][j] = r; \ E[j].insert(r); em[j][r] = i; \ E[r].insert(i); em[r][i] = j; \ S.push(pair<int,int>(i, j)); #define REMOVE_EDGE(i, j) \ E[i].erase(j); em[i][j] = -1; \ E[j].erase(i); em[j][i] = -1; #define DECOMPOSE_ON(i,j,k,r) { \ int m = em[j][i]; REMOVE_EDGE(j,i); \ SET_TRIANGLE(i,m,r); SET_TRIANGLE(m,j,r); \ SET_TRIANGLE(j,k,r); SET_TRIANGLE(k,i,r); } #define DECOMPOSE_IN(i,j,k,r) { \ SET_TRIANGLE(i,j,r); SET_TRIANGLE(j,k,r); \ SET_TRIANGLE(k,i,r); } #define FLIP_EDGE(i,j) { \ int k = em[j][i]; REMOVE_EDGE(i,j); \ SET_TRIANGLE(i,k,r); SET_TRIANGLE(k,j,r); } #define IS_LEGAL(i, j) \ (em[i][j] < 0 || em[j][i] < 0 || \ !incircle(P[i],P[j],P[em[i][j]],P[em[j][i]])) double Delaunay(vector<point> P) { const int n = P.size(); P.push_back( point(-inf,-inf) ); P.push_back( point(+inf,-inf) ); P.push_back( point( 0 ,+inf) ); int em[n+3][n+3]; memset(em, -1, sizeof(em)); set<int> E[n+3]; stack< pair<int,int> > S; SET_TRIANGLE(n+0, n+1, n+2); for (int r = 0; r < n; ++r) { int i = n, j = n+1, k; while (1) { k = em[i][j]; if (ccw(P[i], P[em[i][j]], P[r]) == +1) j = k; else if (ccw(P[j], P[em[i][j]], P[r]) == -1) i = k; else break; } if (ccw(P[i], P[j], P[r]) != +1) { DECOMPOSE_ON(i,j,k,r); } else if (ccw(P[j], P[k], P[r]) != +1) { DECOMPOSE_ON(j,k,i,r); } else if (ccw(P[k], P[i], P[r]) != +1) { DECOMPOSE_ON(k,i,j,r); } else { DECOMPOSE_IN(i,j,k,r); } while (!S.empty()) { int u = S.top().first, v = S.top().second; S.pop(); if (!IS_LEGAL(u, v)) FLIP_EDGE(u, v); } } double minarg = 1e5; for (int a = 0; a < n; ++a) { for (set<int>::iterator itr = E[a].begin(); itr != E[a].end(); ++itr) { int b = *itr, c = em[a][b]; if (b < n && c < n) { point p = P[a] - P[b], q = P[c] - P[b]; minarg = min(minarg, acos(dot(p,q)/abs(p)/abs(q))); } } } return minarg; } -------------------------------------------------- http://www.prefield.com/algorithm/geometry/delaunay.htmlのサイト様のものなんですが、私自身c++プログラム初心者なので、わからず困っています。。概要でも結構ですのでどなたか回答してくださる方いらっしゃれば回答よろしくお願いします。

  • 二分法のプログラム

    関数x^3-7x^2-6x+2を二分法で解くプログラムを作ったのですが、エラーが出てコンパイルできません。訂正箇所を教えて下さい。 宜しくお願い致します。 #include<stdio.h> #include<math.h> #define EPSILON 0.1E-5 #define TURE 1 #define FALSE 0 int kansu(int x); void Nibunho(left,right,sol,flag); double left,right; int flag; int main(void) { printf("区間の左端と右端は?\n"); scanf("%lf %lf",&left,&right); flag=FALSE; Nibunho(left,right,&root,&flag); if(flag) printf("解 = %e (繰り返し回数 = %d)\n",root,k); else { printf("入力した範囲で解は求まりませんでした。\n"); printf("f(%e) = %e \n",root,k); } return 0; } int kansu(int x) { int f(double x) f(x)=x*x*x-7.0*x*x-6.0*x+2.0; return(f(x)); } void Nibunho(left,right,sol,flag) { double left,right,*sol; int *flag; double a,b,c,fa,fb,fc; k=0; a=left; b=right; do { k++; c=(a+b)/2.0; fc=f(c); fa=f(a); fb=f(b); if(fabs(fc)<1.0e-10) { a=c; b=c; *flag=TRUE; } else { if( (fa * fc < 0.0) || (fb * fc < 0.0) ) { *flag = TRUE; if( (fa*fc) < 0.0 ) b=c; else a=c; } else { if( fabs(fa) > fabs(fb) ) a=c; else b=c; } } } while((b-a)>EPSILON) *sol=(a+b)/2.0; }

  • Cで作ったプログラムについて

    (3,3)行列同士の掛け算についてのプログラムを組んでみましたが、 M_abの値がムチャクチャです。 #include<stdio.h> int main() { int M_a[3][3]; int M_b[3][3]; int M_ab[3][3]; int x; int line; int colm; for(line = 0; line < 3; line ++){ for(colm = 0; colm < 3; colm ++ ) { printf("M_a[%d][%d] >" ,line ,colm ); scanf("%d",&M_a[line][colm]); } } for(line = 0; line < 3; line ++){ for(colm = 0; colm < 3; colm ++){ printf("M_b[%d][%d] >",line,colm); scanf("%d",&M_b[line][colm]); } M_ab[line][colm] = 0; } for(x = 0; x < 3; x ++ ){ for(line = 0; line < 3; line ++){ for(colm = 0; colm < 3; colm ++){ M_ab[line][colm] += M_a[line][x] * M_b[x][colm] ; } } } for(line = 0; line < 3; line ++){ for(colm = 0; colm < 3; colm ++){ printf("M_A = %d\t",M_a[line][colm]); printf("M_B = %d\t",M_b[line][colm]); printf("M_AB = %d\n",M_ab[line][colm]); } } return(0); }

  • このプログラム見てほしいです!!

    #include <stdio.h> int gcd2(int a, int b) { if (!b) return a; return gcd2(b, a%b); } int main() { int a, b, c; printf("2つの任意の整数を入力せよ:"); scanf("%d %d",&a,&b); c=gcd2(a,b); printf("最小公倍数は%d\n",a*b/c); printf("最大公約数は%d\n",c); return 0; } で、最小公約数を出すことはできたのですが、全ての公約数を表示させたいんです!!どうやったらいいのでしょうか??プログラミングまだ初心者なので、ちょっと行き詰ってしまいました。。。 お時間があればでいいのですが、もう一つわからないプログラムがあります。 自然数nを入力し、x^2+y^2=z^2 (x<y)を満たすようなn以下の自然数の組(x,y,z)がいくつあるのかを出力するプログラムなのですが、全くわからず行き詰っています。。どなたかお時間があれば教えて頂きたいです。 色々と申し訳ありません。お願いします(__)

  • VC2010の開発

    VC++(2010)でプログラミングを行っています。 #define A1 (String型) #define A2 (Int32型) #define A3 (Int32型) #define B1 (String型) #define B2 (Double型) #define B3 (Double型) #define C1 (String型) #define C2 (Double型) #define C3 (Double型) 上記のようなA、B、C(型が異なる)をリストで管理したいです。 イメージとしては XX list = {{A1, A2, A3}, {B1, B2, B3},{C1, C2, C3}} です。 テンプレートクラスで実装できますか? また、別な方法があれば教えてください。

  • プログラム

    アドバイスをもとにいろんなサイトを見てみたんですが、なんとなくはわかるんですがこれから先どうしたら良いかわかりません。a,bを入力する画面まではいくんですが、それから先の結果がでないんです。何がいけないんですか? #include <stdio.h> double func(double x){ double y; y=x*x*x-3*x*x+9*x-8; return(y); } int main(){ double EPS=0.00005; double a, b, c; char t; int i=0; do{ printf(" a = "); scanf("%lf%c", &a, &t); printf(" b = "); scanf("%lf%c", &b, &t); if(func(a)*func(b) >= 0){ printf(" f(a)*f(b)>0\n\n"); } }while(func(a)*func(b) >= 0); if(b-a<0){ c=a; a=b; b=c; } while(b-a>EPS){ c=a-((b-a)/(func(b)-func(b)))*func(a); if(func(c)*func(a)<0){ b=c; }else{ a=c; } i++; printf(" %d\t%20.15f\n",i,c); }

  • processingのカーソルと画像の距離

    processingでクリスマスカードを作るのですが、どうしてもカーソルと雪だるまの距離があいてしまいます。この距離をあけないようにするにはどうしたらいいでしょうか?わかる方がいらっしゃいましたらどうぞよろしくお願いします。 void setup() { size(600,600); smooth(); noStroke(); } int flag = 0; void draw() { background(10,50,100); fill(0); rect(0,450,600,280); int x=50,y=30; fill(#006e54); triangle(300,50,400,200,200,200); triangle(300,50+x,420,280,180,280); triangle(300,50+2*x,420+y,280+2*x,180-y,280+2*x); fill(190,103,31); rect(275,280+2*x,50,150); textSize(45); fill(255,0,0); text("Merry X'mas!",170,580); fill(random(255),random(255),random(255)); translate(249,5); beginShape(); vertex(50 , 50 - 20); vertex(50 - 12 , 50 + 15); vertex(50 + 18 , 50 - 8); vertex(50 - 18 , 50 - 8); vertex(50 + 12 , 50 + 15); endShape(CLOSE); fill(random(255),random(255),random(255)); ellipse(20,90,30,30); fill(random(255),random(255),random(255)); ellipse(100,130,30,30); fill(random(255),random(255),random(255)); ellipse(10,170,30,30); fill(random(255),random(255),random(255)); ellipse(55,220,30,30); fill(random(255),random(255),random(255)); ellipse(130,250,30,30); fill(random(255),random(255),random(255)); ellipse(90,350,30,30); fill(random(255),random(255),random(255)); ellipse(30,300,30,30); fill(random(255),random(255),random(255)); ellipse(10,360,30,30); fill(random(255),random(255),random(255)); ellipse(160,320,30,30); fill(random(255),random(255),random(255)); ellipse(-40,330,30,30); if(mousePressed) { flag=1; } else { flag=0; } if(flag==1) { snowman(); } else { textSize(20); fill(255); text("Please press mouse to create a snowman!",-150,20); } } void snowman() { int speed=2; int x=mouseX; int y=mouseY; x+=random(-speed,speed);//let snowman move randomly // x=constrain(x,0,500); y+=random(-speed,speed); y=constrain(y,0,600); fill(255); //make a little snowman ellipse(x,y-50,50,50); ellipse(x,y,100,100); fill(0); ellipse(x-10,y-55,10,10); ellipse(x+10,y-55,10,10); fill(#ff0000); triangle(x-10,y-50,x+10,y-50,x,y-30); }

  • C言語で直角三角形の斜辺を求めるプログラムについて

    「二辺の長さが与えられているとき、斜辺の長さを求めよ」という問題です。 #include <stdio.h> #include <math.h> #define a 3 #define b 4 int main (void) { double c=0; c=sqrt(a*a+b*b); printf("%f",c); return 0; } visual2010c++で作ったんですが、sqrtに下線がついて、コンパイルエラーしちゃいます。 すんごい初歩的なことなんだと思いますが、どこなのか気づけません。 どなたかよろしくお願いします。

  • プログラムの最適化について質問です。

    プログラムの最適化について質問です。 /* 課題7 */ #include<stdio.h> #define A n /* n=10^0~9 */ void main() { int a,x; for(a=0;a<A;a++){ x=x+1; } } /* 課題8 */ #include<stdio.h> #define A n /* n=10^0~9 */ void main() { int a,x; for(a=0;a<A;a++){ x++; } } 課題7に比べて課題8の記述のメリットとして、単にソースコードを短くできる以外に、何が考えられるか。 という質問に対しての答えが分かりません。解説お願いします。

専門家に質問してみよう