给出了结构:
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
首先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