點線面的常識和繪製特定需求的弧線

一,點線面常識canvas

1.基本概念segmentfault

  • 點:沒有大小,只有位置(x,y,z)
  • 線:由無數個點組成,只有長度,沒有寬度
  • 面:擁有位置,寬高,邊界,面積屬性,沒有厚度

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

clipboard.png
圖一圖片

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.接下來咱們就能夠根據這種狀況本身封裝一個圓弧對象出來。這是我作過的一個效果:

圖片描述

相關文章
相關標籤/搜索