mit6837的assignment0的总结

来源:互联网 发布:招网络女主播是做什么 编辑:程序博客网 时间:2024/04/29 10:58

       这是一个做分形计算的实验.

       本身的算法很简单,就是随即取分部整张图的点,然后概率性的选取矩阵做迭代,迭代若干次后就可以获得结果.

       实验本身提供了vectors,matrix,image类的实现.我们要做的就是给出Ifs类和最后的main函数.

       先是Ifs.h文件中Ifs类的申明:

 class Ifs { 
 private:
 struct MatrixType
 {
  Matrix m;
  float f;
  MatrixType(const Matrix& tm, float tf )
   :m(tm)
   ,f(tf)
  {
  }

 };
 typedef std::vector<MatrixType> Matrices;
 Matrices Trans;
public:
 Ifs(){}
 Ifs(Matrices Trans);
 void Read(char *filename);
 Image* render(int pnum,int inum,int width,int height);
 Matrix cal(float n);
};

用了vector来储存分形矩阵和概率.、

因为image函数它本身的初始化过程中了就用了new,所以我们对render函数的调用用指针.

       然后Ifs.c文件:

void Ifs::Read( char *filename)
{
 ifstream ifile;     
 ifile.open(filename);
 int n;
 float f;
 ifile>>n;
 float a[16];
 while(1)
 { 
  if(ifile.eof()!=0)
   break;
  ifile>>f>>a[0]>>a[1]>>a[3]>>a[4]>>a[5]>>a[7]>>a[12]>>a[13]>>a[15];
  Matrix k;
  for(int s=0;s<4;s++){
       if (s == 2) continue;
   for(int t=0;t<4;t++){
    if (t == 2) continue;
    k.Set(t,s,a[4*s+t]);
   }
  }
  Trans.push_back(MatrixType(k,f));
 }
 ifile.close();

}

     这是读入文件的函数,用push_back来保存到Ifs类Tran中.注意下矩阵变换3*3到4*4是把第三行和第三列全部补成0.

Matrix Ifs::cal(float n)
{
 Matrices::iterator i = Trans.begin();
 for (;i != Trans.end();i++)
 {
  n -= i->f;
  if (n<=0)
  {
   return i->m;
  }

 }
}

Image* Ifs::render(int pnum,int inum,int width,int height)
{
 float randp,kp;
 srand(time(0));
 float(* pointarray)[2]= new float[width*height][2];
 Image* myimage=new Image(width,height);
 Vec2f vec;

 for(int j=0;j<=pnum-1;j++)
 {
  int k=rand()%100;
  kp=k/100.00;
  pointarray[j][0]=k;
  k=rand()%100;
  kp=k/100.00;
  pointarray[j][1]=k;
 }
 for(int i=0;i<=inum-1;i++)
  for(int j=0;j<=pnum-1;j++)
  {
   vec=Vec2f::Vec2f(pointarray[j][0],pointarray[j][1]);
   int k=rand()%100;
   randp=k/100.00;
   Matrix aTran=cal(randp);
   aTran.Transform(vec);
   pointarray[j][0]=vec.x();
   pointarray[j][1]=vec.y();
   if(pointarray[j][0]>=1)
    pointarray[j][0]=0.99;
   if(pointarray[j][0]<0)
    pointarray[j][0]=0;
   if(pointarray[j][1]>=1)
    pointarray[j][1]=0.99;
   if(pointarray[j][1]<0)
    pointarray[j][1]=0;
  }
 for(int j=0;j<=pnum-1;j++)
  myimage->SetPixel(pointarray[j][0]*width,pointarray[j][1]*height,Vec3f(0.0f,1.0f,0.0f));
 delete []pointarray;
 return myimage;
}

cal函数是用来按概率选取哪个矩阵的.

render函数就是读入长宽,点数和迭代次数,然后进行迭代生成一个image类的过程.pointarray数组太大,所以new出来.return前记得把它delete掉.这里的image是new出来的,为了不让它在调用结束就析构掉,我们对image是new的,后面在parse.c中记得把它delete掉.注意矩阵变换后可能越界,所以把越界的点拉回来.

最后是parse.c:

int main(int argc,char *argv[])
{
 char *input_file = NULL;
 int width = 100;
 int height = 100;
 int pnum = 100;
 int inum = 10;
 char *output_file = NULL;
 float depth_min = 0;
 float depth_max = 1;
 char *depth_file = NULL;

 // sample command lines:
 // raycast -input input.txt -size 100 100 -output output.tga
 // raycast -input input.txt -size 100 100 -depth 5.5 8.8 output.tga

 for (int i = 1; i < argc; i++) {
  if (!strcmp(argv[i],"-input")) {
   i++; assert (i < argc);
   input_file = argv[i];
  } else if (!strcmp(argv[i],"-size")) {
   i++; assert (i < argc);
   width = height=atoi(argv[i]);
  } else if (!strcmp(argv[i],"-points")) {
   i++; assert (i < argc);
   pnum = atoi(argv[i]);
  } else if (!strcmp(argv[i],"-iters")) {
   i++; assert (i < argc);
   inum = atoi(argv[i]);
  } else if (!strcmp(argv[i],"-output")) {
   i++; assert (i < argc);
   output_file = argv[i];
  } else if (!strcmp(argv[i],"-depth")) {
   i++; assert (i < argc);
   depth_min = atof(argv[i]);
   i++; assert (i < argc);
   depth_max = atof(argv[i]);
   i++; assert (i < argc);
   depth_file = argv[i];
  } else {
   printf ("whoops error with command line argument %d: '%s'\n",i,argv[i]);
   assert(0);
  }
 }
 Ifs myifs;
 myifs.Read(input_file);
 Image* myimage=myifs.render(pnum,inum,width,height);
 myimage->SaveTGA(output_file);
 delete myimage;
}

最后记得把myimage delete掉就可以了.

原创粉丝点击