通过求交点的方式显示其他玩家所在的方位,并在屏幕边缘显示方位指示
1、已知两个点,求直线方程的a,b值:
a*x1+b=y1
a*x2+b=y2
a*x2+y1-a*x1=y2
a,b的值:
a=(y2-y1)/(x2-x1)
b=y1-(y2-y1)/(x2-x1)*x1
需要注意两个点x坐标相等的情况。
如果两个点x坐标相等,则该直线与y轴平行。
如果两个点y坐标相等,则该直线与x轴平行。
如果两个点x,y坐标都相等,则不是线,是同一个点。
2、已知两条直线,求交点:
a1*x+b1=y
a2*x+b2=y
a1*x+b1=a2*x+b2
交点坐标:
x=(b2-b1)/(a1-a2)
y=(b2-b1)/(a1-a2)*a1+b1
需要注意a1和a2相等的情况。
如果a1和a2相等,b1和b2不相等,则两条直线平行,无交点。
如果a1和a2相等,b1和b2相等,则两条直线是同一条线,无交点。
如果a1和a2不相等,b1和b2相等,则两条直线不平行,有交点,相交于y轴b1点或b2点。
如果a1和a2不相等,b1和b2不相等,则两条直线不平行,有交点。
3、已知两条线段的端点,求这两条线段的交点:
通过(1)求得端点所在的直线的方程;
通过(2)求得这两条直线的交点。
这里需要判断下交点是落在线段内,还是线段外(虚交点)。
如果交点x坐标小于线段1的左侧端点的x坐标,或者交点y坐标大于线段1的右侧端点的y坐标,则该交点落在线段1外,即线段的延长线上,是个虚交点。反之,是线段1的正常交点。
以上知识可应用场景:
场景1–游戏里,求玩家1相对于玩家2所在的方位,如果是在屏幕外,则在屏幕边缘显示玩家1的方位指示图标。
解决思路:
首先,玩家2是一定在屏幕内的,这里需要判断玩家1是不是在屏幕内。
如果是在屏幕内,则无需后面的处理。
如果是在屏幕外,让我们继续下面的处理。
把玩家1和玩家2的世界坐标转换成屏幕坐标系里的坐标,分别记作s1和s2。
(注意:这里有个容易钻进去的误区,就是很容易想到去计算方向向量,即s1-s2。计算完之后又会自然而然的想着用这个向量去处理上面的问题,最后会发现,自己已经进入了一个深坑里,深深的把自己的思维给圈住了,即使偶尔换个方向思考,比如求交点的方式,还是容易被这个向量给迷惑,总想着去用这个向量去解决,尽管这个向量没啥卵用。)
这时,只需要求得线段s1-s2与屏幕的四个边框线段的交点即可,交点也必须同时落在相交的两个线段内。
在Unity中,屏幕坐标系的原点是在左上角,向右是x轴正方向,向下是y轴正方向。
所以s1和s2的坐标也是相对于左上角的位置。
屏幕的四个边框线段分别是:
(注意:只需要确保端点坐标位于线段上即可,无需关注线段的方向,别又被分心了)
左边框线段:(0,0)-(0,屏幕高度)
下边框线段:(0,屏幕高度)-(屏幕宽度,屏幕高度)
右边框线段:(屏幕宽度,0)-(屏幕宽度,屏幕高度)
上边框线段:(0,0)-(屏幕宽度,0)
有了4个边框线段,通过上面的知识,即可求得线段s1-s2与4个边框的交点。因为玩家2在屏幕内,所以玩家2的屏幕坐标s2也一定是在4个边框的内部,线段s1-s2必定与某一个边框有且只有一个交点(一定不会有虚交点)。求得的交点坐标也是相对于左上角原点的坐标。
获得交点后,我们需要在屏幕的该交点位置显示玩家1所在的方位的指示器UI。
假设在Unity中,我们使用Canvas+Image来显示,此时我们需要把Image放到交点位置。
这个地方也很关键,需要注意,不能直接把交点的坐标赋值给Image的transform的position。
要仔细查看Image的锚点设置,通过使用Image的RectTransform组件的anchoredPosition属性来设置Image的位置。
假设Image的锚点是在中心,下面分别求出线段s1-s2与4个边框相交时anchoredPosition属性的值:
与左边框相交时:
anchoredPosition=new Vector2(-屏幕宽度/2+Image宽度/2,屏幕高度/2-交点y坐标);
与下边框相交时:
anchoredPosition=new Vector2(交点x坐标-屏幕宽度/2,-屏幕高度/2+Image宽高/2);
与右边框相交时:
anchoredPosition=new Vector2(屏幕宽度/2-Image宽度/2,屏幕高度/2-交点y坐标);
与上边框相交时:
anchoredPosition=new Vector2(交点x坐标-屏幕宽度/2,屏幕高度/2-Image宽高/2)。
(注意,加减Image宽度(高度)/2,是为了使Image完全显示在屏幕内。)