用数组绘制C中的轨迹图

时间:2015-09-17 20:46:35

标签: c arrays math graph

第一次发帖提问 - 让我希望我建立良好的声誉! 标题几乎描述了我的任务的性质:

  

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

我获得了必须使用的功能的原型,所以这里是我提出的相关代码(这是非常冗长的,但仅仅是为了完整性。实际问题可以是发现在第3和第4个功能中):

$(MODULE_NAME):$(VARIABLE_NAME)

这是我被困住的部分,毫无希望地无能为力。

我理解这个功能背后的想法:它接收&#34;空画布&#34;数组以及包含数据的数组(图中的点)。那么,现在需要做的是,#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中的[1][4]有一个元素,然后是trajData = 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 - 对吧?请指教... }

如果有人注意到任何其他问题或有任何建议,请分享!一切有帮助的人都很感激...

2 个答案:

答案 0 :(得分:0)

阿什顿,如果我没有弄错的话,你似乎遇到的概念上的困难只与C(语法明智)有部分相关。另一部分只是简单地了解你要求对两个独立的数组做什么。我会采取措施清除雾气,希望不会让它变得更糟。这基本上是一个数据扩展问题。

您的两个数组trajDatadisplayData只是同一数据的两种不同表示形式。 trajData包含完整值,displayData只会保留相同的值,以适合[HEIGHT][WIDTH]

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

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

由于您当前正在使用trajData,请将返回类型更改为有用的内容,例如type voidunsigned int或简称size_t(即使没有负片时间)并返回点数)始终选择您的返回类型,以便它返回一些有价值的信息给您。 int返回(不要与void混淆)只应在没有任何用途返回时使用,例如只有void *数据或print内存的函数等等。

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

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

Sy

然后,您需要在int Sx = 0; int Sy = 0; int y_min = INT_MAX; int y_max = INT_MIN; 类似于以下内容的Sy中选择最大/最小值:

calcTraj

要计算比例因子,您将执行类似于:

的操作
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)float,以准确缩放您的值。

此外,如果double远大于Sx,您可能会为每个WIDTH值写入多个'Y'值,其中轨迹的斜率变为垂直 - 就像直接射击子弹的情节。 (如果你只能给1个值,你可以平均)。以下内容应该有效:

'X'

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

答案 1 :(得分:0)

最后!我已经完成了我的课程并且工作得很满意......

  

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

但是请注意,这个程序不是为了准确而构建的,而是为了测试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人员!