一,點線面常識canvas
1.基本概念segmentfault
2.三角函數:這位大神講得很好,我就不詳細說了 https://segmentfault.com/a/11...
注:之後出現跟他同樣的知識點,我就直接連接過去 (~ ̄▽ ̄)~函數
二,將經常使用的幾何方法封裝成一個對象工具
const Util={ //已知直角三角形一直角條邊的傾斜弧度,求另外一條直角邊的傾斜弧度 getRadPositive:(rad)=>{ return rad+Math.PI*2; }, //兩點相減 getPointBaseOrigin:(p1,p2)=>{ const dx = p2.x - p1.x; const dy = p2.y - p1.y; return {x:dx,y:dy}; }, //根據兩點獲取距離 getDistance:(p1,p2)=>{ const p=Util.getPointBaseOrigin(p1,p2); return Math.sqrt(p.x*p.x + p.y*p.y); }, //根據兩點獲取一點到另外一點的方向 getRadian:(p1,p2)=>{ const p=Util.getPointBaseOrigin(p1,p2); return Math.atan2(p.y,p.x); }, //已知射線起點point 和方向rad,求其發射到某段距離len 時的點位 getPointByVector:(rad,len,point)=>{ return { x:Math.cos(rad)*len+point.x, y:Math.sin(rad)*len+point.y, } }, //取兩點間的中點 getCenterPoint:(p1,p2)=>{ return {x:(p1.x+p2.x)/2,y:(p1.y+p2.y)/2}; }, //根據勾股定理中的銳角和對邊長度,獲取斜邊長度 getCbyRadA:(rad,a)=>{ return a/Math.sin(rad); }, //根據勾股定理中的銳角和斜邊長度,獲取臨邊長度 getBbyRadC:(rad,c)=>{ return Math.cos(rad)*c; }, //根據勾股定理中的銳角和斜邊長度,獲取對邊長度 getAbyRadC:(rad,c)=>{ return Math.sin(rad)*c; }, //根據圓弧的起點、端點、弧度,獲取圓心位置 getObyStarEndRad:(startPoint,endPoint,radian)=>{ const centerPoint=Util.getCenterPoint(startPoint,endPoint); const aLen=Util.getDistance(startPoint,endPoint)/2; const aRad=Util.getRadian(startPoint,endPoint); const bRad=Util.getRadPositive(aRad); const radius=Util.getCbyRadA(radian/2,aLen); const bLen=Util.getBbyRadC(radian/2,radius); return Util.getPointByVector(bRad,bLen,centerPoint); }, //根據圓弧的起點、端點、弧度,獲取半徑 getRadiusbyStarEndRad:(startPoint,endPoint,radian)=>{ const aLen=Util.getDistance(startPoint,endPoint)/2; return Util.getCbyRadA(radian/2,aLen); }, } export default Util;
接下來就能夠使用Unit 工具作實例了spa
三,實例code
canvas 裏的arc 圓弧的形參是:圓點 x,圓點 y,半徑,起始弧度,結束弧度,方向(默認false,即順時針)對象
實際上,咱們可能須要從一個端點畫弧線,而不用在意圓心在哪裏。好比圖一中,以startPoint 爲起點,以endPoint 爲結束點,順時針畫一段已知弧度的弧線。blog
圖一圖片
1.已知條件:ip
let startPoint={x:-300,y:100}; //起始點 let endPoint={x:100,y:-200}; //端點 let radian=Math.PI/4; //弧度 let counterclockwise=false; //是否逆時針
2.想要用arc 畫圖,就須要根據已知條件求arc 裏的形參。
求:圓點,半徑,起始弧度,結束弧度
3.解:
根據起點startPoint、終點endPoint,求線段中心點 centerPoint,a 的長度aLen,a的傾斜弧度aRad,a的垂線傾斜的弧度bRad(b 的傾斜弧度)
let centerPoint=Util.getCenterPoint(startPoint,endPoint); let aLen=Util.getDistance(startPoint,endPoint)/2; let aRad=Util.getRadian(startPoint,endPoint); let bRad=aRad+Math.PI/2;
根據a 和radA,求半徑c (radius)和b 的長度 bLen
let radius=Util.getCbyRadA(radian/2,aLen); let bLen=Util.getBbyRadC(radian/2,radius);
根據b 的弧度、b 的長度,求圓點 circleCenter 的位置(x,y)
let circleCenter=Util.getPointByVector(bRad,bLen,centerPoint);
根據圓點和起點,圓點和終點,求圓弧的起始弧度startRad,結束弧度endRad
let startRad=Util.getRadian(circleCenter,startPoint); let endRad=Util.getRadian(circleCenter,endPoint);
繪製 arc
ctx.beginPath(); ctx.arc(circleCenter.x,circleCenter.y,radius,startRad,endRad); ctx.stroke();
4.接下來咱們就能夠根據這種狀況本身封裝一個圓弧對象出來。這是我作過的一個效果: