利用MatLab解决桌球射击方位角问题 有2个球置于矩形板之上,一个用来做射击球,另一个则是作为目标图,现在考虑的问题是,如何设置射击球的方向,从而撞击目标球,使之进入矩形板的四个角点。可以利用矩形边的反弹,忽略摩擦。 这个问题其实就是桌球射击的理想化的简化版。由于没有摩擦,所以碰撞之后,目标球的行进方向将沿着射击球球心到目标球的球心的射线方向,并且由于没有摩擦,将不需要考虑速度这个概念。简化起见,规定目标球不经过矩形边的反弹直接进洞,而射击球最多只能利用矩形边的反弹1次,我不太了解桌球上的规则如何,但我想这种简化大约也符合普通桌球玩家考虑的瞄准原则吧。 以下涉及到的角度都是以平面直线逆时针旋转与之重合所转的角度,我是这样考虑这个问题的,先从射击球考虑,目标球射入矩形板的四个角洞有四个角度,对于每一个角度,射击球都有一个确定的碰撞,即沿着射击球进洞方向的反方向,换句话说在碰撞一刹那,射击球的球心是确定的,射击球包括原位置,与矩形四条边的映射位置共有5个球心与该球心连成一条射线(该射线方向即射击球瞄准方向),然而还有个限制条件,即射击球只能撞击圆心与目标球两条切线所夹的范围,这样就需要5个镜像点与4个撞击点所连的射线是否符合该限制条件,符合的话就是我们可以瞄准的方向了。 主程序 a=input('第一个球的x坐标'); b=input('第一个球的y坐标'); r1=input('第一个球的半径'); c=input('第二个球的x坐标'); d=input('第二个球的y坐标'); r2=input('第二个球的半径'); w=input('矩形宽'); h=input('矩形高'); R=[0 w w 0; 0 0 h h]; for I=1:4 A(I)=lineangle(a,b,R(1,I),R(2,I)); %A存放第一个球到矩形四个角的角度 end Z=mirror(c,d,w,h);%z(2,5)存放了射击球的5个射击点 q=[0]; for I=1:5 [small,big]=fwei(Z(1,I),Z(2,I),a,b,r1+r2); for J=1:4 if (A(J)>=small&&A(J)<=big)||(A(J)-2*pi>=small&&A(J)-2*pi<=big) p=answer(A(J),Z(1,I),Z(2,I),c,d,r1,r2); q=[q,finalanswer(p,I)]; end end end function angle=lineangle(a,b,c,d)%以(a,b)基点,连接2点直线的角度if c-a==0 angle=pi/2;endangle=atan((d-b)/(c-a));if (d-b)/(c-a)<0 if d-b>0 angle=angle+pi; else angle=angle+2*pi; endelse if d-b<0 angle=angle+pi; endendangle=angle+pi;if(angle>2*pi) angle=angle-2*pi;end function [small,big]=fwei(a,b,c,d,r) %点(a,b)做圆(c,d),半径r两条切线所夹的圆心角范围 angle=lineangle(c,d,a,b); long=sqrt((a-c)^2+(b-d)^2); o=acos(r/long); small=angle-o; big=angle+o; function q=finalanswer(p,I) %在第I种边映射下的p角还原 if I==1 q=p; else if (I==2)|(I==4) q=-p+2*pi; else if (I==3)|(I==5) q=pi-p; end end end function p=answer(o,a,b,c,d,r1,r2) c=c+(r1+r2)*cos(o); d=d+(r1+r2)*sin(o); p=lineangle(a,b,c,d); function zs=mirror(a,b,w,h) %点(a,b)关于长w,宽h的矩形四条边的映射 zs(:,1)=[a;b]; X=[a -a a 2*w-a]; Y=[-b b 2*h-b b]; for I=2:5 zs(:,I)=[X(I-1);Y(I-1)]; end

评论