[英]Calculating force vectors between N bodies returns incorrect values?
我正在尝试编写一个 function,它使用 F = GMm/r^2(给定质量和初始位置 in.txt 文件)计算作用在 N 个物体上的力矢量,并将这些值存储在动态分配的数组中. 我认为问题源于半径(两个物体之间的距离)的计算,因为返回的值不正确。 initial_positions.txt 文件中的 position 向量采用以下格式(不带标题):
pos_x pos_y pos_z
1 2 3
4 5 6
7 8 9
1 2 3
4 5 6
masss.txt 文件中的质量是这样的格式:
1
2
3
4
5
因此,质量为 1 的物体的初始值为 position (1, 2, 3),质量为 2 的物体的初始值为 position (4, 5, 6) 等。
我读取文件并计算力矢量的代码:
#include <stdio.h>
#include <stdlib.h>
int NumberOfBodies(void) //finds the number of bodies from masses.txt file.
{
char character;
char previousCharacter;
int numberOfBodies = 1;
FILE *file = fopen("masses.txt", "r");
if (file == NULL)
{
printf("\nUnable to access the 'masses.txt' file.\n");
exit(1);
}
else
{
while ((character = fgetc(file)) != EOF)
{
if (character == '\n' && previousCharacter != '\n')
{
numberOfBodies++;
}
previousCharacter = character;
}
}
fclose(file);
return numberOfBodies;
}
double *ReadMasses(int numberOfBodies) //reads masses.
{
int row;
int line;
double *masses = malloc(sizeof(double) * numberOfBodies);
FILE *file = fopen("masses.txt", "r");
if (file == NULL)
{
printf("\nUnable to access the 'masses.txt' file.\n");
exit(1);
}
for (row = 0; row < numberOfBodies; row++)
{
line = fscanf(file, "%lf", &masses[row]);
if (line == EOF)
{
break;
}
}
fclose(file);
return masses;
}
double **ReadInitialPositions(int numberOfBodies) //reads initial positions.
{
int row;
int scan;
double **initialPositions = malloc(sizeof(double*) * numberOfBodies);
for (row = 0; row < numberOfBodies; row++)
{
initialPositions[row] = malloc(sizeof(double) * 3); //hardcoded as we only consider x, y, and z components of position.
}
FILE *file = fopen("initial_positions.txt", "r");
if (file == NULL)
{
printf("\nUnable to access the 'initial_positions.txt' file.\n");
exit(1);
}
for (row = 0; row < numberOfBodies; row++)
{
scan = fscanf(file, "%lf %lf %lf", &initialPositions[row][0], &initialPositions[row][1], &initialPositions[row][2]);
if (scan == EOF)
{
break;
}
}
fclose(file);
return initialPositions;
}
double **CalculateForces(int numberOfBodies, double *masses, double **initialPositions) //function to calculate force vectors.
{
int row;
int column;
int currentBody = 0;
double radius;
double gravitationalConstant = 6.6743;
double **forces = malloc(sizeof(double*) * numberOfBodies);
for (row = 0; row < numberOfBodies; row++)
{
forces[row] = malloc(sizeof(double) * 3);
}
for (row = 0; row < numberOfBodies; row++)
{
for (column = 0; column < 3; column++)
{
if (row != currentBody)
{
radius = (initialPositions[row][column] - initialPositions[row][currentBody]); //I suspect the issue stems from this line.
forces[row][column] = (gravitationalConstant * masses[row] * masses[currentBody]) / (radius * radius);
currentBody++;
}
else
{
forces[row][column] = 0;
currentBody++;
}
}
}
for (row = 0; row < numberOfBodies; row++)
{
for (column = 0; column < 3; column++)
{
printf(" %lf", forces[row][column]); //Prints force vectors.
}
printf(" \n");
}
return forces;
}
int main(void)
{
int numberOfBodies;
double *masses;
double **initialPositions;
numberOfBodies = NumberOfBodies();
masses = ReadMasses(numberOfBodies);
initialPositions = ReadInitialPositions(numberOfBodies);
CalculateForces(numberOfBodies, masses, initialPositions);
return 0;
}
NumberOfBodies()、ReadMasses() 和 ReadInitialPositions() 似乎都按预期工作。 提前致谢::)
这具有在没有牢固掌握数学的情况下编写的代码的所有指定用途。 尝试先写出数学。
GMm/r^2 给出了两个物体之间的标量力。 它沿着物体之间的方向矢量起作用。 因此,必须将标量拆分为其矢量分量。 分裂只是乘以缩放到单位长度的方向向量。
更重要的是,如果你计算物体 a 和 b 之间的力,那么
Rab^2 = (xb - xa)^2 + (yb - ya)^2 + (zb - za)^ 2
Fab = ma mb / Rab^2
从 a 到 b 的单位向量具有坐标
Uabx = (xb - xa) / Rab
Uaby = (yb - ya) / Rab
Uabz = (zb - za) / Rab
当然是上面计算的 Rab = sqrt(Rab^2) 。
由于 b 作用在 a 上的力的三个分量是
Fabx = Uabx * Fab
Faby = Uaby * Fab
Fabz = Uabz * Fab
由于 a 作用在 b 上的力为 Fb = -Fa。
将其作为算法解决:
For each pair a,b of bodies
Find r^2 the distance between a and b.
Find Fab the scalar force between a and b.
Find Ua the unit vector from a toward b.
Find vector Fa by splitting Fab into three components using Ua.
Add Fa into the total force acting on a.
Add -Fa into the total force acting on b.
快速查看您的代码表明它不太接近正确。 例如:它为一对物体计算三个不同的值 r。 空间中两点之间只能有一个距离!
提示:要获取 [0..n-1] 中不包括自对(如 (1, 1))的所有整数对(忽略顺序),标准模式是如下所示的循环:
for (j = 1; j < n; j++)
for (i = 0; i < j; i++)
这将按顺序迭代 ij 对 (0, 1), (0, 2), (1, 2), (0, 3), (1, 3), (2, 3), ...
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.