JavaScript: 使用 atan2 來繪製 箭頭 和 曲線

来源:http://www.cnblogs.com/f1194361820/archive/2017/09/13/7517474.html
-Advertisement-
Play Games

最近搞Canvas繪圖,知道了JavaScript中提供了atan2(y,x)這樣一個三角函數。乍眼一看,不認識,畢竟在高中時,學過的三角函數有:sin,cos,arcsin,arccos,tan,arctan等,並沒有這個。而工作中又需要用到它,所以這裡就做了個簡單的瞭解。 何時需要用到 atan ...


最近搞Canvas繪圖,知道了JavaScript中提供了atan2(y,x)這樣一個三角函數。乍眼一看,不認識,畢竟在高中時,學過的三角函數有:sin,cos,arcsin,arccos,tan,arctan等,並沒有這個。而工作中又需要用到它,所以這裡就做了個簡單的瞭解。

 

  1. 在坐標系中理解tan 和atan
  2. 為何存在atan2 ?
  3. atan2 應用

 

 

 

在坐標系中理解tan atan

回顧一下三角函數tan

tanθ,用三角函數來表示時,它的值等於sinθ/cosθ,如果將其放到坐標系中,它的的值等價於:dy/dx。在坐標系中,任意兩個點所組成的直線,相對於x軸的斜率就是tanθ = dy /dx,相對於y軸的斜率就是dx/dy ,此時我們用cot來表示;其中,dy 是兩個點的y坐標的差值,dx是兩個點的x坐標的差值。

那麼坐標系內除了y軸,任何一個點(x,y),相對於x軸的斜率就是y-0/x-0,也即是y/x

 

我們將tanθ稱為一條直線相對於x軸的斜率,那麼θ就是相對於x軸的夾角(旋轉角度)了。

tan,是根據角度計算斜率的。那麼反過來 arctan(反正切)自然就認為是根據斜率來計算角度的。

 

為何存在atan2 ?

JavaScript中,提供了兩個arctan函數,一個是atan, 一個是atan2atan就是我們所熟知arctan。其實在很多編程語言中都提供了atan2

那麼atan2又是怎麼回事呢?

 

要知道這個,需要知道arctan的不足之處:

arctan的返回值範圍是(-π/2,  π/2) 不包括, ±π/2,也就是(兩個點組成的直線與x軸夾角是90°)90°是計算不出來的。為啥呢?在計算arctan ( dy/dx)時,如果兩個點(x1,y1),(x2,y2)組成的直線與x軸的夾角呈90°時,dx= x2-x1 = 0 0 是不能作為除數的,所以就無法計算這種情形。

值的範圍也就是計算的角度的範圍在(-π/2,  π/2),從坐標系來看,這個角度的範圍只能是在第14象限,並不能表示出第23象限的角。

 

為了彌補atan的不足,在電腦編程領域,引入了atan2函數,它的計算結果是在(-π,π]。它正好可以覆蓋整個坐標系,包括90°的情形。

 

它的計算過程是怎樣的呢?

關於這個,我從wikipedia上摘取了它的計算過程:

 

 

 

 

atan2的應用

在第一小節中的那張圖中的坐標系,是我們熟知的。在HTMLCanvas中,坐標系並不像我們熟知的坐標系那樣。它是這樣的:

 

x軸正向沿順時針方向,所經過的角度分別是0,π/2, π,3π/22π。

x軸正向沿逆時針方向,所經過的角度分別是0-π/2, -π,-3π/2-2π。

 

 

 

atan2的結果在(-π,π]之間,恰好一周,四個象限全覆蓋。從坐標系來看,順時針方向的值是正值,逆時針方向的值是負的。 

從坐標繫上來看,atan2結果是(0,-π)時就表示,從x軸正向逆時針方向轉最大 π弧度(180角度)。同理,(0,π)表示從x軸正向順時針轉最大π弧度(180角度)。

 

在第1)小節中說了atan可以用來計算平面坐標系內任意兩點的連線與x軸正向之間的夾角。而atan2atan的補充,那麼使用atan2自然就可以來計算平面坐標系內任意兩點的連線與x軸正向之間的夾角了。

 如果兩個點在第一象限內:

 

 

如果兩個點在第四象限內:

如果兩個點在不同的象限內,我們也可以平移來看。

 

 

何時需要使用atan2 ?

 

目前我遇到了兩種情況,是通過atan2來解決的:

1) 在平面坐標系內任意兩個點間畫一條帶有箭頭的直線(可以是單向箭頭,可以是雙向箭頭)。在這個需求中,另外也知道了箭頭的一條邊與直線的夾角和箭頭的長度。

這個需求的難點就是要計算出箭頭的另外兩個點坐標。

2) 在平面坐標系內任意兩個點之間畫一條指定曲率的曲線(arc)。在這個需求中,要計算arc,自然要知道radius, startAngle, endAngle,圓心坐標。可以根據曲率來計算出半徑等,但是難點在計算圓心坐標。

 

這兩個需求的共同特點是:

1)兩個已知的點

2)根據這兩個點和其他的條件去計算一些必須的(畫line,arc等必須的)點坐標。

 

目前我遇到了這兩種需求,都通過atan2來解決的。其他的情況,目前尚且未知,待後續發現時,補充上。

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 前面的話 本文將詳細介紹SVG基本操作API,並使用這些API製作實例效果 基礎API 在javascript中,可以使用一些基本的API來對SVG進行操作 【NS地址】 因為SVG定義在其自身的命令空間下,而不是HTML的命名空間下,可以作為單獨的XML文件存在。所以需要使用自身的NS地址 有兩個 ...
  • 做項目碰到問題:記錄之 問題: 如上圖中“新職”下的紅色線條該如何實現,開始嘗試將新職用一個span包裹起來 這樣實現的效果會長於UI圖中的效果。 解決辦法: 1 可以新設一個span 設置disblay: block, 然後在下方位置上設置長度寬度顏色,在細微調整位置。 2.https://www ...
  • 我們接著上文繼續,本文我們講解兄弟組件的通信,項目結構還是跟上文一樣. 在src/assets目錄下建立文件EventHandler.js,該文件的作用在於給同級組件之間傳遞事件 EventHandler.js代碼: 2,在Components目錄下新建一個組件Brother1.vue 。通過Eve ...
  • 我們在一些網站中可以見到一款網頁編輯器——markdown; 這是一款功能強大的富文本編輯器,之前自己在網頁上使用的時候遇到了一點點的問題,現在跟大家分享下 在我們寫了文章之後是需要將內容保存到資料庫的,如果保存到資料庫中要方便以後需改的話,那麼需要保存成markdown語言,如果保存成html語言 ...
  • 在git命令行下,執行以下命令完成環境的搭建: 1,npm install --global vue-cli 安裝vue命令行工具 2,vue init webpack vue-demo 使用vue命令生成一個webpack項目,項目名稱為vue-demo 3,cd vue-demo 切入項目 4, ...
  • 一,Rest and Spread操作符: 用來聲明任意數量的方法參數也就是“...”操作符 輸出結果: 18 jajj 89 function test (a, b, c) { console.log(a); console.log(b); console.log(c); } var agrs = ...
  • 用JS編寫一個函數,返回數組中重覆出現過的元素,見下麵的代碼: 而數組去重的方法詳見我的另一篇博文-->數組去重 ...
  • 1、對象集合 cells[] 返回包含表格中所有單元格的一個數組 rows[] 返回包含表格中所有行的一個數組 tBodies[] 返回包含表格中所有tbody的一個數組(主包含ty和td) 2、對象屬性 border 設置或返回表格邊框的寬度 caption 對錶格的caption元素的引用 ce ...
一周排行
    -Advertisement-
    Play Games
  • 前言 本文介紹一款使用 C# 與 WPF 開發的音頻播放器,其界面簡潔大方,操作體驗流暢。該播放器支持多種音頻格式(如 MP4、WMA、OGG、FLAC 等),並具備標記、實時歌詞顯示等功能。 另外,還支持換膚及多語言(中英文)切換。核心音頻處理採用 FFmpeg 組件,獲得了廣泛認可,目前 Git ...
  • OAuth2.0授權驗證-gitee授權碼模式 本文主要介紹如何筆者自己是如何使用gitee提供的OAuth2.0協議完成授權驗證並登錄到自己的系統,完整模式如圖 1、創建應用 打開gitee個人中心->第三方應用->創建應用 創建應用後在我的應用界面,查看已創建應用的Client ID和Clien ...
  • 解決了這個問題:《winForm下,fastReport.net 從.net framework 升級到.net5遇到的錯誤“Operation is not supported on this platform.”》 本文內容轉載自:https://www.fcnsoft.com/Home/Sho ...
  • 國內文章 WPF 從裸 Win 32 的 WM_Pointer 消息獲取觸摸點繪製筆跡 https://www.cnblogs.com/lindexi/p/18390983 本文將告訴大家如何在 WPF 裡面,接收裸 Win 32 的 WM_Pointer 消息,從消息裡面獲取觸摸點信息,使用觸摸點 ...
  • 前言 給大家推薦一個專為新零售快消行業打造了一套高效的進銷存管理系統。 系統不僅具備強大的庫存管理功能,還集成了高性能的輕量級 POS 解決方案,確保頁面載入速度極快,提供良好的用戶體驗。 項目介紹 Dorisoy.POS 是一款基於 .NET 7 和 Angular 4 開發的新零售快消進銷存管理 ...
  • ABP CLI常用的代碼分享 一、確保環境配置正確 安裝.NET CLI: ABP CLI是基於.NET Core或.NET 5/6/7等更高版本構建的,因此首先需要在你的開發環境中安裝.NET CLI。這可以通過訪問Microsoft官網下載並安裝相應版本的.NET SDK來實現。 安裝ABP ...
  • 問題 問題是這樣的:第三方的webapi,需要先調用登陸介面獲取Cookie,訪問其它介面時攜帶Cookie信息。 但使用HttpClient類調用登陸介面,返回的Headers中沒有找到Cookie信息。 分析 首先,使用Postman測試該登陸介面,正常返回Cookie信息,說明是HttpCli ...
  • 國內文章 關於.NET在中國為什麼工資低的分析 https://www.cnblogs.com/thinkingmore/p/18406244 .NET在中國開發者的薪資偏低,主要因市場需求、技術棧選擇和企業文化等因素所致。歷史上,.NET曾因微軟的閉源策略發展受限,儘管後來推出了跨平臺的.NET ...
  • 在WPF開發應用中,動畫不僅可以引起用戶的註意與興趣,而且還使軟體更加便於使用。前面幾篇文章講解了畫筆(Brush),形狀(Shape),幾何圖形(Geometry),變換(Transform)等相關內容,今天繼續講解動畫相關內容和知識點,僅供學習分享使用,如有不足之處,還請指正。 ...
  • 什麼是委托? 委托可以說是把一個方法代入另一個方法執行,相當於指向函數的指針;事件就相當於保存委托的數組; 1.實例化委托的方式: 方式1:通過new創建實例: public delegate void ShowDelegate(); 或者 public delegate string ShowDe ...