Javascript 如何在SVG坐标系中从3个x/y点查找旋转度
很抱歉,我应该知道这一点。我在SVG二维坐标系上有2个点。我需要得到度(0-360),现在我能返回的就是0-180回到0,0-180上没有正负号。。。我可以找到相近的问题,但没有一个会导致0-360 以下是javascript中的代码:Javascript 如何在SVG坐标系中从3个x/y点查找旋转度,javascript,math,svg,2d,coordinates,Javascript,Math,Svg,2d,Coordinates,很抱歉,我应该知道这一点。我在SVG二维坐标系上有2个点。我需要得到度(0-360),现在我能返回的就是0-180回到0,0-180上没有正负号。。。我可以找到相近的问题,但没有一个会导致0-360 以下是javascript中的代码: // center point, say 200,200 var rx = that.get("rotateOriginX"); // ember code but substitute 200,200 if you want var ry = th
// center point, say 200,200
var rx = that.get("rotateOriginX"); // ember code but substitute 200,200 if you want
var ry = that.get("rotateOriginY");
// I create third point (directly up on coordinate system)
// 200, 190 - line straight up and down to angle vertex above
var p1x = rx;
var p1y = ry - 10; // this is negative 10 to go up because svg y axis starts in upper left
// mouse position variable, this can be 360 degrees around vertex
var p2x = d3.mouse(this.parentNode.parentNode)[0];
var p2y = d3.mouse(this.parentNode.parentNode)[1];
// I have three points now
var p0c = Math.sqrt(Math.pow(rx-p1x, 2) + Math.pow(ry-p1y, 2));
var p1c = Math.sqrt(Math.pow(rx-p2x, 2) + Math.pow(ry-p2y, 2));
var p0p1 = Math.sqrt(Math.pow(p2x-p1x, 2) + Math.pow(p2y-p1y, 2));
// this always returns 0-180-0 but is not signed (+/-)
// ALL I WANT IS 0-360 so I can rotate a shape to user's preference as determined by mouse
var degrees = (180 * (Math.acos((p1c*p1c+p0c*p0c-p0p1*p0p1)/(2*p1c*p0c))) / Math.PI);
解决办法是这样的,虽然任何一个“数学人”或女孩都可能会简化一些,但我觉得我把它复杂化了,但我得到了我需要的东西。如果你简化它,请提供一些解释 Math.acos返回一个从-180到180的浮点值,零面向右/东(如果视为指南针),0到-180覆盖圆周长的上半部分。0到+180从右向左延伸,覆盖圆的下半部圆周(180为360的一半)。这对于偶尔做一次数学的人来说可能很正常(0向右,逆时针增加数字)。因为我从2个x/y点开始,我知道我希望0面朝上/向北,所以我可以在函数中自动创建第三个点,只需要2个点作为参数 因此,有3个点,一个始终朝上/朝北,在2d平面上,我从Math.acos获得弧度,如上所述。然后我得到Math.atan2的结果,它给了我看起来像弧度的东西(0-180和0--180),但是它不是面向东/右,而是面向上/北,因此通过这个附加信息(以及它被符号[+-]),我可以推导出原始数字所在的象限(无符号的0-180)然后,如果点在左上方象限或左下方象限,我只需通过从360中减去来修正度变量 复杂,是的,功能是的,优雅,不。标记为回答不占用他人资源,但欢迎更合理的解释
findBearingOfTwoPoints: function(p1, p2, forceInt){
var degrees = 0;
try{
var a1 = Math.sqrt(Math.pow(p1.x - p1.x, 2) + Math.pow(p1.y - (p1.y - 10), 2));
var a2 = Math.sqrt(Math.pow(p1.x - p2.x, 2) + Math.pow(p1.y - p2.y, 2));
var a3 = Math.sqrt(Math.pow(p2.x - p1.x, 2) + Math.pow(p2.y - (p1.y - 10), 2));
// this is probably better to be called radians
degrees = (180 * (Math.acos((a2 * a2 + a1 * a1 - a3 * a3)/(2 * a2 * a1))) / Math.PI);
var angle = 0;
var deltaY = p2.y - p1.y;
var deltaX = p2.x - p1.x;
angle = (Math.atan2(deltaY, deltaX) * (180 / Math.PI));
if(angle < -90 || angle > 90){
degrees = 360 - degrees;
}
if(forceInt===true){
degrees = parseInt(degrees);
}
}
catch(e){
//
}
return degrees;
},
findbearingoftwoints:函数(p1、p2、forceInt){
变量度=0;
试一试{
var a1=Math.sqrt(Math.pow(p1.x-p1.x,2)+Math.pow(p1.y-(p1.y-10),2));
vara2=Math.sqrt(Math.pow(p1.x-p2.x,2)+Math.pow(p1.y-p2.y,2));
var a3=Math.sqrt(Math.pow(p2.x-p1.x,2)+Math.pow(p2.y-(p1.y-10),2));
//这可能更适合称为弧度
度=(180*(数学acos((a2*a2+a1*a1-a3*a3)/(2*a2*a1))/Math.PI);
var角=0;
var deltaY=p2.y-p1.y;
增值税=p2.x-p1.x;
角度=(数学atan2(deltaY,deltaX)*(180/数学PI));
如果(角度<-90 | |角度>90){
度=360度;
}
如果(forceInt==真){
度=parseInt(度);
}
}
捕获(e){
//
}
返回度;
},
acos,asin
- 是四象限的
- 但在整个范围内并不精确
- 还有一些其他的问题,比如需要夹紧
atan(dy/dx)
- 只有2象限
- 这是因为
松开了原始atan(dy/dx)
dx,dy的符号
atan(dy/dx)
=atan2(dy,dx)
或atanxy(dx,dy)
- 它只是
,带有一些dx,dy符号的决策表来处理所有象限atan
- 这是我的C++