Gro*_*ler 8 javascript geometry angle
我想获得 360 度的角度......对于我的游戏,我需要知道玩家正朝着哪个方向前进......

此处的代码获得正确的角度,但仅以 90 度为增量:(意思是,当我单击左上象限时,我得到的角度为 0 到 90 度……左下角为 0 到 -90 度,等等。 ..)

var dY = this.pos.y-e.gameY; //opposite
var dX = this.pos.x-e.gameX; //adjacent
var dist = Math.sqrt((dY*dY)+(dX*dX)); //hypotenuse
var sin = dY/dist; //opposite over hypotenuse
var radians = Math.asin(sin);
var degrees = radians*(180/Math.PI); //convert from radians to degrees
this.calculatedAngle = degrees;
Run Code Online (Sandbox Code Playgroud)
我怎样才能得到它的 360 度?
这是另一个示例:前两个代表问题...当我单击左上/左下象限时,它一直在从 x 轴绘制一个直角三角形...
我需要它像下面的 2 张图片一样,它一直在绘制角度:

您可以直接从坐标执行此操作,而无需计算斜边等额外信息,只需使用该atan2函数即可,该函数是在 FORTRAN 早期为与您的情况完全相同的情况而设计的。
注意两个重要的事情:
atan2已创建该函数以自动处理除多种可能情况中的一种情况之外的所有情况,以及(-PI, PI]。两个坐标都是 (0, 0) 的情况未定义(当矢量的幅度为零时所有角度都等效),因此在这种情况下我任意将角度设置为零度。并且为了获得所需的范围,需要一些简单的逻辑和加法。
var Vx = this.pos.x - e.gameX;
var Vy = this.pos.y - e.gameY;
var radians;
if (Vx || Vy) {
radians = Math.atan2(Vy, Vx);
} else {
radians = 0;
}
if (radians < 0) {
radians += 2*Math.PI;
}
var degrees = radians * 180 / Math.PI;
this.calculatedAngle = degrees;
Run Code Online (Sandbox Code Playgroud)
结果将是为所有情况定义的角度,并且根据需要在 [0, 360°) 范围内。
var Vx = this.pos.x - e.gameX;
var Vy = this.pos.y - e.gameY;
var radians;
if (Vx || Vy) {
radians = Math.atan2(Vy, Vx);
} else {
radians = 0;
}
if (radians < 0) {
radians += 2*Math.PI;
}
var degrees = radians * 180 / Math.PI;
this.calculatedAngle = degrees;
Run Code Online (Sandbox Code Playgroud)
function showDegrees(e, svg) {
var rectangle = svg.getBoundingClientRect();
var targetX = (rectangle.left + rectangle.right)/2;
var targetY = (rectangle.top + rectangle.bottom)/2;
var Vx = Math.round(e.clientX - targetX);
var Vy = Math.round(targetY - e.clientY);
var radians = Math.atan2(Vy, Vx);
if (radians < 0) radians += 2*Math.PI;
var degrees = Math.round(radians*180/Math.PI);
var textBox = document.getElementById('showdegrees');
textBox.innerHTML = degrees + '°' + ' (' + Vx + ', ' + Vy + ')';
textBox.setAttribute('x', Math.round(100 + Vx));
textBox.setAttribute('y', Math.round(100 - Vy));
}Run Code Online (Sandbox Code Playgroud)
尝试这个:
var dY = this.pos.y - e.gameY, // opposite
dX = this.pos.x - e.gameX, // adjacent
radians = Math.atan(dY/dX); // wrong, in [-1/2 pi, 1/2 pi]
if(1/dX < 0) radians += Math.PI; // fixed, in [-1/2 pi, 3/2 pi]
if(1/radians < 0) radians += 2*Math.PI; // fixed, in [+0, 2 pi]
var degrees = radians*180/Math.PI; // from radians to degrees
Run Code Online (Sandbox Code Playgroud)
解释:
Math.atan和正切。使用计算斜边的Math.sqrt成本很高。Math.atan-1/2 pi给出和之间的角度1/2 pi,即右半圆. 为了解决这个问题,只需求pi和以防dX出现负数。-1/2 pi然后我们得到和之间的角度3/2 pi。因此,如果它是负数,我们求和2 pi以获得0和之间的角度2 pi。-0负面因素才能使其正常工作。因此,我们不检查dX < 0和radians < 0,而是检查它们的逆。NaN请注意,如果dX和dY都是0(或) ,则最终结果将是-0。您需要使用比反正弦更多的信息来解决这个问题。原因是 arcsin 只会返回 -\xcf\x80/2 和 \xcf\x80/2 (-90 度和 90 度)之间的值,正如您所知。
\n\n因此,要弄清楚另一部分,您需要了解自己处于哪个象限。
\n\n
在象限 2 中,反正弦在 90 到 0 之间,实际角度在 90 到 180 之间。因此,如果您在象限 2 中,则 180- calculated angle= real angle。(180-90=90, 180-0=180)。
在象限 3 中,反正弦在 0 到 -90 之间。实际角度在 180 到 270 之间。同样,180- calculated angle= real angle。(180-0=180, 180-(-90)=270)。
在象限 4 中,反正弦在 -90 到 0 之间。实际角度在 270 到 360 之间。因此 360+ calculated angle= real angle。(360+(-90)=270, 360+0)=360)。
对于象限 1 也是如此,只是不需要进行转换。( 0+360=360 (equivalent to 0), 90+360=450 (equivalent to 90) ).
因此,首先确定象限,然后应用基于该象限的规则。\n对于 (x,y) 坐标,如果 x 为正且 y 为正,则位于象限 1。如果 x 为负且 y 为正,则位于象限 2。如果 x 为负且 y 为负,则位于象限3. 如果 x 为正且 y 为负,则您位于象限 4。
\n\n所以在你的情况下,距原点的距离是你的(dX,dY)坐标对,所以像这样的事情应该做到这一点:
//your original code...\nvar degrees = radians*(180/Math.PI); //convert from radians to degrees\n\n//then\n\n\nif (dX>=0 and dY>=0)\n{//quadrant 1\n//no transformation, do nothing\n}\nif (dX>=0 and dy<0) \n{ //quadrant 4\ndegrees=360+degrees;\n}\nif (dX<0 and dy<0) \n{ //quadrant 3\ndegrees=180-degrees;\n}\nif (dX<0 and dy>0) \n{ //quadrant 2\ndegrees=180-degrees;\n}\n\n\nthis.calculatedAngle = degrees;\nRun Code Online (Sandbox Code Playgroud)\n
| 归档时间: |
|
| 查看次数: |
10661 次 |
| 最近记录: |