一,点线面常识
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 为结束点,顺时针画一段已知弧度的弧线。
图一
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.接下来我们就可以根据这种情况自己封装一个圆弧对象出来。这是我做过的一个效果:
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。