4

一,点线面常识

1.基本概念

  • 点:没有大小,只有位置(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 工具做实例了

三,实例

canvas 里的arc 圆弧的形参是:圆点 x,圆点 y,半径,起始弧度,结束弧度,方向(默认false,即顺时针)

实际上,我们可能需要从一个端点画弧线,而不用在乎圆心在哪里。比如图一中,以startPoint 为起点,以endPoint 为结束点,顺时针画一段已知弧度的弧线。

clipboard.png
图一

1.已知条件:

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.接下来我们就可以根据这种情况自己封装一个圆弧对象出来。这是我做过的一个效果:

图片描述


已注销
148 声望9 粉丝

下一篇 »
1-集合