dポイントプレゼントキャンペーン実施中!

こんにちは。
次の問題がわかりません(>_<)
【グラッフィックスのダイヤモンドパターンを回転させる】問題です。
 平面図形(正八角形、正十二角形とか)がくるくる回るようにしたいのですが、図形が崩れた感じで奇妙な(?)回転になります。一応、プログラムは書いてみましたが、どこが間違っているのかわかりません。
 下に自分で考えたプログラムの流れとソースを記しておきました。わかる方ご回答願います。

※ 実行結果は無限に設定してあるので、Ctrl+C でプログラムを強制的に終わらせることとします。

【プログラムの流れ】
(1) 座標を計算(半径1のもの)
(2) ダイヤモンドパターンを書く
(3) 座標を回転
(4) ちょっと待つ
(5) 画面を消去する→(2)に戻る



【プログラム】
-----------------------------------------------------------
/* ダイヤモンドパターンを回転させる*/
#include<stdio.h>
#include<math.h>
#include <gucc/gucc.h>

#definePAI3.141593

void main( void )
{
inti, j, np, k, t1,c,t2,rad,u,v;
doublex[100], y[100], z[100];
int R[5]={0,64,128,192,255};
int G[5]={0,64,128,192,255};
int B[5]={0,64,128,192,255};
doublers, ang;

rs = 150.0;/*円の半径*/
printf("頂点数? ");
scanf( "%d",&np );/*npは頂点数*/
for( i=0; i<np; i++ ){
ang = 2.0 * PAI * (i-1) /np ;/*PAIはπ*/

/*半径1の円周上の点*/
x[i] = cos(ang);
y[i] = sin(ang);

}

G_INIT();/*グラフィックモードの切り替えと初期化*/
G_CLS();


do{
/*図形を描く*/
for( i=0; i<np-1; i++ ){
for( j=i+1; j<np; j++ ){
G_LINE( rs*x[i]+ 300.0, rs*y[i]+ 240.0, rs*x[j]+ 300.0 , rs*y[j]+ 240.0 );
}
}

/*座標を回転 */
for( i=0; i<np-1; i++ ){
rad=rad+0.05;
z[i] = x[i] * cos(0.05) + y[i] * sin(0.05);
y[i] = -x[i] * sin(0.05) + y[i] * cos(0.05);
x[i]=z[i];
}



/*ちょっと待つ*/
t1=time(&t2);
while(t1==time(&t2));

/*画面を消去*/
G_CLS();
}while(1);
}
----------------------------------------------------------------

A 回答 (3件)

もう1つ。



for( i=0; i<np-1; i++ ){
G_LINE( rs*(y[i] * cos(rad) - x[i] * sin(rad))+ 300.0, rs*(x[i] * cos(rad) + y[i] * sin(rad))+ 240.0, rs*(y[i+1] * cos(rad) - x[i+1] * sin(rad))+ 300.0 , rs*(x[i+1] * cos(rad) + y[i+1] * sin(rad))+ 240.0 );
}
の後に
G_LINE( rs*(y[0] * cos(rad) - x[0] * sin(rad))+ 300.0, rs*(x[0] * cos(rad) + y[0] * sin(rad))+ 240.0, rs*(y[np-1] * cos(rad) - x[np-1] * sin(rad))+ 300.0 , rs*(x[np-1] * cos(rad) + y[np-1] * sin(rad))+ 240.0 );
を追加。

ループで
[0]から[1]に線を引く
[1]から[2]に線を引く
[2]から[3]に線を引く
[3]から[4]に線を引く
(中略)
[np-2]から[np-1]に線を引く
までを繰り返した後で、最後に
[0]から[np-1]に線を引く
としないと、多角形が閉じません。
    • good
    • 0
この回答へのお礼

お礼が遅くなってすみません。アドバイスありがとうございました!!とても参考になりました。
プログラムは無事に完成し、多角形がきれいにくるくる回っています(^^)

お礼日時:2008/12/19 10:53

追記。



{と}の対応を修正し忘れたので、余計な}、足りない}は、質問者さんが適切に修正して下さい。
    • good
    • 0

回転させる度に、x[]とy[]の中身を書き替えると、誤差が蓄積され、すぐに図形が歪んでしまう。



多角形の座標をx[]とy[]に作成したら、それ以降、x[]とy[]の中身は変更しないようにした方が良い。

#include <stdio.h>
#include <math.h>
#include <time.h> /* time関数を使用するにはtime.hが必要 */
#include <gucc/gucc.h>

/* doubleを使用するなら、最低、15桁は書くこと */
#define PAI 3.141592653589793

void main( void )
{
int i, j, np, k, c, kakudo,u,v;
double x[100], y[100], z[100];
int R[5]={0,64,128,192,255};
int G[5]={0,64,128,192,255};
int B[5]={0,64,128,192,255};
double rs, ang, rad;
time_t t1;
/* time()の引数はtime_t *である。int *である保証はない
通常、
typedef unsigned long time_t;
と定義されている
sizeof(int)とsizeof(unsigned long)が異なる場合
time(&int_val)の呼び出しはメモリを破壊する */

rs = 150.0;/*円の半径*/
printf("頂点数? ");
scanf( "%d",&np );/*npは頂点数*/
for( i=0; i<np; i++ ){
ang = 2.0 * PAI * i /np ;/*PAIはπ*/

/*半径1の円周上の点*/
x[i] = cos(ang);
y[i] = sin(ang);

}

G_INIT();/*グラフィックモードの切り替えと初期化*/
G_CLS();

kakudo = 0;

for (;;) { /* 無限ループは「do ~ while(1);」よりも「for (;;) {~}」の方が好ましい */

rad = (double)kakudo * PAI / 180.0; /* 角度からラジアン値を求める */

/*図形を描く*/
for( i=0; i<np-1; i++ ){
G_LINE( rs*(y[i] * cos(rad) - x[i] * sin(rad))+ 300.0, rs*(x[i] * cos(rad) + y[i] * sin(rad))+ 240.0, rs*(y[i+1] * cos(rad) - x[i+1] * sin(rad))+ 300.0 , rs*(x[i+1] * cos(rad) + y[i+1] * sin(rad))+ 240.0 );
}
}

/* 角度を変更 */
kakudo += 5;
kakudo %= 360; /* kakudoが大きくなるとsin、cosの誤差が大きくなるので、kakudoは常に0~359度の間に収める */
/* ラジアン値のradを操作して「1周したら0度に戻す」のは、誤差の問題があるので、好ましくない */

/*ちょっと待つ*/
/* 戻り値をt1に代入するなら、引数はNULLで良い
引数を指定するならtime(&t1);で良く、戻り値は不要 */
t1=time(NULL);

/* 戻り値をt1と比較するなら、引数はNULLで良い */
while(t1==time(NULL)) {;}
/* 「ループ内で何もしない場合」は「;」のみで済まさず「{;}」の
ように「何もしないのを明示的に記述する」こと。
「;」のみでは「do {~} while(条件);」の場合の
「while(条件);」と紛らわしい。
ここは
for (t1=time(NULL);t1==time(NULL);) {;}
とも書けるが、代入と比較で似た式が並び、紛らわしいので好ましくない */

/*画面を消去*/
G_CLS();
}
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!