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