解题思路:
我这个肯定不是最优解,大家看看就行。其实需要注意的就是圆和矩形相切的问题以及碰撞之前圆心的运动轨迹和碰撞之后的圆心的运动轨迹是互相垂直的就行了。
注意事项:注意角度是要转换到PI上,in_3.slope * acos(-1) / 180; //求出真正的斜率。第二个是Pi的定义,这个我是看了别人的答案才知道的。
参考代码:
#include<stdint.h>
#include<stdio.h>
#include<math.h>
#include<stdbool.h>
#define pi 3.1415 // 精度不够,会导致答案错误
struct Rectangle {
int Length; //矩形的长
int width; //矩形的宽
};
struct Circle {
double x; //圆心的X轴坐标
double y; //圆心的Y轴坐标
int r; //圆的半径
};
struct Line {
double slope; //直线的斜率
int velocity; //点运行的速度
int time; //点运行的时间
};
bool CheckCircleTangent(struct Rectangle in_1, struct Circle* in_2);
void Calculate(struct Rectangle in_1, struct Circle in_2, struct Line in_3);
int main(void) {
struct Rectangle rectangel = {0};
struct Circle circle = {0};
struct Line line = {0};
(scanf("%d%d%lf%lf%d%lf%d%d", &rectangel.Length, &rectangel.width, &circle.x, &circle.y
, &circle.r, &line.slope, &line.velocity, &line.time));
{
Calculate(rectangel, circle, line);
}
return 0;
}
void Calculate(struct Rectangle in_1, struct Circle in_2, struct Line in_3) {
int Line_slop = 0; //撞击到墙壁
double RealSlope = in_3.slope * acos(-1) / 180; //求出真正的斜率
while (in_3.time != 0) { //时间没有运行完
//圆心进行移动
switch ((int)in_3.slope) {
case 0: //Y轴不动
if (Line_slop == 0) {
in_2.x += in_3.velocity;
} else {
in_2.x -= in_3.velocity;
}
break;
case 180: //Y轴不动
if (Line_slop != 0) {
in_2.x += in_3.velocity;
} else {
in_2.x -= in_3.velocity;
}
break;
case 90: //X轴不动
if (Line_slop == 0) {
in_2.y += in_3.velocity;
} else {
in_2.y -= in_3.velocity;
}
break;
case 270: //X轴不动
if (Line_slop != 0) {
in_2.y += in_3.velocity;
} else {
in_2.y -= in_3.velocity;
}
break;
default:
if (Line_slop == 1) {
in_2.x += in_3.velocity * sin(RealSlope);
in_2.y += in_3.velocity * cos(RealSlope);
} else {
in_2.x += in_3.velocity * cos(RealSlope);
in_2.y += in_3.velocity * sin(RealSlope);
}
break;
}
if (CheckCircleTangent(in_1, &in_2)) { //球已经撞到矩形的四条边中的其中一条边
//更新直线的斜率
if (Line_slop != 1) {
Line_slop = 1;
} else {
Line_slop = 0;
}
}
in_3.time--;
printf("%0.2lf %0.2lf\n", in_2.x, in_2.y);
}
printf("%0.2lf %0.2lf\n", in_2.x, in_2.y);
}
bool CheckCircleTangent(struct Rectangle in_1, struct Circle* in_2) {
bool flag = false;
if ((in_1.width - in_2->r <= in_2->y || in_2->y <= in_2->r)
|| (in_1.Length - in_2->r <= in_2->x || in_2->x <= in_2->r)) { //矩阵四条边和圆相切
if (in_1.width - in_2->r < in_2->y) {
in_2->y = in_1.width - in_2->r;
} else if (in_2->y < in_2->r) {
in_2->y = in_2->r;
}
if (in_1.Length - in_2->r < in_2->x) {
in_2->x = in_1.Length - in_2->r;
} else if (in_2->x < in_2->r) {
in_2->x = in_2->y;
}
flag = true;
}
return flag;
}
0.0分
0 人评分
C语言网提供由在职研发工程师或ACM蓝桥杯竞赛优秀选手录制的视频教程,并配有习题和答疑,点击了解:
一点编程也不会写的:零基础C语言学练课程
解决困扰你多年的C语言疑难杂症特性的C语言进阶课程
从零到写出一个爬虫的Python编程课程
只会语法写不出代码?手把手带你写100个编程真题的编程百练课程
信息学奥赛或C++选手的 必学C++课程
蓝桥杯ACM、信息学奥赛的必学课程:算法竞赛课入门课程
手把手讲解近五年真题的蓝桥杯辅导课程
发表评论 取消回复