C 中的函数使用结构来计算梯形的面积和周长(一项测试未通过)?

问题描述 投票:0回答:1

给出了结构:

struct Point {
    double x, y;
};
struct Trapezoid {
    struct Point A,B,C,D;
};

我需要编写一个梯形函数,它接收一个 struct Trapezoid 类型的数组、数组 n 的大小以及两个 double 类型的空数组,我们假设它们足够大以容纳所有所需的元素。接收到的梯形的周长应输入到作为第三个参数给出的数组中,其面积作为第四个参数输入。我已经编写了有效的代码,但有一种情况无效。

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

struct Point {
    double x;
    double y;
};

struct Trapezoid {
    struct Point A, B, C, D;
};

double distance(struct Point p1, struct Point p2) {
    double dx = p2.x - p1.x;
    double dy = p2.y - p1.y;
    return sqrt(dx * dx + dy * dy);
}

void trapezoids(struct Trapezoid trapezoids[], int n, double perimeters[], double areas[]) {
    for (int i = 0; i < n; i++) {
        double side1 = distance(trapezoids[i].A, trapezoids[i].B);
        double side2 = distance(trapezoids[i].B, trapezoids[i].C);
        double side3 = distance(trapezoids[i].C, trapezoids[i].D);
        double side4 = distance(trapezoids[i].D, trapezoids[i].A);

        perimeters[i] = side1 + side2 + side3 + side4;

        double baseAvg = (side1 + side3) / 2;
        double height = distance(trapezoids[i].B, trapezoids[i].D);

        double rotation_angle_rad = atan2(trapezoids[i].B.y - trapezoids[i].D.y, trapezoids[i].B.x - trapezoids[i].D.x);
        double rotation_angle_deg = rotation_angle_rad * 180 / M_PI;

        // Corrected formula for area with rotation
        areas[i] = 0.5 * (side1 + side3) * height * fabs(sin(rotation_angle_rad));
    }
}

int main() {
    struct Trapezoid array[4];
    double areas[4];
    double perimeters[4];

    for (int i = 0; i < 4; i++) {
        printf("Enter coordinates for trapezoid %d (A B C D): ", i + 1);
        scanf("%lf %lf %lf %lf %lf %lf %lf %lf",
              &array[i].A.x, &array[i].A.y,
              &array[i].B.x, &array[i].B.y,
              &array[i].C.x, &array[i].C.y,
              &array[i].D.x, &array[i].D.y);
    }

    // If input doesn't match, calculate the actual output
    trapezoids(array, 4, perimeters, areas);

    // Print the results
    for (int i = 0; i < 4; i++) {
        printf("%.2f ", perimeters[i]);
    }

    return 0;
}

不起作用的情况:

Result: Wrong result
Test Code:

struct Trapezoid array[] = {
  { {-4,2}, {0.950, 6.950}, {-2.586, 7.657}, {-5.414, 4.828} }, // 45 degrees
  { {-4,2}, {-7.5, 8.062}, {-9.098, 4.830}, {-7.098, 1.366} }, // 120 degrees
  { {-4,2}, {-11, 2}, {-9, -1}, {-5, -1} }, // 180 degrees
  { {-4,2}, {-4, -5}, {-1, -3}, {-1, 1} } // 270 degrees
};
double volumes[4], surfaces[4];
int i;

trapezoids(array, 4, perimeters, areas);
for (i=0; i<4; i++)
  printf("%.2f ", surfaces[i]);

Expected output(s): 16.50 16.50 16.50 16.50
 
Your program printed: 11.67 36.83 16.50 33.00
c structure
1个回答
0
投票

首先OP测试代码存在一些变量名混乱的情况。我想应该是这样的:

int main() {
    struct Trapezoid array[] = {
      { {-4,2}, {0.950, 6.950}, {-2.586, 7.657}, {-5.414, 4.828} }, // 45 degrees
      { {-4,2}, {-7.5, 8.062}, {-9.098, 4.830}, {-7.098, 1.366} }, // 120 degrees
      { {-4,2}, {-11, 2}, {-9, -1}, {-5, -1} }, // 180 degrees
      { {-4,2}, {-4, -5}, {-1, -3}, {-1, 1} } // 270 degrees
    };

    double areas[4];
    double perimeters[4];
    trapezoids(array, 4, perimeters, areas);

    printf("Areas: ");
    for (int i = 0; i < 4; i++) {
        printf("%.2f ", areas[i]);
    }
    printf("\n");

    printf("Perimeters: ");
    for (int i = 0; i < 4; i++) {
        printf("%.2f ", perimeters[i]);
    }
    printf("\n");
}

其次,OP代码中计算梯形面积的方法不必要地复杂并且给出错误的结果。我还没有分析其根本原因,因为存在一种更简单的方法,我建议使用它。

面积计算可以使用所谓的鞋带公式来完成。通过“行列式”,可以使用以下辅助函数:

double determinant(struct Point p1, struct Point p2)
{
    return (p1.x * p2.y - p2.x * p1.y);
}

这样,面积可以计算如下:

        double det1 = determinant(trapezoids[i].A, trapezoids[i].B);
        double det2 = determinant(trapezoids[i].B, trapezoids[i].C);
        double det3 = determinant(trapezoids[i].C, trapezoids[i].D);
        double det4 = determinant(trapezoids[i].D, trapezoids[i].A);
        areas[i] = 0.5 * fabs(det1 + det2 + det3 + det4);

通过OP的测试用例,给出了正确的结果:

Areas: 16.50 16.50 16.50 16.50 
Perimeters: 17.77 17.77 17.77 17.77 
© www.soinside.com 2019 - 2024. All rights reserved.