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]