2014-10-20 65 views
0

我很抱歉,我应该知道这一点。我在SVG 2d坐标系统上有2个点。我需要获得学位(0-360),现在我可以返回0-180回0,0-180没有负号或正号...我可以找到密切的问题,但没有任何结果为0 -360。如何在SVG坐标系中找到3 x/y点的旋转度

这是在JavaScript代码:

// 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); 

回答

0

的解决方案是这样,但任何“数学小子”或加仑很可能将能够简化一些这方面,我觉得我是在复杂的,但我得到我需要的可靠。如果你简化它,请提供一些解释。

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面向东/右,它面朝上/北,所以有了这些附加信息(以及它被签名[+ - ])我可以推导出原始数字所在的象限(无符号0-180),并且我可以通过从360减去该点是否位于顶部或左下方象限中来修正度变量。

夸张,是的,功能是,优雅,notta。标记为回答不为别人占用资源,但更合理的解释将受到欢迎。

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; 
}, 
1
  1. acos,asin

    • 是4象限
    • ,但不是在整个范围内
    • 精确,很少有其他的问题,他们一样需要夹紧的...
  2. atan(dy/dx)

    • 只有2象限
    • 是因为atan(dy/dx)松动的原dx,dy
  3. 4象限atan(dy/dx) = atan2(dy,dx)atanxy(dx,dy)

    符号
    • 它只是atan与++

atanxy

DX的一些迹象,DY决策表来处理所有象限
  • 这里是我用C atanxy