繁体   English   中英

用数组在C中绘制轨迹图

[英]Plotting Trajectory Graph in C with Arrays

第一次发布问题-希望我能树立良好的声誉! 标题几乎描述了我的工作性质:

用户输入弹丸的初始速度和发射角后,我的程序必须生成点并绘制弹丸轨迹图。 为此,我必须使用两个2D数组-一个用于生成的点,另一个用于画布(基本上是一个40x80的空格填充的空数组)。

为我提供了必须使用的函数的原型,所以这里是我提供的相关代码(虽然很冗长,但仅出于完整性考虑。实际问题可以在第3和第4个函数中找到。 ):

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "Assignment6B.h"

int Sx = 0;
int Sy = 0;
void calcTraj(double initSpeed, double launchAngle, double trajData[][2]) {
    do {
        double Ux = initSpeed*cos(launchAngle*3.14/180.0);
        double Uy = initSpeed*sin(launchAngle*3.14/180.0);
        Sy = (Sx/Ux)*(Uy - ((9.81*Sx)/(2*Ux)));
        if (Sy >= ZERO) {
            trajData[Sx][0] = Sx;
            trajData[Sx][1] = Sy;
        }
        Sx++;
    } while (Sy >= ZERO);
}

int Row, Column;
void clearDisplayData(char displayData[HEIGHT][WIDTH]) {
    for (Row = 0; Row < HEIGHT; Row++) {
        for (Column = 0; Column < WIDTH; Column++) {
            displayData[Row][Column] = ' ';
        }
    }
}

void updateDisplayData(char displayData[HEIGHT][WIDTH], double trajData[][2]) {

这是我受困的部分,毫无希望。

我理解该函数背后的思想:它接收“空画布”数组以及包含数据的数组(图形的点)。 那么,是什么现在需要做的,是所有的元素displayData ,与对应[Sx][Sy]坐标-在trajData ,需要与被替换X 例如,说trajData中的[1][4]有一个元素,则displayData[1][4] = X

我只是不知道该如何编码。 如果有人可以提供样品,那就太好了!

}

void printData(char displayData[HEIGHT][WIDTH]) {
    puts("");
    for (Column = 0; Column < WIDTH + 2; Column++) {
        printf("_");
    }
    puts("");
    for (Row = 0; Row < HEIGHT; Row++) {
        printf("|");
        for (Column = 0; Column < WIDTH; Column++) {
            printf("%c", displayData[Row][Column]);
        }
        printf("|");
        puts("");
    }
    for (Column = 0; Column < WIDTH + 2; Column++) {
        printf("_");
    }

此功能也不完全正确。 我必须绘制一个图,这意味着点[0,0]必须在左下角。 但是数组的元素[0][0]在左上角。

我认为应该以for循环反转行的显示顺序,例如for (Row = HEIGHT; Row > 0; Row--) -- for (Row = HEIGHT; Row > 0; Row--) -对吗? 请指教... }

如果有人发现任何其他问题或有任何建议,请分享! 一切帮助都值得赞赏...

阿什顿,如果我没记错的话,您似乎遇到的概念上的困难仅部分与C有关(语法上)。 另一部分只是简单地了解要求您使用两个单独的阵列做什么。 我会尽力消除雾气,希望不会使情况变得更糟。 这基本上是一个数据扩展问题。

你的两个数组trajDatadisplayData只是相同数据的两个不同的表示。 trajData保留完整值, displayData将仅保留缩放以适合[HEIGHT][WIDTH]的相同值。

您的trajData保留了在任何给定时间点从运动学方程返回的值。 您的displayData只是一个数组,其中包含将trajData的内容打印到某些[HEIGHT][WIDTH]显示时将要打印到屏幕上的内容。 这是您的工作所在。

为了适应trajData进入[HEIGHT][WIDTH]的约束displayData ,你需要计算两个比例因子。 第一个将缩放HEIGHTMAX - HEIGHTMIN之间的差,因此所有Y值数据点都适合HEIGHT 您的第二个比例因子将确保您所有的时间值(您计算出的点的迭代次数,例如while (Sy >= ZERO); )将适合WIDTH (这也意味着您将需要使用trajData的点数返回(或更新指针)。

由于您当前使用的是type void ,请将返回类型更改为有用的值,例如, unsigned intsize_t或简单地称为int (即使没有负时间)并返回点数)请始终选择返回类型,以便它返回一些对您有价值的信息。 void返回(不要与void *混淆)仅在没有任何返回可使用的情况下才使用,例如仅print数据或free内存的函数等。

知道点数并知道'Y'值的范围,您可以计算因子来缩放trajData值。 这些比例因子将限制您用于填充displayData的值,因此它们都适合,因此您不会在数组末尾犯下写入错误。

使用displayData数组(清除后)的目标只是打开包含trajData值的单元格,这些单元格的值已缩放为适合[HEIGHT][WIDTH] 要使用比例,您需要知道SxSy的范围,因此您可以添加一些变量,例如:

int Sx = 0;
int Sy = 0;
int y_min = INT_MAX;
int y_max = INT_MIN;

然后,您需要在calcTraj选择Sy的最大值/最小值,类似于:

int calcTraj(double initSpeed, double launchAngle, double trajData[][2]) {

    ... 
    if (Sy >= ZERO) {
        if (Sy > y_max) y_max = Sy;
        if (Sy < y_min) y_min = Sy;
        ...
    } while (Sy >= ZERO);

    return Sx;
}

要计算比例因子,您将执行以下操作:

int scale_x = WIDTH/Sx;
int scale_y = HEIGHT/(y_max - y_min);

为了填充displayData ,您只需要打开要显示轨迹路径的任何字符,例如'X''#''*' 类似于以下内容的内容应该很接近,但请注意 ,由于您使用的是整数除法,因此可能必须调整在HEIGHT小于(y_max - y_min)使用的缩放公式,或更改为其他中间数据类型,例如floatdouble准确地扩展您的价值。

同样,如果Sx远大于WIDTH您可能会在轨迹的斜率变为垂直的每个'X'值上写几个'Y'值-像是将子弹笔直向上射击的情节。 (如果您只能给出1的值,则可以取平均值)。 类似于以下内容的东西应该起作用:

/* set each relative cell to 'X' */
for (i = 0; i < Sx; i++) {
    displayData[scale_x * trajData[i][0]][scale_y * trajData[i][1]] = 'X';
}

注意:这些只是关于此问题的想法,我还没有编写完整的示例进行测试。 因此,如果您遇到问题,请告诉我。

最后! 我已经完成我的程序,并且效果令人满意。

完成的代码如下。 我仅添加它,以便可能遇到相同问题的人可以看到所需的结果。

但是请注意,该程序并不是为准确性而构建的,而是对C初学者的技能,知识和能力的测试。

头文件:

#ifndef ASSIGNMENT6B_H_
#define ASSIGNMENT6B_H_

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

// Constants (of array to serve an "canvas" for graph and calculations)
#define WIDTH   80
#define HEIGHT  40
#define g       9.81
#define ZERO    0.0

// Function Prototypes
void calcTraj(double initSpeed, double launchAngle, double trajData[WIDTH][2]);
void clearDisplayData(char displayData[HEIGHT][WIDTH]);
void updateDisplayData(char displayData[HEIGHT][WIDTH], double trajData[WIDTH][2]);
void printData(char displayData[HEIGHT][WIDTH]);

#endif /* ASSIGNMENT6B_H_ */

职能:

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "Assignment6B.h"

void calcTraj(double initSpeed, double launchAngle, double trajData[WIDTH][2]) {
    int Sx = 0;
    int Sy = 0;
    //assign all values in array to 0
    int i, j;
    for (i = 0; i < WIDTH; i++) {
        for (j = 0; j < 2; j++) {
            trajData[i][j] = 0;
        }
    }
    double Ux = initSpeed*cos(launchAngle*M_PI/180.0);      //Horizontal component of velocity
    double Uy = initSpeed*sin(launchAngle*M_PI/180.0);      //Vertical component of velocity
    do {
        Sy = (Sx/Ux)*(Uy - ((g*Sx)/(2*Ux)));                //Calculates y-value of position for every x used
        if (Sy >= ZERO) {
            //Stores data in a table form
            trajData[Sx][0] = Sx;
            trajData[Sx][1] = Sy;
        }
        Sx++;
    } while (Sy >= 0 && Sx <= 80 && Sx >= 0);               //Executed only for as long as projectile is air-borne
}                                                           //and within graphing range

//Assigns spaces to all elements of the "canvas",
//i.e. creates an empty array with the desired dimensions
void clearDisplayData(char displayData[HEIGHT][WIDTH]) {
    int Row, Column;
    for (Row = 0; Row < HEIGHT; Row++) {
        for (Column = 0; Column < WIDTH; Column++) {
            displayData[Row][Column] = ' ';
        }
    }
}

//Merges the two arrays,
//i.e. adds all data (coordinates) for trajData to displayData to create the graph
void updateDisplayData(char displayData[HEIGHT][WIDTH], double trajData[WIDTH][2]) {
    int i;
    for (i = 0; i < WIDTH; i++) {
        if (HEIGHT - (int)floor(trajData[i][1]) >= 0) {
            displayData[HEIGHT - (int)floor(trajData[i][1])][(int)floor(trajData[i][0])] = '*';
        }
    }
}

//Prints graph and border
void printData(char displayData[HEIGHT][WIDTH]) {
    int Row, Column;
    puts("");
    for (Column = 0; Column < WIDTH + 2; Column++) {
        printf("_");
    }
    puts("");
    for (Row = 0; Row < HEIGHT; Row++) {
        printf("|");
        for (Column = 0; Column < WIDTH; Column++) {
            printf("%c", displayData[Row][Column]);
        }
        printf("|");
        puts("");
    }
    for (Column = 0; Column < WIDTH + 2; Column++) {
        printf("_");
    }
}

主要:

#include "Assignment6B.h"

double initSpeed, launchAngle;
char displayData[HEIGHT][WIDTH];
double trajData[WIDTH][2];
int a;

int main() {

    do {

        //Clear display (on Windows)
        system("cls");

        setbuf(stdout, 0);

        clearDisplayData(displayData);

        printData(displayData);

        //Values to be entered by user and used in functions
        printf("\n\nEnter the Initial Speed of the particle: ");
        scanf("%lf", &initSpeed);
        printf("\nEnter the Launch Angle of the particle: ");
        scanf("%lf", &launchAngle);

        calcTraj(initSpeed, launchAngle, trajData);

        updateDisplayData(displayData, trajData);

        printData(displayData);

        //Allows user to repeat or exit
        printf("\n\nType a '0' to exit; any other number to continue: ");
        scanf("%d", &a);

    } while (a != 0);

    return 0;
}

就是这样! 随时发表评论,评分,投票或其他任何方式-谢谢,Stack Overflow的人!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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