2014-10-20 75 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