HDU3471 England vs Germany 计算几何题

本文介绍了一种通过三维空间中的向量运算来判断足球是否进球的方法。具体包括使用点积判断球的速度方向,利用叉乘计算法向量,并通过矢量与面的交点确定球是否进入目标区域。
部署运行你感兴趣的模型镜像
Accepted3471296MS200K

对于速度V的方向有三种情况,可用V与ABCD面法向量的点积判断:
1 V指向ABCD面外侧,或V与ABCD面平行,不可能进球;
2 ball在ABCD面内侧,不可能进球;
3 ball在ABCD面上,当且仅当 P在多边形ABCD内(不包括边界)才进球
4 ball在ABCD面外侧,当且仅当 直线P+xV与ABCD面的交点Q在多边形ABCD内(不包括边界)才进球

代码

   
#include < iostream >
#include
< cmath >
using namespace std;
struct point{
double x,y,z;
point(
double xx = 0 , double yy = 0 , double zz = 0 ){ // 构造函数
x = xx,y = yy,z = zz;
}
point
operator * ( double h){
return point(x * h,y * h,z * h);
}
double operator * (point h){ // 点乘
return this -> x * h.x + this -> y * h.y + this -> z * h.z;
}
point
operator + (point h){
return point(x + h.x,y + h.y,z + h.z);
}
point
operator - (point h){
return point(x - h.x,y - h.y,z - h.z);
}
// 所有class method必须有匹配的左值类型进行调用而friend则无需这样
point friend operator % (point a,point b){ // 叉乘
return point(a.y * b.z - b.y * a.z, a.z * b.x - b.z * a.x, a.x * b.y - b.x * a.y);
}
double len2(){
return x * x + y * y + z * z;
}
double len(){
return sqrt(len2());
}
void in (){
scanf(
" %lf%lf%lf " , & x, & y, & z);
}
void show(){
printf(
" %.2lf %.2lf %.2lf\n " ,x,y,z);
}
}ball,v,a,b,c,d,e,f,g,h;
point dc,da,dh,aim;
// dh是dc和da的叉乘,也就是面abcd向外的法向量;
// aim是球最后飞到的位置,当然设置到无穷远处比较好的。

const double eps = 1e - 4 ;
int sign( double x){
if (fabs(x) < eps) return 0 ;
return x > 0 ? 1 : - 1 ;
}

point intersection(point l1,point l2,point s1,point s2,point s3)
// 矢量与面的交点
{
point ret
= (s3 - s2) % (s1 - s2); // 法向量
double t = ret * (s1 - l1) / (ret * (l2 - l1));
ret.x
= l1.x + (l2.x - l1.x) * t;
ret.y
= l1.y + (l2.y - l1.y) * t;
ret.z
= l1.z + (l2.z - l1.z) * t;
return ret;
}

double area(point a,point b,point c){ // 三个点求面积
return ((b - a) % (c - a)).len() / 2.0 ;
}
bool ok(point pcro){ // 判断点是否位于矩形内
double s1,s2 = 0 ,tmp;
s1
= (b - a).len() * (d - a).len();
s2
= 0 ;
tmp
= area(pcro,a,d);
s2
+= tmp;
if (sign(tmp) == 0 )
return false ;
tmp
= area(pcro,d,c);
s2
+= tmp;
if (sign(tmp) == 0 )
return false ;
tmp
= area(pcro,c,b);
s2
+= tmp;
if (sign(tmp) == 0 )
return false ;
tmp
= area(pcro,b,a);
s2
+= tmp;
if (sign(tmp) == 0 )
return false ;
if (sign(s1 - s2) == 0 )
return true ;
return false ;
}

int main()
{
int cas,ca;
scanf(
" %d " , & cas);
for (ca = 1 ;ca <= cas;ca ++ )
{
ball.
in (); v. in ();
a.
in (); b. in (); c. in (); d. in ();
e.
in (); f. in (); g. in (); h. in ();
dc
= c - d; da = a - d; dh = dc % da; // 以d点作为参考点
aim = ball + v;
printf(
" Case %d: " ,ca);
// 不动球,平行了,或者飞出来的球,球在平面的另一侧,无效
if (sign(v.len() == 0 ) || sign(v * dh) >= 0 || ((ball - d) * dh) < 0 )
{
puts(
" Intelligent Larrionda!!! " );
continue ;
}
point pcro
= intersection(ball,aim,a,b,c);
puts(ok(pcro)
? " Stupid Larrionda!!! " : " Intelligent Larrionda!!! " );
}
return 0 ;
}

两点:

1.c++ operator定义为friend function请看博文http://blog.youkuaiyun.com/frankie110/archive/2009/12/30/5108373.aspx

2.当ball在ABCD面上时,intersection函数中的t等于0。 t代表的是什么?

  t代表的是(ball到平面的距离)与(v在平面法向量上的投影)的比值。

转载于:https://www.cnblogs.com/DreamUp/archive/2010/08/21/1805526.html

您可能感兴趣的与本文相关的镜像

Stable-Diffusion-3.5

Stable-Diffusion-3.5

图片生成
Stable-Diffusion

Stable Diffusion 3.5 (SD 3.5) 是由 Stability AI 推出的新一代文本到图像生成模型,相比 3.0 版本,它提升了图像质量、运行速度和硬件效率

欢迎使用“可调增益放大器 Multisim”设计资源包!本资源专为电子爱好者、学生以及工程师设计,旨在展示如何在著名的电路仿真软件Multisim环境下,实现一个具有创新性的数字控制增益放大器项目。 项目概述 在这个项目中,我们通过巧妙结合模拟电路与数字逻辑,设计出一款独特且实用的放大器。该放大器的特点在于其增益可以被精确调控,并非固定不变。用户可以通过控制键,轻松地改变放大器的增益状态,使其在1到8倍之间平滑切换。每一步增益的变化都直观地通过LED数码管显示出来,为观察和调试提供了极大的便利。 技术特点 数字控制: 使用数字输入来调整模拟放大器的增益,展示了数字信号对模拟电路控制的应用。 动态增益调整: 放大器支持8级增益调节(1x至8x),满足不同应用场景的需求。 可视化的增益指示: 利用LED数码管实时显示当前的放大倍数,增强项目的交互性和实用性。 Multisim仿真环境: 所有设计均在Multisim中完成,确保了设计的仿真准确性和学习的便捷性。 使用指南 软件准备: 确保您的计算机上已安装最新版本的Multisim软件。 打开项目: 导入提供的Multisim项目文件,开始查看或修改设计。 仿真体验: 在仿真模式下测试放大器的功能,观察增益变化及LED显示是否符合预期。 实验与调整: 根据需要调整电路参数以优化性能。 实物搭建 (选做): 参考设计图,在真实硬件上复现实验。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值