Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/469.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 以未知角度旋转2D矢量,使其方向矢量为[1,0]_Javascript_Math_Geometry - Fatal编程技术网

Javascript 以未知角度旋转2D矢量,使其方向矢量为[1,0]

Javascript 以未知角度旋转2D矢量,使其方向矢量为[1,0],javascript,math,geometry,Javascript,Math,Geometry,我试图围绕原点旋转向量[x,y],这样当旋转完成时,它就位于x轴上。为此,我首先计算[x,y]和[1,0]之间的角度,然后对其应用一个简单的2D。我用的是向量 math.angleBetween = function(A, B) { var x = numeric.dot(A, B) / (numer

我试图围绕原点旋转向量
[x,y]
,这样当旋转完成时,它就位于x轴上。为此,我首先计算
[x,y]
[1,0]
之间的角度,然后对其应用一个简单的2D。我用的是向量

math.angleBetween = function(A, B) {                                                                                               
    var x = numeric.dot(A, B) / (numeric.norm2(A) * numeric.norm2(B));                                                             
    if(Math.abs(x) <= 1) {                                                                                                         
        return Math.acos(x);                                                                                                       
    } else {                                                                                                                       
        throw "Bad input to angleBetween";                                                                                         
    }                                                                                                                              
};

math.alignToX = function(V) {
    var theta = -math.angleBetween([1,0], V);
    var R = [[Math.cos(theta), -Math.sin(theta)],
             [Math.sin(theta), Math.cos(theta)]];
    return numeric.dot(R, V);
};

我做错了什么?

我的问题是如此明显,以至于我无法相信我没有看到它。当我检查
Math.acos
的域时,我根本没有检查范围!当向量超出范围(即
[0,PI]
)时,就会出现问题。以下是我所做的修复:

math.alignToX = function(V) {
    var theta = -math.angleBetween([1,0], V);
    var R = [[Math.cos(theta), -Math.sin(theta)],
             [Math.sin(theta), Math.cos(theta)]];
    var result = numeric.dot(R, V);
    if(Math.abs(result[1]) < ZERO_THRESHOLD) {
        return result;
    } else {
        V = numeric.dot([[-1, 0], [0, -1]], V); // rotate by PI
        theta = -math.angleBetween([1,0], V);
        R = [[Math.cos(theta), -Math.sin(theta)],
             [Math.sin(theta), Math.cos(theta)]];
        result = numeric.dot(R, V);
        if(Math.abs(result[1]) < ZERO_THRESHOLD) {
            return result;
        } else {
            throw "Unable to align " + V; // still don't trust it 100%
        }
    }
};

该结果上的Y坐标明显小于我的零点阈值(1e-10)。我几乎感到很遗憾,我自己解决了它,但我不认为我会这么快,如果我没有张贴在这里。我在检查我的帖子是否有打字错误时看到了这个问题。

我的问题非常明显,我简直不敢相信我竟然没有看到它。当我检查
Math.acos
的域时,我根本没有检查范围!当向量超出范围(即
[0,PI]
)时,就会出现问题。以下是我所做的修复:

math.alignToX = function(V) {
    var theta = -math.angleBetween([1,0], V);
    var R = [[Math.cos(theta), -Math.sin(theta)],
             [Math.sin(theta), Math.cos(theta)]];
    var result = numeric.dot(R, V);
    if(Math.abs(result[1]) < ZERO_THRESHOLD) {
        return result;
    } else {
        V = numeric.dot([[-1, 0], [0, -1]], V); // rotate by PI
        theta = -math.angleBetween([1,0], V);
        R = [[Math.cos(theta), -Math.sin(theta)],
             [Math.sin(theta), Math.cos(theta)]];
        result = numeric.dot(R, V);
        if(Math.abs(result[1]) < ZERO_THRESHOLD) {
            return result;
        } else {
            throw "Unable to align " + V; // still don't trust it 100%
        }
    }
};

该结果上的Y坐标明显小于我的零点阈值(1e-10)。我几乎感到很遗憾,我自己解决了它,但我不认为我会这么快,如果我没有张贴在这里。我在查看我的帖子时发现了这个问题。

如果你旋转的不是向量,那么你需要使用
R
矩阵。但是如果你只需要旋转向量,结果将是
[Math.sqrt(x*x+y*y),0]
如果你旋转的不是向量,那么你需要使用
R
矩阵。但是如果你只需要旋转你的向量,结果将是
[Math.sqrt(x*x+y*y),0]

事实上,构建一个旋转矩阵,将已知的2d向量与[1,0]对齐的任务根本不需要任何三角函数

事实上,如果[xy]是你的向量,s是它的长度(s=Sqrt(x*x+y*y)),那么映射[xy]与[10]对齐的变换(纯旋转,无缩放)就是:

例如,假设向量是[Sqrt(3)/2,1/2]。这是一个单位向量,可以很容易地检查,因此s=1

    [Sqrt(3)/2     1/2   ]
T = [  -1/2     Sqrt(3)/2]
将T乘以我们的向量,我们得到:

    [Sqrt(3)/2     1/2   ][Sqrt(3)/2]   [1]
T = [  -1/2     Sqrt(3)/2][  1/2    ] = [0]
因此,在找到旋转角度(在本例中是Pi/6)并创建旋转矩阵时,您已经回到了开始的位置。[Sqrt(3)/2,1/2]的旋转角度为Pi/2,cos(Pi/2)为Sqrt(3)/2=x,sin(Pi/2)为1/2=y

换句话说,如果你知道向量,你已经知道它与x轴夹角的正弦和余弦,从正弦和余弦的定义:

cos a = x/s
sin a = y/s where s = || [x, y] ||, is the length of the vector.

事实上,构建一个旋转矩阵,将已知2d向量与[1,0]对齐的任务根本不需要任何三角函数

事实上,如果[xy]是你的向量,s是它的长度(s=Sqrt(x*x+y*y)),那么映射[xy]与[10]对齐的变换(纯旋转,无缩放)就是:

例如,假设向量是[Sqrt(3)/2,1/2]。这是一个单位向量,可以很容易地检查,因此s=1

    [Sqrt(3)/2     1/2   ]
T = [  -1/2     Sqrt(3)/2]
将T乘以我们的向量,我们得到:

    [Sqrt(3)/2     1/2   ][Sqrt(3)/2]   [1]
T = [  -1/2     Sqrt(3)/2][  1/2    ] = [0]
因此,在找到旋转角度(在本例中是Pi/6)并创建旋转矩阵时,您已经回到了开始的位置。[Sqrt(3)/2,1/2]的旋转角度为Pi/2,cos(Pi/2)为Sqrt(3)/2=x,sin(Pi/2)为1/2=y

换句话说,如果你知道向量,你已经知道它与x轴夹角的正弦和余弦,从正弦和余弦的定义:

cos a = x/s
sin a = y/s where s = || [x, y] ||, is the length of the vector.

这比我的解决方案好得多。谢谢是的,他需要R来旋转其他点,但不需要计算三角函数来计算R。这比我的解决方案好得多。谢谢是的,他需要R来旋转其他点,但不需要计算三角函数来计算R。非常好。您可能想添加
s=Sqrt(x*x+y*y)
,这样
T=1/(x*x+y*y)*[[x-y][y-x]]
。经过思考,我意识到:如果您将
[x,y]
映射到
[1,0]
,那么您就已经缩放了。所以我们应该有
T=1/s*[[xy][yx]]
@Teepeemm,这就是我在第一稿中的想法,然后我重新阅读OP的问题,发现他想要的是相同的方向,而不是幅度。至少我是这样解释的。你同意吗?我认为OP需要方向为
[1,0]
且大小为
[x,y]
的向量。例如,我认为他给出的第二个例子是他想要的。(从另一个角度来看:既然
T
只作用于
[x,y]
,而不是任何其他点,问“我如何才能使它成为
[1,0]
?”将是一个荒谬的问题。)但我承认,如果
T
应该作用于其他点,那么我会把
[x,y]
变成
[1,0]
这是一个有效的问题。非常好。您可能想添加
s=Sqrt(x*x+y*y)
,这样
T=1/(x*x+y*y)*[[x-y][y-x]]
。经过思考,我意识到:如果您将
[x,y]
映射到
[1,0]
,那么您就已经缩放了。所以我们应该有
T=1/s*[[xy][yx]]
@Teepeemm,这就是我在第一稿中的想法,然后我重新阅读OP的问题,发现他想要的是相同的方向,而不是幅度。至少我是这样解释的。你同意吗?我认为OP需要方向为
[1,0]
且大小为
[x,y]
的向量。例如,我认为他给出的第二个例子是他想要的。(另一种看待它的方式:因为
T
只作用于
[x,y]
而不是任何其他点,问“我怎样才能使它
[1,0]