javascript 求两点间夹角的最快方法
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12903547/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Fastest way to find the angle between two points
提问by Timothy Eckstein
To increase the speed at which I find the sine/cosine of an angle, I have built a reference table instead of calculating them on the fly. I have the same idea with finding the angle from one point to another.
为了提高我找到角度的正弦/余弦的速度,我建立了一个参考表,而不是即时计算它们。我对找到从一个点到另一个点的角度有同样的想法。
I have created a table of 3600 normalized vectors (3600 / 10 = accuracy of one tenth of a degree). Whenever I need to know the angle from one point to the next, I look through the table to find the best match. However, I am concerned that this might be slower than using math.atan2().
我创建了一个包含 3600 个归一化向量的表(3600 / 10 = 十分之一度的精度)。每当我需要知道从一个点到另一个点的角度时,我都会查看表格以找到最佳匹配。但是,我担心这可能比使用 math.atan2() 慢。
Here is the code I am using:
这是我正在使用的代码:
Create the vector table:
创建向量表:
// vector to angle table
var vectorToAngleTable = new Array();
for (i = 0; i < 3600; i += 1) {
vectorToAngleTable[i] = new Vector2();
vectorToAngleTable[i] = RotatePoint(forwardVector, i / 10);
}
Find the angle from two points:
从两点求角度:
function NormalizeVector(vector) {
var toReturn = vector;
var dist = Math.sqrt(vector.x * vector.x + vector.y * vector.y);
toReturn.x /= dist.x;
toReturn.y /= dist.y;
return toReturn;
}
function PointDirection(position, target) {
var vector = target;
var toReturn = 0;
var smallest = 1.0;
vector.x -= position.x;
vector.y -= position.y;
vector = NormalizeVector(vector);
for (i = 0; i < 3600; i += 1) {
if (PointDistance(vectorToAngleTable[i], vector) < smallest) {
smalllest = PointDistance(vectorToAngleTable[i], vector);
toReturn = i;
}
}
return toReturn;
}
function PointDistance(point1, point2) {
return Math.sqrt(((point2.x - point1.x) * (point2.x - point1.x)) + ((point2.y - point1.y) * (point2.y - point1.y)));
}
As you can see, my concern is all the lines of code it is going through, and how many entries there are on the table that it looks through. I would love to know the fastest way to find the angle, no matter what the method is.
正如您所看到的,我关心的是它经过的所有代码行,以及它查看的表上有多少条目。我很想知道找到角度的最快方法,无论使用什么方法。
回答by Paul S.
As angle(v1, v2) = acos( (v1x * v2x + v1y * v2y) / (sqrt(v1x^2+v1y^2) * sqrt(v2x^2+v2y^2)) )
and we know v2 = [1, 0]
正如angle(v1, v2) = acos( (v1x * v2x + v1y * v2y) / (sqrt(v1x^2+v1y^2) * sqrt(v2x^2+v2y^2)) )
我们所知v2 = [1, 0]
var v = {x: 0, y: 1},
angleRad = Math.acos( v.x / Math.sqrt(v.x*v.x + v.y*v.y) ),
angleDeg = angleRad * 180 / Math.PI;
where v
is the vector [point2.x - point1.x , point2.y - point1.y]
v
向量在哪里[point2.x - point1.x , point2.y - point1.y]
Edit - I just realised you may have meant treat each point as a vector, in which case it'd be
编辑 - 我刚刚意识到你可能想把每个点都当作一个向量,在这种情况下它会是
var v1 = {x: 0, y: 1}, v2 = {x: 1, y: 0},
angleRad = Math.acos( (v1.x * v2.x + v1.y * v2.y) / ( Math.sqrt(v1.x*v1.x + v1.y*v1.y) * Math.sqrt(v2.x*v2.x + v2.y*v2.y) ) ),
angleDeg = angleRad * 180 / Math.PI;
where v1
is the vector [point1.x , point1.y]
and v2
is [point2.x , point2.y]
哪里v1
是向量[point1.x , point1.y]
,v2
是[point2.x , point2.y]
Edit 2
To speed up if you're using the vectors length many times, save it as e.g. v.length = ...
so you can get it without re-calculating again.
If you know every vector will need it's angles calculated multiple times, use the first method I wrote and cache it, i.e. v.angle = ...
. You can then you can do v2.angle - v1.angle
to find angle between the two, etc.
i.e. have
编辑 2
如果您多次使用向量长度,要加快速度,请将其另存为 eg,v.length = ...
以便您无需再次重新计算即可获得它。如果您知道每个向量都需要多次计算其角度,请使用我编写的第一种方法并将其缓存,即v.angle = ...
. 然后你可以v2.angle - v1.angle
找到两者之间的角度等,
即有
function Vector(x, y){
this.x = x;
this.y = y;
this.length = Math.sqrt(x*x + y*y);
this.angle = Math.acos( x / this.length );
}
jsperfof pre-computing and finding in an array of 3601
items vs using acosdirectly
回答by Tommy
That's definitely going to be smaller than a call to atan2
, since it's a square root and then a linear search through 3600 possibilities. Conversely many processors implement atan2 directly — it's FPATAN in Intel land.
这肯定会比调用 小atan2
,因为它是一个平方根,然后是对 3600 种可能性的线性搜索。相反,许多处理器直接实现 atan2——它是英特尔领域的 FPATAN。