给出到不共线三点的距离,求这个点的坐标(公式是用 maple 求的):
# include <stdio.h> # include <string.h> # include <math.h> # define TRUE 1 # define FALSE 0 const double ERR = 0.05; typedef char BOOL; typedef struct { double x; double y; }Point; Point s1, s2, s3; /* station */ double d1, d2, d3; /* distance */ BOOL read(void); void solve(void); void print_msg(void); double dist(Point x, Point y); char test_eps(double x, double y); int isNegtive(double *var); void compute(Point p1, Point p2, double dt1, double dt2, Point *q1, Point *q2); int main() { freopen("in.txt", "r", stdin); freopen("out.txt", "w", stdout); print_msg(); while (read() == TRUE) { solve(); } return 0; } void print_msg(void) { puts("输入三个基站坐标以及客户端到三个基站的距离,输出客户端的坐标。"); } BOOL read(void) { if (scanf("%lf%lf%lf%lf%lf%lf%lf%lf%lf", &s1.x, &s1.y, &s2.x, &s2.y, &s3.x, &s3.y, &d1, &d2, &d3) == EOF) { /*printf("%lf %lf %lf %lf %lf %lf %lf %lf %lf\n", s1.x, s1.y, s2.x, s2.y, s3.x, s3.y, d1, d2, d3);*/ return FALSE; } return TRUE; } double dist(Point a, Point b) { return sqrt(pow(a.x-b.x, 2.0) + pow(a.y-b.y, 2.0) + 1e-6); } int isNegtive(double *var) /* 判断一个 double 类型数是否为负、为零 */ { if ((*var)+1e-6 < 0) { puts("data Error!"); return -1; } else if (-1e-6<(*var) && (*var)<1e-6) { (*var) = 0; return 0; } return 1; } void compute(Point p1, Point p2, double dt1, double dt2, Point *q1, Point *q2) { double r, R, h, k, delta; double r2, r4; double R2, R4; double k2, k4; double h2, h4; double xDen, yDen; double tmp; R = dt1; r = dt2; h = p2.x - p1.x; k = p2.y - p1.y; r2 = r * r; R2 = R * R; k2 = k * k; h2 = h * h; r4 = r2 * r2; R4 = R2 * R2; h4 = h2 * h2; k4 = k2 * k2; tmp = -1.0*h2*R4 - 2.0*h4*k2 - h2*k4 + 2.0*h4*R2 + 2.0*h4*r2 - h2*r4 + 2.0*k2*r2*h2 + 2.0*h2*k2*R2 + 2.0*h2*r2*R2 - h2*h4; switch(isNegtive(&tmp)) { case -1 : return; case 0 : delta = 0; break; case 1 : delta = sqrt(tmp + 1e-6); break; } yDen = 2.0 * (h2 + k2); xDen = h * yDen; if (-1e-6<yDen && yDen<1e-6) { /* 两个基站的纵坐标相同 */ if ( isNegtive(&h) == 0) return ; (*q1).x = (*q2).x = (R2-r2+h2)/(2.0*h); tmp = R2 - pow((*q1).x, 2.0); if ( isNegtive(&tmp) == -1 ) return ; (*q1).y = 1.0*sqrt(tmp); (*q2).y = -1.0*sqrt(tmp); } else if (-1e-6<h && h<1e-6) { /* 两个基站的横坐标相同 */ if ( isNegtive(&k) == 0) return ; (*q1).y = (*q2).y = (R2-r2+k2)/(2.0*k); tmp = R2 - pow((*q1).y, 2.0); if ( isNegtive(&tmp) == -1 ) return ; (*q1).x = 1.0*sqrt(tmp); (*q2).x = -1.0*sqrt(tmp); } else { /* 两个基站的横纵坐标都不相同 */ tmp = -1.0*h4 - h2*k2 + h2*r2 - h2*R2; (*q1).x = ( -1.0*tmp - k*delta ) / xDen; (*q2).x = ( -1.0*tmp + k*delta ) / xDen;; tmp = -1.0*k*r2 + h2*k + k*k2 + k*R2; (*q1).y = ( 1.0*tmp + delta ) / yDen; (*q2).y = ( 1.0*tmp - delta ) / yDen; } (*q1).x += p1.x; (*q1).y += p1.y; (*q2).x += p1.x; (*q2).y += p1.y; } char test_eps(double x, double y) { if (2.0*abs(x-y)/(x+y) < ERR+1e-6) return 1; return 0; } void solve(void) { Point t1, t2; compute(s1, s2, d1, d2, &t1, &t2); /* printf("(%.3lf, %.3lf)\n", t1.x, t1.y); printf("(%.3lf, %.3lf)\n", t2.x, t2.y); */ if (test_eps(dist(t1, s3), d3)) { printf("客户端坐标a:"); printf("(%.3lf, %.3lf)\n", t1.x, t1.y); } else if (test_eps(dist(t2, s3), d3)) { printf("客户端坐标b:"); printf("(%.3lf, %.3lf)\n", t2.x, t2.y); } else { puts("数据有误"); } }
随机生成不共线三点的坐标(浮点数)和一个点:
/* 随机生成数据 */ # include <stdio.h> # include <math.h> # include <time.h> # define N 100 /* 随机生成 N 组数据 */ # define MOD 31723 /* 素数 */ typedef struct { double x; double y; }Point; Point s1, s2, s3, c; /* station */ double d1, d2, d3; /* distance */ double dist(Point a, Point b); int rand_sgn(void) /* 随机生成符号 */ { return (rand()&0x1) ? 1:-1; } double rand_double(void) { int den; while ((den=rand()%MOD) == 0) ; return rand_sgn()*(rand()%MOD)*1000.0/den; } void rand_Point(Point *p) { (*p).x = rand_double(); (*p).y = rand_double(); } char is_equal(Point p, Point q) { if (1e-6<p.x-q.x && p.x-q.x<1e-6 && 1e-6<p.y-q.y && p.y-q.y<1e-6) { return 1; } else return 0; } char is_inline(Point p1, Point p2, Point p3) { double x1, y1, x2, y2, tmp; x1 = p2.x - p1.x; y1 = p2.y - p1.y; x2 = p3.x - p1.x; y2 = p3.y - p1.y; tmp = x1*y2 - x2*y1; if (1e-6<tmp && tmp<1e-6) return 1; else return 0; } int main() { int cnt; /* 自动生成随机数据 */ FILE *pFile1, *pFile2; pFile1 = fopen ("client.txt","w"); pFile2 = fopen ("in.txt","w"); cnt = N; srand( time(NULL) ); while (cnt--) { rand_Point(&s1); do { rand_Point(&s2); } while (is_equal(s1, s2)); do { rand_Point(&s3); } while (is_inline(s1, s2, s3)); rand_Point(&c); /* 客户端准确位置 */ if (pFile1!=NULL) { fprintf(pFile1, "%lf %lf\n", c.x, c.y); } /* 生成测试数据 */ if (pFile2!=NULL) { fprintf(pFile2, "%lf %lf\n%lf %lf\n%lf %lf\n", s1.x, s1.y, s2.x, s2.y, s3.x, s3.y); fprintf(pFile2, "%lf\n%lf\n%lf\n", dist(s1, c), dist(s2, c), dist(s3, c)); } } fclose (pFile1);; fclose (pFile2); /**/ /* 手工输入: freopen("dataG.txt", "r", stdin); freopen("in.txt", "w", stdout); while (~scanf("%lf%lf%lf%lf%lf%lf%lf%lf", &s1.x, &s1.y, &s2.x, &s2.y, &s3.x, &s3.y, &c.x, &c.y)) { printf("%lf %lf\n%lf %lf\n%lf %lf\n", s1.x, s1.y, s2.x, s2.y, s3.x, s3.y); printf("%lf\n%lf\n%lf\n", dist(s1, c), dist(s2, c), dist(s3, c)); } */ return 0; } double dist(Point a, Point b) { return sqrt(pow(a.x-b.x, 2.0) + pow(a.y-b.y, 2.0)); }
.