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

(一)连接必要的辅助线:①连接点 A 和点 O;②从点 A 往下作一条垂直线;③连接点 A1 和点 O。(二)已知的量:①AO 实际就是圆 O 的半径。点 A 坐标的求解步骤:
- 求 ∠AOB;
- 求 OB 的长;
- 求 AB 的长;
- X 轴上的坐标:O 的 X 轴 + OB 的长度;
- Y 轴上的坐标:O 的 Y 轴 - AB 的长度;
求 A 点的坐标就必须要知道 OB 和 AB。
求 OB 的长
领边比斜边用 COS 函数,那么 OB 的长就是:
\]
求 AB 的长
对边比斜边用 SIN 函数,那么 AB 的长就是:
\]
求 ∠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° = 0、cos0°= 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);

Canvas:绘制多边形的更多相关文章
- canvas绘制多边形
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- 浅谈使用canvas绘制多边形
本文主要使用坐标轴的使用来绘制多边形,点位则都是在y轴上寻找,这种方法能够更好的理解图形与修改. //id为html里canvas标签的属性id: //x,y为坐标轴的起始位置,因为canvas默认坐 ...
- JavaScript+canvas 绘制多边形
效果图: <body> <canvas id="square" width="500"></canvas> <canv ...
- (三)canvas绘制样式
beginPath() 对画线点的一个开始限制 moveTo() 画线的起点,只在开头使用 参数两个x轴,y轴 lineTo() 后续连线 两个参数x轴,y轴 stroke() 连线无填充 fill( ...
- 学习笔记:HTML5 Canvas绘制简单图形
HTML5 Canvas绘制简单图形 1.添加Canvas标签,添加id供js操作. <canvas id="mycanvas" height="700" ...
- [WebGL入门]十四,绘制多边形
注意:文章翻译http://wgld.org/.原作者杉本雅広(doxas),文章中假设有我的额外说明,我会加上[lufy:].另外,鄙人webgl研究还不够深入.一些专业词语,假设翻译有误,欢迎大家 ...
- Canvas绘制不规则图形,实现可拖动,编辑--V1.0第一篇
目前的工作在做在线的标注工具,接触canvas一年了,各种绘制,基本上图像的交互canvas都可以完成,也写了几篇关于canvas的文章,遇到的问题也写博客上了,对于canvas有问题的朋友可以去看看 ...
- Canvas学习:封装Canvas绘制基本图形API
Canvas学习:封装Canvas绘制基本图形API Canvas Canvas学习 从前面的文章中我们了解到,通过Canvas中的CanvasRenderingContext2D对象中的属性和方 ...
- JS实现鼠标点击爱心&绘制多边形&每日一言功能
本篇文章主要介绍我的个人博客 程序猿刘川枫 中页面使用的美化功能(基于JS实现): 1.鼠标点击出现不同颜色爱心特效 2.页面浮动多边形跟随鼠标移动 3.每日一言功能 1.鼠标点击出现爱心特效 经常在 ...
- HTML5学习总结——canvas绘制象棋(canvas绘图)
一.HTML5学习总结——canvas绘制象棋 1.第一次:canvas绘制象棋(笨方法)示例代码: <!DOCTYPE html> <html> <head> & ...
随机推荐
- K近邻算法(k-nearest neighbor, kNN)
K近邻算法(K-nearest neighbor, KNN) KNN是一种分类和回归方法. KNN简介 KNN模型3要素 KNN优缺点 KNN应用 参考文献 KNN简介 KNN思想 给定一个训练集 T ...
- OpenJudge 1.8.11 图像旋转
11:图像旋转 总时间限制: 1000ms 内存限制: 65536kB 描述 输入一个n行m列的黑白图像,将它顺时针旋转90度后输出. 输入 第一行包含两个整数n和m,表示图像包含像素点的行数和列数. ...
- YonBuilder移动开发平台功能大盘点
YonBuilder是面向企业组织和个人开发者的低代码开发平台,实现无代码.低代码.专业代码开发三种模式.提供元数据驱动和画布构建两种开发方式,通过点击拖拽+自动化代码生成和移动多端编译的技术,与开放 ...
- 3、swagger调试
Swagger: 1.将项目中所有的接口展现在页面上,这样后端程序员就不需要专门为前端使用者编写专门的接口文档: 2.当接口更新之后,只需要修改代码中的Swagger描述就可以实时生成新的接口文档了, ...
- 论文解读(CAN)《Contrastive Adaptation Network for Unsupervised Domain Adaptation》
论文信息 论文标题:Contrastive Adaptation Network for Unsupervised Domain Adaptation论文作者:Guoliang Kang, Lu Ji ...
- 大数据 - ADS 数据可视化实现
之前数据分层处理,最后把轻度聚合的结果保存到 ClickHouse 中,主要的目的就是提供即时的数据查询.统计.分析服务.这些统计服务一般会用两种形式展现,一种是为专业的数据分析人员的 BI 工具,一 ...
- 如何指定多个项目的 InternalsVisibleTo
InternalsVisibleTo 属性允许你指定一个或多个程序集,这些程序集可以访问当前程序集中的内部类型.经常在进行单元测试时使用,例如,你可以在一个项目中定义一个内部类型,然后在另一个项目中进 ...
- HttpServletRequest获取参数和文件
从HttpServletRequest中获取上传文件及参数的方法 try { //下面这句必须加,不然报错 MultipartResolver resolver = new CommonsMultip ...
- vue多界面开发
1. 安装 vue-cli,已有的请跳过这一步 npm install -g @vue/cli 若已安装旧版 vue-cli 则需要先卸载 vue-cli npm uninstall -g vue-c ...
- P7368 [USACO05NOV]Asteroids G
题面 贝茜想在 \(N\times N\) 的网格中驾驶她的宇宙飞船.网格中有 \(K\) 个小行星.要使驾驶过程愉快,就必须把这些小行星全部消除. 贝茜有一个武器,可以以一个单位代价消除一行或一列的 ...