前言

CanvasRenderingContext2D 没有提供绘制多边形的函数,所以只能由我们自己来实现绘制多边形的函数。以六边形为基础,需要用到三角函数:sin 和 cos。

点 A 坐标

(一)连接必要的辅助线:①连接点 A 和点 O;②从点 A 往下作一条垂直线;③连接点 A1 和点 O。(二)已知的量:①AO 实际就是圆 O 的半径。点 A 坐标的求解步骤:

  1. 求 ∠AOB;
  2. 求 OB 的长;
  3. 求 AB 的长;
  4. X 轴上的坐标:O 的 X 轴 + OB 的长度;
  5. Y 轴上的坐标:O 的 Y 轴 - AB 的长度;

求 A 点的坐标就必须要知道 OB 和 AB。

求 OB 的长

领边比斜边用 COS 函数,那么 OB 的长就是:

\[cos∠AOB = \frac{OB}{AO}
\]

求 AB 的长

对边比斜边用 SIN 函数,那么 AB 的长就是:

\[sin∠AOB = \frac{AB}{AO}
\]

求 ∠AOB

求 OB 和 AB 就必须要知道 ∠AOB。观察可知,∠AOB 的度数是360° / 6 = 60°

代码实现

let circX = 100, circY = 100, // 圆心坐标
let sides = 6, angleAOB = (Math.PI * 2) / sides; // ∠AOB let sideOB = Math.cos(angleAOB) * radius, sideAB = Math.sin(angleAOB) * radius; let aX = circX + sideOB, // 点 A 的 x 坐标
let aY = circY - sideAB; // 点 A 的 y 坐标

所以最终求得点 A 的坐标:(140, 30.717967697244916)

点 F 坐标

点 F 不能直接构成一个三角形,所以度数是 0°。sin0° = 0cos0°= 1

let circX = 100, circY = 100, // 圆心坐标
let sides = 6, angle = 0; let adjacentSide = Math.cos(angle) * radius, beveledSide = Math.sin(angle) * radius; let aX = circX + adjacentSide, // 点 F 的 x 坐标
let aY = circY - beveledSide; // 点 F 的 y 坐标

所以最终求得点 F 的坐标:(180, 100)

求所有点坐标

通过上面两个坐标的求解过程可知,只有三角形的度数在增加,从点 F 顺时针开始,每一个角是自身的角度再加 60°。

let radius = 80, sides = 6, circX = 100, circY = 100;
let angle = (Math.PI * 2) / sides, accumulator = 0; for ( let i = 0; i < sides; i++ ) {
let adjacentSide = Math.cos(accumulator) * radius;
let beveledSide = Math.sin(accumulator) * radius;
let aX = circX + adjacentSide;
let aY = circY - beveledSide;
ctx.lineTo(aX, aY);
accumulator += angle;
}

6 个点坐标的结果依次是:

封装成函数

只需提供多边形有多少面、多边形的圆心半径:

function drawPolygonPath(sides, radius, circX, circY, ctx) {
let angle = (Math.PI * 2) / sides, accumulator = 0; ctx.beginPath();
for ( let i = 0; i < sides; i++ ) {
let adjacentSide = Math.cos(accumulator) * radius;
let beveledSide = Math.sin(accumulator) * radius;
let aX = circX + adjacentSide;
let aY = circY - beveledSide;
ctx.lineTo(aX, aY);
accumulator += angle;
}
ctx.closePath();
ctx.stroke();
}

ctx.lineTo(aX, aY) 确定多边形所有的点,在循环结束之后关闭路径,再调用ctx.stroke() 函数,完成多边形的绘制。

let canvas = document.getElementById("canvas");
let ctx = canvas.getContext("2d"); drawPolygonPath(6, 80, 100, 100, ctx);

最新文章

  1. jekins构建自动化项目的步骤
  2. Magento开发常用方法
  3. python import其他文件夹下的模块
  4. hdu 1908 Double Queue
  5. aspose.cell 自定义模板 SUM无效
  6. nodejs save遇到的一个坑
  7. INDEX FAST FULL SCAN和INDEX FULL SCAN
  8. BZOJ1653: [Usaco2006 Feb]Backward Digit Sums
  9. DevExpress]ChartControl 创建Drill-Down样式的Title
  10. 等比缩放之自适应神器——css3的rem
  11. 关于jdk环境变量配置成了1.6.0_39 32位jdk 的路径 cmd中java -version却还是显示 64位或者其他jdk 路径的解决方法
  12. Matplotlib学习笔记(二)
  13. springmvc文件下载之文件名下划线问题终极解决方案
  14. Codeforces round 1086
  15. IIS下uploadify上传大文件出现404错误(提示上传文件大小超过400M)
  16. Number (int float bool complex)--》int 整型、二进制整型、八进制整型、十六进制整型
  17. solr7.1.0学习笔记(10)---Solr发布到Tomcat
  18. 【SqlServer】SqlServer索引的创建、查看、删除
  19. 如何搭建iOS项目基本框架
  20. [OSX] 在 OS X 中安装 MacPorts 指南

热门文章

  1. PYthon窗口学习之用异步请求解决Treeview列表插入大量数据反应慢的解决办法
  2. java中如何知道一个字符串中有多少个字,把每个字打印出来,举例
  3. 小程序wx.previewImage查看图片再次点击返回时重新加载页面问题
  4. 小程序获取自定义属性之e.target与e.currentTarget
  5. vue-cli打包后dist文件运行空白和背景图显示问题详解
  6. 关于表达式&amp;&amp; 和 || 有多项的时候的取值
  7. 在keil中加入DSP库并且使用arm_math.h
  8. 计算机编码规则之:Base64编码
  9. MySQL启动过程详解二:核心模块启动 init_server_components()
  10. Go 语言接口及使用接口实现链表插入