00001 #include <stdlib.h> 00002 #include <stdio.h> 00003 #include <math.h> 00004 00005 typedef struct { 00006 double a, b, c, d, e, f; 00007 } poly6_t; 00008 00009 #define POLY(p, x) (p.a + (x)*(p.b + (x)*(p.c + (x)*(p.d + (x)*(p.e + (x)*p.f))))) 00010 #define POLY1(p, x) (p.b + (x)*(2.*p.c + (x)*(3.*p.d + (x)*(4.*p.e + (x)*5.*p.f)))) 00011 #define POLY2(p, x) (2.*p.c + (x)*(6.*p.d + (x)*(12.*p.e + (x)*20.*p.f))) 00012 00013 00014 #define GAUSSTOL 1.e-10 00015 00016 static int gauss(double A[6][6], double B[6], double C[6]) 00017 { 00018 int i, j, k, i1, n = 6; 00019 double max, temp; 00020 00021 for (j = 0; j <= n - 2; j++) { 00022 i1 = j; 00023 max = fabs(A[j][j]); 00024 for (i = j + 1; i < n; i++) { 00025 if (fabs(A[i][j]) >= max) { 00026 i1 = i; 00027 max = fabs(A[i][j]); 00028 } 00029 } 00030 for (k = j; k < n; k++) { 00031 max = A[j][k]; A[j][k] = A[i1][k]; A[i1][k] = max; 00032 } 00033 max = B[j]; B[j] = B[i1]; B[i1] = max; 00034 for (i = j + 1; i < n; i++) { 00035 if (fabs(A[j][j]) < GAUSSTOL) 00036 return 1; 00037 else 00038 temp = A[i][j] / A[j][j]; 00039 for (k = j; k < n; k++) 00040 A[i][k] -= temp * A[j][k]; 00041 B[i] -= temp * B[j]; 00042 } 00043 } 00044 00045 if (fabs(A[n-1][n-1]) < GAUSSTOL) 00046 return 1; 00047 C[n - 1] = B[n - 1] / A[n - 1][n - 1]; 00048 for (i = n - 2; i >= 0; i--) { 00049 C[i] = B[i]; 00050 for (k = i + 1; k < n; k++) 00051 C[i] -= A[i][k] * C[k]; 00052 if (fabs(A[i][i]) < GAUSSTOL) 00053 return 1; 00054 C[i] /= A[i][i]; 00055 } 00056 return 0; 00057 } 00058 00059 00060 void polycircle(double x1, double y1, double dy1, double ddy1, 00061 double x2, double y2, double dy2, double ddy2, 00062 poly6_t * poly) 00063 { 00064 double A[6][6], B[6], C[6]; 00065 B[0] = y1; 00066 A[0][0] = 1.0; A[0][1] = x1; A[0][2] = x1*x1; A[0][3] = x1*x1*x1; 00067 A[0][4] = x1*x1*x1*x1; A[0][5] = x1*x1*x1*x1*x1; 00068 00069 B[1] = dy1; 00070 A[1][0] = 0.0; A[1][1] = 1.0; A[1][2] = 2.*x1; A[1][3] = 3.*x1*x1; 00071 A[1][4] = 4.*x1*x1*x1; A[1][5] = 5.*x1*x1*x1*x1; 00072 00073 B[2] = ddy1; 00074 A[2][0] = 0.0; A[2][1] = 0.0; A[2][2] = 2.; A[2][3] = 6.*x1; 00075 A[2][4] = 12.*x1*x1; A[2][5] = 20.*x1*x1*x1; 00076 00077 B[3] = y2; 00078 A[3][0] = 1.0; A[3][1] = x2; A[3][2] = x2*x2; A[3][3] = x2*x2*x2; 00079 A[3][4] = x2*x2*x2*x2; A[3][5] = x2*x2*x2*x2*x2; 00080 00081 B[4] = dy2; 00082 A[4][0] = 0.0; A[4][1] = 1.0; A[4][2] = 2.*x2; A[4][3] = 3.*x2*x2; 00083 A[4][4] = 4.*x2*x2*x2; A[4][5] = 5.*x2*x2*x2*x2; 00084 00085 B[5] = ddy2; 00086 A[5][0] = 0.0; A[5][1] = 0.0; A[5][2] = 2.; A[5][3] = 6.*x2; 00087 A[5][4] = 12.*x2*x2; A[5][5] = 20.*x2*x2*x2; 00088 00089 if (gauss(A, B, C)) { 00090 fprintf(stderr, "gauss: no solution\n"); 00091 exit(1); 00092 } 00093 poly->a = C[0]; poly->b = C[1]; poly->c = C[2]; poly->d = C[3]; 00094 poly->e = C[4]; poly->f = C[5]; 00095 } 00096 00097 00098 00099 int main(int argc, char * argv[]) 00100 { 00101 int i, n = 200, n1; 00102 double radius = atof(argv[1]); 00103 double height = atof(argv[2]); 00104 double width = atof(argv[3]); 00105 double theta = height/radius, t, x; 00106 double xc1 = radius + width/2. + 0.5, xc2 = -radius - width/2. + 0.5; 00107 poly6_t poly; 00108 00109 for (i = 0; i < n; i++) { 00110 t = (double)i/(double)(n - 1)*(PI - theta); 00111 printf("%g %g\n", xc1 + radius*cos(t), radius*sin(t)); 00112 } 00113 polycircle(xc1 + radius*cos(PI - theta), 00114 radius*sin(PI - theta), 00115 1./tan(theta), 00116 -20./radius, 00117 xc2 + radius*cos(theta), 00118 radius*sin(theta), 00119 -1./tan(theta), 00120 -20./radius, 00121 &poly); 00122 n1 = 50; 00123 for (i = 1; i < n1 - 1; i++) { 00124 x = xc1 + radius*cos(PI - theta) + (double)i/(double)(n1 - 1)* 00125 (xc2 - xc1 + 2.*radius*cos(theta)); 00126 printf("%g %g\n", x, POLY(poly, x)); 00127 } 00128 for (i = 0; i < n; i++) { 00129 t = theta + (double)i/(double)(n - 1)*(PI - theta); 00130 printf("%g %g\n", xc2 + radius*cos(t), radius*sin(t)); 00131 } 00132 return 0; 00133 } 00134 00135