5

2Dの魔法の六角形の格子を生成しようとしています(つまり、C言語で点の座標を生成する必要があります)。添付の画像を参照してください。図は、大きなものの中に六角形があるタマネギの構造のように見えます。

誰かアイデアがありますか?

注:他の言語で誰かが答えを持っていれば大丈夫です。自分のコードの作成を開始できるように、確認する必要があります。前もって感謝します。

      void generate_particles(void)
      {/* Generates the particle - positions and charge
      Here it indicated to use the hexagonal referential !!*/
      int    i,j;
      int    n=3; /*n represent the nth centered hex number given by the formula 3*n(n- )+1*/
      double b;
      b=(1.0/sqrt(sqrt(3)))*sqrt(2.0/par.NA);
      /* b=1.0;*/


      fprintf(stderr,"Distributing %d particles  on the hexagonal lattice'...", par.N);

      for (i=0;i<n-1;i++)
     {
      coo[i][0]= (sqrt(3)*i*b)/2.0;
       for (j=0;j<(2*n-i-1);j++)
       {
        coo [i][1]= (-(2*n-i-2)*b)/2.0 + j*b;

       fprintf(stderr," %lf    %lf\n",coo[i][0],coo[i][1]);

        /*plot the points with coordinate (x,y) here*/
       if(coo[i][0]!=0)
           {     
       fprintf(stderr," %lf    %lf\n",-coo[i][0],coo[i][1]);
              /*plot the points with coordinates (-x,y)*/
         }
        }

        }fprintf(stderr," done\n\n");
       }  



        void write_configuration_file(void)
    {/* Writes the binary configuration file '<prefix>_config.<postfix>'
     i.e velocities and coordinates. */

     FILE *fp;
     char  filename[100];
      char  postfix_string[100];
      int   i;

      fprintf(stderr,"Writing configuration file");

     if (postfix >=0 ) {
    if      (postfix <   10) sprintf(postfix_string,"000%d",postfix);
    else if (postfix <  100) sprintf(postfix_string, "00%d",postfix);
    else if (postfix < 1000) sprintf(postfix_string,  "0%d",postfix);
    else if (postfix <10000) sprintf(postfix_string,   "%d",postfix);
    else                     sprintf(postfix_string,  "_%d",postfix);
    } else {
    fprintf(stderr,"\nThe internal postfix is negative.\n\n");
    exit(1);
    }

    sprintf(filename,"%s_config.%s",prefix,postfix_string); 

    fprintf(stderr," %s...", filename);

    if ((fp = fopen(filename,"r")) != NULL) {
    fprintf(stderr,"\nFile '%s' already exists. Don't want to overwrite it.\n\n",filename);
    fclose(fp);
    exit(1);
    }

     if ((fp = fopen(filename,"w")) == NULL) {
      fprintf(stderr,"Could not create file '%s'.\n\n",filename);
     exit(1);
     }

     /* postfix */
      if (fwrite(&postfix,sizeof(int),1,fp) != 1)
     { fprintf(stderr,"fwrite error 1.\n\n"); exit(1); }

     /* time */
     if (fwrite(&ti,sizeof(int),1,fp) != 1)
     { fprintf(stderr,"fwrite error 2.\n\n"); exit(1); }


     /* x,y coordinates of all particles/charges */

      if (fwrite(coo,sizeof(double) ,2*par.N,fp) != 2*par.N)
       { 
        fprintf(stderr,"fwrite error 4.\n\n"); exit(1); }

        fclose(fp);

        fprintf(stderr," done\n");
        }


and the main program is:

     int main()
    {
    int i;



         printf("\n");
         printf("\n");
          printf("***************************************************************\n");
      printf("* OK LETS GENERATE THE CONFIG FILE FOR MONTE CARLO SIMULATION *\n");
      printf("***************************************************************\n\n");

      read_wishlist();

      init_ran1();

      for (i=0; i<seed; i++) ran1_fast();


      if (par.N > 0) generate_particles();


      write_parameter_file();
      write_configuration_file();
      write_task_file();

      /*final_test();*/

      fprintf(stderr,"\n\nConfiguration successfully generated.\n\n");
    }

さて、私の問題を説明させてください。実際、前に私に与えたコードは完璧で、Cとmatlabで六角形の粒子をプロットすることができましたが、それはプロットでした。シミュレーションに関しては、各粒子には問題がありました。私のコードでは0からpar.Nまでのラベルがありますが、これを書く方法では、レイヤー13にある13個の粒子しか読み取っていませんでした。したがって、各粒子が1つになるようにこれを変更する方法の解決策を見つけるのを手伝ってください。事前に感謝を調整します。

@MohamedKALLELまず最初に関数generate_particlesで

coo[i][0]はx座標とcooiを表しますy座標、generate_particlesの部分を見ると、残りの部分は忘れてしまいます。前に指定したものと似ていますが、このファイルを実行するときに、自分の言語と他の変数を使用して記述しました。画面にプロットされた座標は、まさに私が最初の構成を開始したいのですが、ここで行うのは、構成バイナリファイルにこれらの座標を書き込むことです。問題は、このバイナリファイルを読んでいるときに、出力される座標は0からn-1nだけであるように見えることです。レイヤーの順序、547個のパーティクルがあるため、コードの記述方法では解決できない問題がありますが、このコードでは13の座標しか与えられていないため、すべてのパーティクルにラベルを付ける必要があります。つまり、547個のパーティクルを指定する必要があります。それぞれに独自の座標がありますか?

4

4 に答える 4

10
int i, j;
float y,x;
float d=1.0;// d is the distance between 2 points as indicated in your schema
for(i=0; i<=(n-1); i++) {
    y = (sqrt(3)*i*d)/2.0;
    for (j = 0; j < (2*n-1-i); j++) {
        x = (-(2*n-i-2)*d)/2.0 + j*d;
        //plot the point with coordinate (x,y) here
        if (y!=0) {
            // plot the point with coordinate (x,-y) here
        }
    }

}

スキーマによる説明:

ここに画像の説明を入力してください

ウィキペディアのリンクに示されているようにhttp://en.wikipedia.org/wiki/Centered_hexagonal_numbernth中心付き六角数は次の式で与えられます

ここに画像の説明を入力してください

  • したがって、n = 1の場合、六角形の点の数は1です。
  • n = 2の場合、六角形の点の数は7です。
  • n = 3の場合、六角形の点の数は19です。
  • ..。
于 2013-01-11T17:21:14.237 に答える
2

数学的には、ポイントは

(j + 2k, sqrt(3)j) L/2

ここで、jとkは整数であり、Lは2つのポイント(画像の青い線)間の距離です。

編集:

n番目のレイヤーの(i、j)ペアを出力するコードは次のとおりです。

for(int t=0; t<n ; ++t)
    {
      cout << " (" << t << ", " << n-t << ")" << endl;
      cout << " (" << n << ", " << -t << ")" << endl;
      cout << " (" << n-t << ", " << -n << ")" << endl;
      cout << " (" << -t << ", " << -n+t << ")" << endl;
      cout << " (" << -n << ", " << t << ")" << endl;
      cout << " (" << -n+t << ", " << n << ")" << endl;
    }
于 2013-01-11T15:30:39.630 に答える
1

ラティスだけが必要な場合は、座標は単純に最初の六角形の座標であり、水平方向の行で繰り返されてシフトされます。数十個の六角形を描くと、それが明らかになります。

タマネギの参照により、六角形を作成してから、そのすべての頂点に新しい六角形を作成し、次に2番目の境界の外側の境界に別の世代(3番目)の六角形を作成したいと思います。

あなたは力ずくでそれを行うことができます。

  • 最初の六角形を描きます(たとえば、Aki Suihkonenの答えを参照)。
  • すべての頂点をクローズドリストに配置します。
  • 連続する頂点のすべてのカップル(最後のポイントにいるときは、「次」が最初です)について、作成されたベースラインに対して120度を減算(または六角形を太陽方向に歩くかウィダーシンを歩くかによっては加算)して正三角形を作成します。最初の2つのポイントで。
  • エッジ(頂点のカップル)と同じ数のポイントを取得します。
  • これらのポイントは、新世代の六角形の中心です。すでに存在するエッジの再描画を避けるために、まだ古いエッジのリストがあります。これらの六角形を描画し、それらの頂点を保存します(結合されたエッジの重複に注意してください)。
  • 頂点の新しいリストが最初のリストに置き換わります。
  • 洗って、すすぎ、繰り返します。

数式もあるかもしれません-「六角形のテッセレーション」を探してみてください。

更新:別の可能性は、同じ方法で三角形のグリッドを作成し、それらを六角形に結合することです(きれいなグラフィックについてはここを参照してください)。六角形を構成する6つの三角形ができたら、三角形を塗りつぶすための簡単なアルゴリズムがあります。それらを適応させて、内側のポイントを列挙することができます。ポイントが三角形の内側にあるかどうかを確認する簡単な方法もあります。

于 2013-01-11T15:34:08.153 に答える
1

極形式の座標はR*exp(i * n * pi / 3);です。ここで、n=0..5です。

これはx=R * cos(n);にマップされます。y = R * sin(n); n = 0..5 * pi / 3;

これにより、六角形が原点の中心に配置されます(x = 0、y = 0)。

次のレベルの六角形の角の中心は驚くべきことに:

a = n*R*( exp(i*n*pi/3) + exp(i*(n+1)*pi/3);
            ___
           /   \
       ___/  b  \
      /   \     /
  ___/  a  \___/
 /   \     /   \
/  x  \___/  b1 \
\     /   \     /
 \___/ a1  \___/
           /   \
          /  b2 \
          \     /
           \___/

ポイント「a」または「b」から、n-1ステップを繰り返す必要があります。これらの座標は、center_a + m * R * exp(i *(n + 4)/ 3)+ m * R * exp(i *(n + 5)/ 3)になります。

于 2013-01-11T15:16:40.867 に答える