C++ 二维幻方六边形格的生成算法
我正在尝试生成一个2D魔法六边形晶格(即我需要用C语言生成点的坐标)参见附件中的图像,该图看起来像一个洋葱状结构,其中较大的一个内有六边形,以此类推 有人有主意吗 注意:如果任何人有其他语言的答案,我只需要看一下,这样我就可以开始构建自己的代码了。 提前谢谢C++ 二维幻方六边形格的生成算法,c++,c,C++,C,我正在尝试生成一个2D魔法六边形晶格(即我需要用C语言生成点的坐标)参见附件中的图像,该图看起来像一个洋葱状结构,其中较大的一个内有六边形,以此类推 有人有主意吗 注意:如果任何人有其他语言的答案,我只需要看一下,这样我就可以开始构建自己的代码了。 提前谢谢 void generate_particles(void) {/* Generates the particle - positions and charge Here it indicated to u
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");
}
void生成_粒子(void)
{/*生成粒子位置和电荷
这里表示要使用六边形参照*/
int i,j;
int n=3;/*n表示由公式3*n(n-+1)给出的以n为中心的十六进制数*/
双b;
b=(1.0/sqrt(sqrt(3))*sqrt(2.0/par.NA);
/*b=1.0*/
FPrTrF(STDRR),“分布在六角晶格上的%D粒子”……,PAR n。
对于(i=0;i=0){
if(postfix<10)sprintf(postfix_字符串,“000%d”,postfix);
否则如果(后缀<100)sprintf(后缀字符串,“00%d”,后缀);
否则如果(后缀<1000)sprintf(后缀字符串,“0%d”,后缀);
else if(postfix极坐标形式为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步。然后这些坐标是中心坐标(i*(n+4)/3)+m*R*exp(i*(n+5)/3)从数学上讲,这些点是
(j + 2k, sqrt(3)j) L/2
其中j和k是整数,L是两个点之间的距离(图像中的蓝线)
编辑:
下面是打印第n层(i,j)对的代码:
for(int t=0;t如果你只是想要晶格,那么坐标就是第一个六边形的坐标,它被水平行重复并移动。画几十个六边形,这将是显而易见的
洋葱参考使我认为您需要构造一个六边形,然后在其所有顶点上构建新的六边形,然后在第二个顶点的外边界上构建另一代(第三代)六边形
你可以用蛮力来做
- 绘制第一个六边形(参见Aki Suikkonen的答案)
- 将其所有顶点放置在闭合列表中
- 对于所有连续顶点对(当您位于最后一个点时,“下一个”是第一个),通过减去(或添加,取决于您是否沿六边形日光或widdershins行走)120度到由前两个点形成的基线来构建等边三角形
- 得到的点与边(顶点对)的数量相同
- 这些点是新一代六边形的中心。您仍然保留旧的边列表,以避免重新绘制现有边。绘制这些六边形并存储其顶点(注意连接边上的重复点)
- 新的顶点列表将替换第一个顶点
- 清洗,漂洗,重复
可能还有一个公式——试着寻找“六边形镶嵌”
更新:另一种可能是用同样的方法构建一个三角形网格,并将它们组合成六边形(有关漂亮的图形,请参阅)一旦你有了构成六边形的六个三角形,就会有快速算法来填充三角形;你可以调整这些算法来枚举内部点。也有快速方法来检查点是否在三角形内部。int i,j;
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
}
}
}
浮动y,x;
float d=1.0;//d是模式中指示的两点之间的距离
对于(i=0;我“喜欢洋葱结构,其中较大的内部有六边形”…这就是我所说的需求规范:)对不起,我想这里没有人能从这个描述中看出你真正想要什么这些图形很漂亮,但不是很有用。你想计算什么点?你想计算六边形顶点的坐标吗,给定中心点的坐标和(最大值)半径?可能是给出了中心点。然后算法推导出六边形的坐标。我无法理解您的要求。罗盘指令对计算机来说几乎毫无用处。顺便说一句,几何上不可能将较小的六边形叠加成较大的六边形,就像您可以处理正方形和三角形一样。是的,但有一个每个六边形的角点之间的点的集合,这个公式不适用,你写的那个只适用于六边形的顶点,但我想要的是内点,你想知道给定的点是否在六边形的内部,你是不是在一个像素一个像素地画六边形?试着说明最初的问题,就是六边形的那个这是一个解决问题的办法。我想这可能行得通,我会尽快尝试,但你说的n是什么意思??总点数??n是指链接中的数字:。因此,对于n=1,六边形中的点数是1。对于n=2,六边形中的点数是7。对于n=3,六边形中的点数是7n为19如维基百科链接所示,n
居中的六边形数由公式3n(n-1)给出+1
@SarahAl Jawhari:Salam Alaikoum,如果你有更多问题要问这个问题。请更新你的问题,而不是我的答案,然后给我一个关于我的答案的评论以查看你的更新,我将尝试回答你。否则你可以问一个新问题,并在新问题中引用此线程Salam AlaikoumSalam mohamed can你现在看到问题了吗?谢谢你的帮助谢谢
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
}
}
}