簡體   English   中英

如何在Javascript中找到SVG上兩條直線(路徑)之間的角度?

[英]How to find angle between two straight lines (paths) on a SVG in Javascript?

我在SVG畫布中有兩條直線作為<path> 使用LineA (A1x, A1y) (A2x, A2y)和LineB (B1x, B1y) (B2x, B2y)像素坐標,如何計算這些線之間的角度。

我有以下代碼適用於三個點(它適用於下圖中的綠色案例)。 (A2x, A2y) != (B1x, B1y)時它不起作用。

即使沒有連接線,如何修改此公式也能正常工作。

function find_angle(p0,p1,c) {
var p0c = Math.sqrt(Math.pow(c.x-p0.x,2)+
                    Math.pow(c.y-p0.y,2));  
var p1c = Math.sqrt(Math.pow(c.x-p1.x,2)+
                    Math.pow(c.y-p1.y,2));
var p0p1 = Math.sqrt(Math.pow(p1.x-p0.x,2)+
                     Math.pow(p1.y-p0.y,2));
var angle = Math.acos((p1c*p1c+p0c*p0c-p0p1*p0p1)/(2*p1c*p0c));
return angle * (180 / Math.PI);
}

圖片

您可以利用Math.atan2函數與這些段的交叉乘積和方向向量的點積。 注意atan2返回-Pi...Pi范圍內的有符號角度

//find vector components
var dAx = A2x - A1x;
var dAy = A2y - A1y;
var dBx = B2x - B1x;
var dBy = B2y - B1y;
var angle = Math.atan2(dAx * dBy - dAy * dBx, dAx * dBx + dAy * dBy);
if(angle < 0) {angle = angle * -1;}
var degree_angle = angle * (180 / Math.PI);

你想要P0-CP1-D代替P0-CP1-C :只需翻譯其中一個段讓DC重合: P1' = P1 - D + C (然后D' = C )。

找到兩行之間的角度(@):

tan @ =(m1-m2)/(1 + m1.m2)

其中m1和m2分別是線的梯度。 就JS而言:

var m1 = (A1y-A2y)/(A1x-A2x)
var m2 = (B1y-B2y)/(B1x-B2x)
var angle
if(m1*m2==-1){
    angle = Math.PI/2
}else{
    angle = Math.atan((m1-m2)/(1+m1*m2))
}

在提交我的答案后,我意識到這與@YvesDaoust提供的解決方案相同。 這個答案是一個更簡潔的概念性概述,我在這里用JavaScript示例充實了相同的方法。

答案很簡單:

function find_disconnected_angle(p0,c0, p1,c1) {
  return find_angle({x:p0.x-c0.x+c1.x,y:p0.y-c0.y+c1.y},p1,c1);
}

您可以使用三角函數基礎從頭開始計算角度。 但是,為了讓您的生活更輕松,您也可以使用您已有的功能。 首先,只需在數學上平移一條線,使其一個端點與另一條線的一個端點重合。 有四種不同的方法可以匹配每條線的一個端點,每種方式都會產生一個可能不同的角度測量值。 然而,當你取出每個原始的非翻譯線段,將每個角度延伸到一個無限的線條,並檢查那些角度時,你必須弄清楚你想要的四個角度,這不是一個兩難的難題。兩條線相交。

你需要一個4點作為輸入的函數,即p0,p1,p2和p3。 然而,為了弄清楚哪些點是巧合的,我把它們標記為p0,c0,p1和c1,這樣p0和c0都以這樣的方式移動,使得c0和c1重合,結果三點:p0new,p1和c,后者等於c1和c0new。

更新 :在仔細檢查原始函數后,我意識到我上面討論的四個可能角度的選擇可能與您編寫的確切函數實現無關,因為點p0和p1的順序對您的函數無關緊要。 您可以重寫原始函數,也許使用其他答案中的一些概念,以便能夠更完全地控制您獲得的角度,如果這真的是您想要的。 在任何情況下,我的答案背后的一般概念都有:如果你已經有一個計算3點之間角度的函數(無論算法有什么限制),你可以在兩個斷開的線段上使用相同的函數,只需簡單地翻譯一個兩個端點重合,然后使用相同的功能(同樣,算法仍有任何限制)。

 function find_angle(p0,p1,c) { var p0c = Math.sqrt(Math.pow(cx-p0.x,2)+ Math.pow(cy-p0.y,2)); var p1c = Math.sqrt(Math.pow(cx-p1.x,2)+ Math.pow(cy-p1.y,2)); var p0p1 = Math.sqrt(Math.pow(p1.x-p0.x,2)+ Math.pow(p1.y-p0.y,2)); var angle = Math.acos((p1c*p1c+p0c*p0c-p0p1*p0p1)/(2*p1c*p0c)); return angle * (180 / Math.PI); } function find_disconnected_angle(p0,c0, p1,c1) { return find_angle({x:p0.x-c0.x+c1.x,y:p0.y-c0.y+c1.y},p1,c1); } console.log( find_angle( {x: 7, y: 2}, {x: 7, y: 7}, {x: 2, y: 2} ) ); console.log( find_disconnected_angle( {x: 27, y: 42}, {x: 22, y: 42}, {x: 7, y: 7}, {x: 2, y: 2} ) ); 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM