繁体   English   中英

计算 N 个物体之间的力矢量返回不正确的值?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM