CSDN首页 空间 新闻 论坛 Blog 下载 读书 网摘 搜索 .NET Java 视频 接项目 求职 在线学习 买书 程序员 通知
不看会后悔的Windows XP之经验谈 简单快捷DIY实用家庭影院
CSDN社区
搜索 收藏 打印 关闭
CSDN社区 >  专题开发/技术/项目 >  数据结构与算法

100分,求思路!由点得到拟合球

楼主jianxinlee(ljxlee)2003-12-03 14:49:53 在 专题开发/技术/项目 / 数据结构与算法 提问

现有离散空间点若干,如何得到拟合意义上的球,即要求算法给出球心坐标和半径! 问题点数:100、回复次数:8Top

1 楼jianxinlee(ljxlee)回复于 2003-12-03 14:58:20 得分 0

关于提到“拟合意义”,是我自己感觉这个问题就像常见的直线拟合或者多项式拟合。  
   
  当然一个很显然的思路是:(x-x0)^2   +(y-y0)^2   +(z-z0)^2   =   R^2,   然后对R求和S,构造S达到最小时的(x0,   y0,   z0)。但是这个构造过程如何进行呢?  
   
  或者那位牛牛有更好的办法,感激不尽!Top

2 楼saint001(saint001)回复于 2003-12-03 15:04:00 得分 0

如果进行最小二乘拟合,就是求这些点的坐标平均值Top

3 楼saint001(saint001)回复于 2003-12-03 15:06:07 得分 0

问题不是你说的对R求和,使和最小,如果是这个意思,平均值就差不多了(对R^2求和最小)  
  而是要求Ri的偏差(方差)比较小Top

4 楼jianxinlee(ljxlee)回复于 2003-12-03 16:13:35 得分 0

saint001,应该你是对的,我的描述有问题!  
   
  但是这个Ri怎么构造呢?球心半径都是待求量Top

5 楼saint001(saint001)回复于 2003-12-04 16:24:52 得分 0

很简单的问题  
  昨天把它想复杂了  
   
  直接对x^2+y^2+z^2+ax+by+cz+d=0拟合就行了  
  拟合的四个系数是a,b,c,d,最小二乘法  
  本来很简单,可是昨天局限在了把球心和半径作为自变量上  
   
  有了a,b,c,d球心坐标和半径也就知道了Top

6 楼saint001(saint001)回复于 2003-12-04 17:00:02 得分 0

前些天编写的最小二乘拟合的程序,这几天就用了好几次,从d:\CircleFit.txt中读取数据  
  #include   "math.h"  
  #include   "stdio.h"  
  #define   ABS(x)   (x)>0?(x):-(x)  
  #define   SWAP(a,b)   {temp=(a);(a)=(b);(b)=temp;}  
   
  void   solve(double   **a,double   *b,double   *x,int   n)  
  {  
  int   i,j,k,ik;  
  double   mik,temp;  
  for(k=0;k<n;k++)  
  {  
  mik=-1;  
  for(i=k;i<n;i++)  
  if(ABS(a[i][k])>mik)  
  {  
  mik=ABS(a[i][k]);  
  ik=i;  
  }  
  for(j=k;j<n;j++)  
  SWAP(a[ik][j],a[k][j]);  
  SWAP(b[k],b[ik]);  
  b[k]/=a[k][k];  
  for(i=n-1;i>=k;i--)  
  a[k][i]/=a[k][k];  
  for(i=k+1;i<n;i++)  
  {  
  b[i]-=a[i][k]*b[k];  
  for(j=n-1;j>=k;j--)  
  a[i][j]-=a[i][k]*a[k][j];  
  }  
  }  
  for(i=n-1;i>=0;i--)  
  {  
  x[i]=b[i];  
  for(j=i+1;j<n;j++)  
  x[i]-=a[i][j]*x[j];  
  }  
  }  
   
  void   linear(double   **x,double   *y,double   *beta,int   n,int   p)  
  {  
  double   **a,*b;  
  int   i,j,k;  
  a=new   double*[p];  
  for(i=0;i<p;i++)  
  a[i]=new   double[p];  
  for(i=0;i<p;i++)  
  for(j=0;j<p;j++)  
  {  
  a[i][j]=0;  
  for(k=0;k<n;k++)  
  a[i][j]+=x[k][i]*x[k][j];  
  }  
  b=new   double[p];  
  for(i=0;i<p;i++)  
  {  
  b[i]=0;  
  for(j=0;j<n;j++)  
  b[i]+=x[j][i]*y[j];  
  }  
  solve(a,b,beta,p);  
  for(i=0;i<p;i++)  
  delete   a[i];  
  delete   a,b;  
  }  
   
  void   main()  
  {  
  int   i,n,p=4;  
  double   x0,y0,z0,r;  
  double   **x,*y,beta[4];  
   
  FILE   *fp=fopen("d:\\CircleFit.txt","r");  
  fscanf(fp,"%d",&n);  
  x=new   double*[n];  
  y=new   double[n];  
  for(i=0;i<n;i++)  
  {  
  x[i]=new   double[4];  
  fscanf(fp,"%lf",x[i]);  
  fscanf(fp,"%lf",x[i]+1);  
  fscanf(fp,"%lf",x[i]+2);  
  x[i][3]=1;  
  y[i]=-x[i][0]*x[i][0]-x[i][1]*x[i][1]-x[i][2]*x[i][2];  
  }  
  fclose(fp);  
  linear(x,y,beta,n,p);  
  x0=-beta[0]/2;  
  y0=-beta[1]/2;  
  z0=-beta[2]/2;  
  r=sqrt(x0*x0+y0*y0+z0*z0-beta[3]);  
  printf("%f\t%f\t%f\t%f\t\n",x0,y0,z0,r);  
  }Top

7 楼saint001(saint001)回复于 2003-12-04 17:35:09 得分 100

刚才一段时间上不去论坛  
  d:\CircleFit.txt中的数据  
  20  
          2.8708         1.3399         3.2936  
          1.3901         0.9456         4.7586  
        -0.2118         1.4578         4.4892  
        -0.7987         1.6279         3.5585  
          2.3814         0.9131         3.9640  
          2.4616         0.8509         2.2743  
        -0.7898         2.6383         3.6532  
          2.5070         3.3155         3.3500  
        -0.6203         0.9506         3.3615  
        -0.8986         2.4616         2.6251  
          2.5346         3.2571         2.5281  
          2.5465         1.8771         4.4302  
          3.0246         2.2083         3.3029  
          3.0213         2.4154         2.6920  
          0.1899         2.2169         4.8677  
          2.6968         1.4048         2.1883  
        -0.7191         3.0063         2.8426  
          2.7501         1.5074         2.1484  
          2.8091         2.7637         2.3159  
        -0.9991         2.1089         3.0588  
  数据是用matlab产生的球心为1,2,3,半径为2的球面上的随机点,并有随机误差(0.1以内),所以拟合出来球心近似是[1,2,3],半径应该近似为2  
  程序输出结果是  
  1.039589                 2.051142                 3.058152                 2.009236  
  前三项为球心坐标,后一项为半径Top

8 楼jianxinlee(ljxlee)回复于 2003-12-04 18:51:21 得分 0

强人,呵呵,谢了,这就结贴!Top

相关问题

  • 计算球队实力的算法?给点思路
  • 模拟公共汽车的思路问题??????????????????
  • 求键盘模拟按钮事件思路
  • 请教虚拟打印机的问题,给点思路。
  • 请问做月报表时,有什么好的思路,方法得到"上月结存"?谢谢!
  • 请提供思路,我们可以通过技术得到某机器的IP地址。怎样得到他的电话号码呢,
  • 给个思路!
  • 给个思路!
  • 排班思路!
  • 求教思路

关键词

  • 坐标
  • 拟合
  • 球心
  • mik
  • 半径
  • 构造
  • 问题
  • double
  • temp

得分解答快速导航

  • 帖主:jianxinlee
  • saint001

相关链接

  • CSDN Blog
  • 技术文档
  • 代码下载
  • 第二书店
  • 读书频道

广告也精彩

反馈

请通过下述方式给我们反馈
反馈
提问
网站简介|广告服务|VIP资费标准|银行汇款帐号|网站地图|帮助|联系方式|诚聘英才|English|问题报告
世纪乐知(北京)网络技术有限公司 版权所有, 京 ICP 证 020026 号
北京创新乐知广告有限公司 提供技术支持
Copyright © 2000-2007, CSDN.NET, All Rights Reserved
GongshangLogo