『Cプログラミング診断室』目次次(第4章 キャストが好き おわりに)

第4章 キャストが好き

いつもの問題


その他にも当然問題があるのですが、誰もが犯す類の過ちなので、個条書きだけして終りにしま す。リスト4−1に示していない部分に関することも書いておきます。

(a) 意味を示さない関数名、変数名の使用。

(b) コメントがない。

(c) 配列の添字を0から使っていない。

(d) 下手な関数をわざわざ作らなくても、ちゃんと標準関数が用意されているので、 そちらを使いなさい。

(e) プログラム全体にばらまかれた定数値。できるだけ定数はマクロで定義しなさい。

(f) 配列のサイズを適当に、多分これだけあれば十分だろうという大きさにしている。 小さい配列のときは、ちゃんと最大サイズを調べ、 大きなときは、mallocなどで動的に領域を確保すべき。

(g) switch文のcaseが非常に多数あり、caseの後の定数式が直接、1とか2という様に 数値で書かれていて、どんな場合か不明。 定数値はマクロにするか、せめてコメントくらいは欲しい。

(h) ポインタを理解していない。
リスト4−3 修正版

     1	/*****************************************************************************/
     2	/*                      ハッチング処理                                       */
     3	/*                                              by BASIC Programmer          */
     4	/*                                                                           */
     5	/*      変更  1991/07/31  fuji    大幅に変更いたしました。                   */
     6	/*****************************************************************************/
     7	#include <stdio.h>
     8	#include <math.h>
     9	
    10	#define MAXSIZE 100
    11	
    12	typedef struct  {
    13	        long    x, y, z;
    14	} point3 ;
    15	
    16	typedef struct  {
    17	        double  x, y, z;
    18	} point3d ;
    19	
    20	typedef double matrix3[3][3];
    21	
    22	typedef struct {
    23	        point3  origin;                 /* 基準点         */
    24	        point3  direction;              /* 方向         */
    25	        int     n;                      /* データ数     */
    26	        point3  positions[MAXSIZE];     /* 座標         */
    27	} hatching;
    28	
    29	typedef struct {
    30	        double   cost, sint, costh[4], sinth[4];
    31	} elements;
    32	
    33	/*----------       static関数プロトタイプ宣言      ----------*/
    34	
    35	static void   get_cos_sin(double x1, double y1, double x2, double y2,
    36	                          double *costh, double *sinth);
    37	static void   convert1(hatching *hin, elements *hw);
    38	static double takasa(long gpx[], long gpy[], long gpz[], double x0, double y0);
    39	
    40	#define f_swap(a,b)     { double tmp=a; a=b; b=tmp }
    41	#define sgn(a)          ((a)==0.0 ? 0.0 : (a)<0.0 ? -1.0 : 1.0)
    42	
    43	/*---------------------------------------------------------------------------*/
    44	/*      回転角度の cos, sin を求める                                         */
    45	/*---------------------------------------------------------------------------*/
    46	static void get_cos_sin(double x1, double y1, double x2, double y2,
    47	                         double *costh, double *sinth)
    48	{
    49	        double  d, w1, w2;
    50	
    51	        d = hypot( w1 = x2 - x1, w2 = y2 - y1 );
    52	        if (1.0 > d) {
    53	                *costh = 1.0;
    54	                *sinth = 0.0;
    55	        } else {
    56	                *costh = w1 / d;
    57	                *sinth = w2 / d;
    58	        }
    59	}
    60	
    61	/*---------------------------------------------------------------------------*/
    62	/*      行列=行列                                                           */
    63	/*---------------------------------------------------------------------------*/
    64	static  void    matcpy( matrix3 out, matrix3 in )
    65	{
    66	        int     i, j;
    67	
    68	        for( i=0 ; i<3 ; ++i )
    69	                for( j=0 ; j<3 ; ++j )
    70	                        out[i][j] = in[i][j];
    71	}
    72	
    73	/*---------------------------------------------------------------------------*/
    74	/*      行列=行列・行列                                                     */
    75	/*---------------------------------------------------------------------------*/
    76	static  void    matmul( matrix3 out, matrix3 m1, matrix3 m2 )
    77	{
    78	        int     i, j, k;
    79	        matrix3 m;
    80	        double  s;
    81	
    82	        for( i=0 ; i<3 ; ++i )
    83	                for( j=0 ; j<3 ; ++j ) {
    84	                        s = 0;
    85	                        for( k=0 ; k<3 ; ++k )
    86	                                s += m1[i][k] * m2[k][j];
    87	                        m[i][j] = s;
    88	                }
    89	
    90	        matcpy( out, m );
    91	}
    92	
    93	/*---------------------------------------------------------------------------*/
    94	/*      実数ベクトル=行列・実数ベクトル                                     */
    95	/*---------------------------------------------------------------------------*/
    96	vecmat( point3d *outp, matrix3 mat, point3d *inp)
    97	{
    98	        point3d wk;
    99	
   100	        wk.x = mat[0][0]*inp->x + mat[0][1]*inp->y + mat[0][2]*inp->z;
   101	        wk.y = mat[1][0]*inp->x + mat[1][1]*inp->y + mat[1][2]*inp->z;
   102	        wk.z = mat[2][0]*inp->x + mat[2][1]*inp->y + mat[2][2]*inp->z;
   103	
   104	        *outp = wk;
   105	}
   106	
   107	/*---------------------------------------------------------------------------*/
   108	/*      整数ベクトル=行列・整数ベクトル                                     */
   109	/*---------------------------------------------------------------------------*/
   110	vecmat_i( point3 *outp, matrix3 mat, point3 *inp)
   111	{
   112	        point3  wk;
   113	
   114	        wk.x = mat[0][0]*inp->x + mat[0][1]*inp->y + mat[0][2]*inp->z;
   115	        wk.y = mat[1][0]*inp->x + mat[1][1]*inp->y + mat[1][2]*inp->z;
   116	        wk.z = mat[2][0]*inp->x + mat[2][1]*inp->y + mat[2][2]*inp->z;
   117	
   118	        *outp = wk;
   119	}
   120	
   121	/*---------------------------------------------------------------------------*/
   122	/*                             convert1                                      */
   123	/*---------------------------------------------------------------------------*/
   124	/*      fuji : 作成者の本当の「意図」が分からないので、無理矢理同じ動作する  */
   125	/*           ようにしました。本当は、もっと、はるかにすっきりなるでしょう。  */
   126	/*---------------------------------------------------------------------------*/
   127	static void     convert1(hatching *hin, elements *hw)
   128	{
   129	        matrix3  rot, r;
   130	        static  matrix3 unitmat = { {1,0,0}, {0,1,0}, {0,0,1} };
   131	        point3d  pos[3];
   132	        int      i, td;
   133	        double   sinth, costh;
   134	        point3  *p;
   135	
   136	        /* 先頭3点の座標値をdoubleで取り出す */
   137	        for( i=0 ; i<3 ; ++i ) {
   138	                pos[i].x = hin->positions[i].x;
   139	                pos[i].y = hin->positions[i].y;
   140	                pos[i].z = hin->positions[i].z;
   141	        }
   142	
   143	        /* z軸まわりの回転を行なう */
   144	        td = 0;
   145	        get_cos_sin( pos[0].x, pos[0].y, pos[1].x, pos[1].y, &costh, &sinth );
   146	        matcpy( rot, unitmat );
   147	        rot[0][0] =   rot[1][1] = hw->costh[td] = costh ;
   148	        rot[1][0] = -(rot[0][1] = hw->sinth[td] = sinth);
   149	        for( i=0 ; i<3 ; ++i )
   150	                vecmat( &pos[i], rot, &pos[i] );
   151	
   152	        /* y軸まわりの回転を行なう */
   153	        td = 1;
   154	        get_cos_sin( pos[0].x, pos[0].z, pos[1].x, pos[1].z, &costh, &sinth );
   155	        matcpy( r, unitmat );
   156	        r[0][0] =   r[2][2] = hw->costh[td] = costh ;
   157	        r[2][0] = -(r[0][2] = hw->sinth[td] = sinth);
   158	        for( i=0 ; i<3 ; ++i )
   159	                vecmat( &pos[i], r, &pos[i] );
   160	        matmul( rot, r, rot );
   161	
   162	        /* x軸まわりの回転を行なう */
   163	        td = 2;
   164	        get_cos_sin( pos[1].y, pos[1].z, pos[2].y, pos[2].z, &costh, &sinth );
   165	        matcpy( r, unitmat );
   166	        r[1][1] =   r[2][2] = hw->costh[td] = costh ;
   167	        r[2][1] = -(r[1][2] = hw->sinth[td] = sinth);
   168	        matmul( rot, r, rot );
   169	
   170	        /* 求まった回転行列を、回転すべき全対象に適用する */
   171	        p = &hin->positions[0];
   172	        for (i = 0; i < hin->n; i++, ++p )
   173	                vecmat_i( p, rot, p );
   174	        vecmat_i( &hin->origin,    rot, &hin->origin    );
   175	        vecmat_i( &hin->direction, rot, &hin->direction );
   176	}
   177	
   178	/*---------------------------------------------------------------------------*/
   179	/*                              高さ                                         */
   180	/*---------------------------------------------------------------------------*/
   181	/*      fuji : 内容が良く分からないので、最低限だけ直しています。ごめんね。  */
   182	/*---------------------------------------------------------------------------*/
   183	static double takasa(long gpx[], long gpy[], long gpz[], double x0, double y0)
   184	{
   185	        int     tr, i1, i2, k, j, i;
   186	        double  iy1, iy2, dd, d1, sinr, z, gcost, gsint,
   187	                xd, yd, kx1, kx2, kz1, kz2, gminx;
   188	        double   xdd[3], ydd[3], zdd[3], ixd[3], iyd[3], izd[3];
   189	        double  d;
   190	
   191	        iy1 =  10000.0;
   192	        iy2 = -10000.0;
   193	        for( tr=0;  ; ++tr ) {
   194	                i1 = tr;
   195	                i2 = (tr+1) % 3;
   196	                d = hypot((double)(gpx[i1]-gpy[i1]), (double)(gpx[i2]-gpy[i2]));
   197	                if( 1.0 <= d ) {
   198	                        gcost = (gpx[i2] - gpx[i1]) / d;
   199	                        gsint = (gpy[i2] - gpy[i1]) / d;
   200	                        gminx = 99999.0;
   201	                        for (j = 0; j < 3; j++ ) {
   202	                            k = (tr + j) % 3;
   203	                            xdd[j] =  gcost * gpx[k] + gsint * gpy[k];
   204	                            ydd[j] = -gsint * gpx[k] + gcost * gpy[k];
   205	                            zdd[j] = (double)gpz[k];
   206	                            if(xdd[j] < gminx)
   207	                                gminx = xdd[j];
   208	                        }
   209	                }
   210	                xd =  gcost * x0 + gsint * y0;
   211	                yd = -gsint * x0 + gcost * y0;
   212	                if( (int)gminx == (int)xd )
   213	                        continue;
   214	                d1 = (iy1 - iy2);
   215	                sinr = (iy2 - iy1) / d1;
   216	                for (i = 0; i < 3; i++) {
   217	                        ixd[i] =  ((zdd[i] - iy1) / d1) * sinr;
   218	                        iyd[i] = -((xdd[i] - xd ) / d1) * sinr;
   219	                        izd[i] = ydd[i] - yd;
   220	                }
   221	                if( iyd[1]==iyd[0] || iyd[2]==iyd[0] )
   222	                        continue;
   223	
   224	                kx1 = ixd[0] - (ixd[1]-ixd[0]) / (iyd[1]-iyd[0]) * iyd[0];
   225	                kz1 = izd[0] - (izd[1]-izd[0]) / (iyd[1]-iyd[0]) * iyd[0];
   226	                kx2 = ixd[0] - (ixd[2]-ixd[0]) / (iyd[2]-iyd[0]) * iyd[0];
   227	                kz2 = izd[0] - (izd[2]-izd[0]) / (iyd[2]-iyd[0]) * iyd[0];
   228	                if (kz2 == kz1 )
   229	                        continue;
   230	                dd = kx1 - (kx2 - kx1) / (kz2 - kz1) * kz1;
   231	                z = dd * d1 * sinr + iy1;
   232	                return(z);
   233	        }
   234	}
   235	
   236	/*---------------------------------------------------------------------------*/
   237	/*              途中までです。ごめんなさーい。  by fuji                      */
   238	/*---------------------------------------------------------------------------*/


Copyright1996 Hirofumi Fujiwara. No reproduction or republication without written permission
『Cプログラミング診断室』目次次(第4章 キャストが好き おわりに)