An Easy Physics Problem

先贴一下代码:

/************************************************
┆  ┏┓   ┏┓ ┆
┆┏┛┻━━━┛┻┓ ┆
┆┃       ┃ ┆
┆┃   ━   ┃ ┆
┆┃ ┳┛ ┗┳ ┃ ┆
┆┃       ┃ ┆
┆┃   ┻   ┃ ┆
┆┗━┓    ┏━┛ ┆
┆  ┃    ┃  ┆      
┆  ┃    ┗━━━┓ ┆
┆  ┃  AC代马   ┣┓┆
┆  ┃           ┏┛┆
┆  ┗┓┓┏━┳┓┏┛ ┆
┆   ┃┫┫ ┃┫┫ ┆
┆   ┗┻  ┛ ┗┻┛ ┆
************************************************ */
#pragma warning (disable:4996)
#include<iostream>
#include<algorithm>
#include<string>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<string>
#include<queue>
#include<set>
#include<map>
//#include<regex>
#include<stack>
#include<cstdlib>
#include<functional>
using namespace std;
typedef   long long ll;
#define INF 0x3f3f3f3f
const int Maxn = 2e5 + 10;
const int N = 100010;
double eps = 1e-4;
int hit(double ox,double oy ,double r,double ax,double ay,double vx,double vy,double &t)
{
	double a=vx*vx+vy*vy;
	double b=2*ax*vx-2*vx*ox+2*ay*vy-2*vy*oy;
	double c=ax*ax+ox*ox-2*ax*ox+ay*ay+oy*oy-2*ay*oy-r*r;
	double tmp=b*b-4*a*c;
	if(tmp<=0) return 0;
	double t1=(sqrt(tmp)-b)/(2*a),t2=-1.0*(sqrt(tmp)+b)/(2*a);
	if(t1<=0 && t2<=0) return 0;
	t=min(t1,t2);
	return 1;
}
int main()
{
	int t;
	scanf("%d",&t);
	for(int cas=1;cas<=t;cas++){
		double ox,oy,r,ax,ay,vx,vy,bx,by;
		scanf("%lf%lf%lf%lf%lf%lf%lf%lf%lf",&ox,&oy,&r,&ax,&ay,&vx,&vy,&bx,&by);
		double pt;
		if(!hit(ox,oy,r,ax,ay,vx,vy,pt)){
			double t0;
			if(vx!=0){
				t0=(bx-ax)/vx;
			}
			else{
				t0=(by-ay)/vy;
			}
			if(fabs(bx-ax-vx*t0)<eps && fabs(by-ay-vy*t0)<eps){
				printf("Case #%d: Yes\n",cas);
			}
			else{
				printf("Case #%d: No\n",cas);
			}
		}
		else{
			double t0;
			if(vx!=0){
				t0=(bx-ax)/vx;
			}
			else{
				t0=(by-ay)/vy;
			}
			if(fabs(bx-ax-vx*t0)<eps && fabs(by-ay-vy*t0)<eps && t0>=0 && t0<=pt){
				printf("Case #%d: Yes\n",cas);
				continue;
			}
			double x1=ax+vx*pt,y1=ay+vy*pt;
			double x2=ox,y2=oy;
			double a=y2-y1,b=x1-x2,c=y1*x2-x1*y2;
			double px1=ax,py1=ay;
			double px2=((b*b-a*a)*px1-2*a*b*py1-2*a*c)/(a*a+b*b);
			double py2=((a*a-b*b)*py1-2*a*b*px1-2*b*c)/(a*a+b*b);
			double vx2=(px2-x1)/t,vy2=(py2-y1)/t;
			if(vx2!=0){
				t0=(bx-x1)/vx2;
			}
			else{
				t0=(by-y1)/vy2;
			}
			if(t0>=0 && fabs(bx-x1-vx2*t0)<eps && fabs(by-y1-vy2*t0)<eps){
				printf("Case #%d: Yes\n",cas);
			}
			else{
				printf("Case #%d: No\n",cas);
			//	printf("%.2f %.2f\n",x1,y1);
			//	printf("%.2f %.2f\n",vx2,vy2);
			}
		}
	}
	return 0;
}

首先分成和圆碰撞和不与圆碰撞两种情况:
1.点A和圆不碰撞,这个很好判断
在这里插入图片描述
上面是射线的轨迹方程,下面是圆的轨迹方程,合并,求解t,若t无解或仅有一个解(即bb-4a*c<=0),直接判断B是否在A的轨迹上
2.若A的轨迹和圆有两个交点,B可以在A去碰撞圆的轨迹上,也可以在A碰撞完圆后的轨迹上。碰撞圆的轨迹上很好判断。下面说说B在碰撞后的轨迹上的求法,求出碰撞点,过碰撞点和圆心作直线L,求起始点关于直线L的对称点(px,py),有了碰撞点、起始点,还有对称点(px,py),不难求碰撞后的轨迹方程。
两点式:(y-y2)/(y1-y2) = (x-x2)/(x1-x2)得出直线L
对称点公式:在这里插入图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
easyswoole是一个基于Swoole扩展的PHP框架,它提供了一种简单且高效的方式来构建WebSocket应用程序。WebSocket是一种在Web浏览器和服务器之间进行全双工通信的协议,它允许服务器主动向客户端推送数据,而不需要客户端发起请求。 使用easyswoole可以轻松地创建和管理WebSocket服务器,并处理来自客户端的连接、消息和事件。下面是一个简单的示例代码,演示了如何使用easyswoole创建一个WebSocket服务器: ```php <?php use EasySwoole\EasySwoole\ServerManager; use EasySwoole\EasySwoole\Swoole\EventRegister; use EasySwoole\EasySwoole\AbstractInterface\Event; use Swoole\WebSocket\Frame; use Swoole\WebSocket\Server; // 注册WebSocket事件回调 Event::getInstance()->set(EventRegister::onMessage, function (Server $server, Frame $frame) { // 处理收到的消息 $data = $frame->data; // TODO: 处理消息逻辑 // 向客户端发送消息 $server->push($frame->fd, 'Hello, client!'); }); // 创建WebSocket服务器 $server = ServerManager::getInstance()->getSwooleServer(); $server->on('WorkerStart', function () { echo "WebSocket server started\n"; }); // 启动服务器 EasySwoole\EasySwoole\Core::getInstance()->initialize(); ``` 上述代码中,我们首先注册了一个`onMessage`事件回调函数,用于处理收到的消息。在这个示例中,我们简单地向客户端发送了一条回复消息。然后,我们创建了一个WebSocket服务器,并在`WorkerStart`事件回调中输出了一条启动消息。最后,我们使用`EasySwoole\EasySwoole\Core::getInstance()->initialize()`启动了服务器。 请注意,上述代码只是一个简单的示例,实际应用中可能需要更复杂的逻辑来处理不同的消息和事件。你可以根据自己的需求进行扩展和定制。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

weixin_44508514

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值