C# 确定具有8个离散方向(水平、垂直和对角线)的二维矢量方向
我有一个游戏板的拇指棒,它是一个向量。向量的值范围定义了一个矩形内的圆,该矩形的跨度为-1、-1到+1、+1 我想知道向量接近的8个可能方向中的哪一个。不用担心向量是(0,0)的情况,我将分别处理这个问题我该怎么做? 注意:这是一个游戏,所以这个功能会经常运行。任何加快函数速度的方法都会有所帮助,例如,我知道我可以使用点积和三角来计算向量和每个方向向量之间的角度,但是我想知道如果我不需要精确的角度,是否可以做得更好。sina/cos a=tan a 你有 Y=sina X=cos a 所以,将反切线函数应用于Y/X,就可以得到角度 编辑:在一整圈中,有两个角度具有相同的切线值(C# 确定具有8个离散方向(水平、垂直和对角线)的二维矢量方向,c#,xna,trigonometry,2d-vector,C#,Xna,Trigonometry,2d Vector,我有一个游戏板的拇指棒,它是一个向量。向量的值范围定义了一个矩形内的圆,该矩形的跨度为-1、-1到+1、+1 我想知道向量接近的8个可能方向中的哪一个。不用担心向量是(0,0)的情况,我将分别处理这个问题我该怎么做? 注意:这是一个游戏,所以这个功能会经常运行。任何加快函数速度的方法都会有所帮助,例如,我知道我可以使用点积和三角来计算向量和每个方向向量之间的角度,但是我想知道如果我不需要精确的角度,是否可以做得更好。sina/cos a=tan a 你有 Y=sina X=cos a 所以,将反
a
和a)
+pi
)。使用X和Y的符号来确定哪一个是有效的。您可以使用预先构建的tan^-1近似表。根据输入向量的大小计算角度应该非常快,并且您可能不需要表格中非常大的分辨率(事实上,如果您只需要8个离散方向,表格中的8个条目就足够了)。想象-1..1正方形内的一个正方形,其中斗杆位置(X)位于其中一侧:
+-----------------+ +-----------------+
| | | |
| | | |
| X | | +-----X-+ |
| | | | | |
| O | | | O | |
| | | | | |
| | | +-------+ |
| | | |
| | | |
+-----------------+ +-----------------+
你只需要找出坐标在哪一边,然后检查它是靠近边的中心还是一个角。如果内方块太小,你可以考虑杆为中心。< /P>
比如:
Public enum Direction {
None,
LeftUp, Up, RightUp, Right, RightDown, Down, LeftDown, Left
}
public Direction GetDirection(double x, double y) {
double absX = Math.Abs(x);
double absY = Math.Abs(y);
if (absX < 0.1 && absY < 0.1) {
// close to center
return Direction.None;
}
if (absX > absY) {
// vertical side
double half = absX * 0.4142;
if (x > 0) {
// left side
if (y > half) return Direction.LeftDown;
if (y < -half) return Diretion.LeftUp;
return Direction.Left;
} else {
// right side
if (y > half) return Direction.RightDown;
if (y < -half) return Direction.RightUp;
return Direction.Right;
}
} else {
// horisontal side
double half = absY * 0.4142;
if (y > 0) {
// bottom
if (x > half) return Direction.RightDown;
if (x < -half) return Direction.LeftDown;
return Direction.Down;
} else {
// top
if (x > half) return Direction.RightUp;
if (x < -half) return Direction.LeftUp;
return Direction.Up;
}
}
}
公共枚举方向{
没有一个
左上,上,右上,右,右下,下,左下,左下
}
公共方向(双x,双y){
双absX=数学Abs(x);
双absY=数学Abs(y);
如果(absX<0.1&&absY<0.1){
//靠近中心
返回方向。无;
}
如果(absX>absY){
//垂直面
双半=absX*0.4142;
如果(x>0){
//左侧
如果(y>一半)返回方向。左下;
如果(y<-half)返回Diretion.LeftUp;
返回方向。左;
}否则{
//右侧
如果(y>一半)返回方向。向右向下;
如果(y<-一半)返回方向。向右上;
返回方向。对;
}
}否则{
//水平面
双半=absY*0.4142;
如果(y>0){
//底部
如果(x>一半)返回方向。向右向下;
如果(x<-一半)返回方向为左下;
返回方向。向下;
}否则{
//顶
如果(x>一半)返回方向。向右上;
如果(x<-一半)返回方向为左上;
返回方向。向上;
}
}
}
没有三角学,只是简单的比较,所以应该很快
(虽然我用三角法计算了点0.4142,即tan(22.5),或角度为45/2的一侧的位置。)我想他知道trig,但担心内置函数太慢。@driis:是的,我只会在需要时进行优化。然而,我认为鉴于我的要求,无法获得向量之间的精确角度(只能确定哪一个是最小的),我认为可以使用其他方法。@GeorgeDuckett然后只定义X/Y的“限制”。X/Y