前言

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);

Canvas:绘制多边形的更多相关文章

  1. canvas绘制多边形

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  2. 浅谈使用canvas绘制多边形

    本文主要使用坐标轴的使用来绘制多边形,点位则都是在y轴上寻找,这种方法能够更好的理解图形与修改. //id为html里canvas标签的属性id: //x,y为坐标轴的起始位置,因为canvas默认坐 ...

  3. JavaScript+canvas 绘制多边形

    效果图: <body> <canvas id="square" width="500"></canvas> <canv ...

  4. (三)canvas绘制样式

    beginPath() 对画线点的一个开始限制 moveTo() 画线的起点,只在开头使用 参数两个x轴,y轴 lineTo() 后续连线 两个参数x轴,y轴 stroke() 连线无填充 fill( ...

  5. 学习笔记:HTML5 Canvas绘制简单图形

    HTML5 Canvas绘制简单图形 1.添加Canvas标签,添加id供js操作. <canvas id="mycanvas" height="700" ...

  6. [WebGL入门]十四,绘制多边形

    注意:文章翻译http://wgld.org/.原作者杉本雅広(doxas),文章中假设有我的额外说明,我会加上[lufy:].另外,鄙人webgl研究还不够深入.一些专业词语,假设翻译有误,欢迎大家 ...

  7. Canvas绘制不规则图形,实现可拖动,编辑--V1.0第一篇

    目前的工作在做在线的标注工具,接触canvas一年了,各种绘制,基本上图像的交互canvas都可以完成,也写了几篇关于canvas的文章,遇到的问题也写博客上了,对于canvas有问题的朋友可以去看看 ...

  8. Canvas学习:封装Canvas绘制基本图形API

    Canvas学习:封装Canvas绘制基本图形API Canvas Canvas学习   从前面的文章中我们了解到,通过Canvas中的CanvasRenderingContext2D对象中的属性和方 ...

  9. JS实现鼠标点击爱心&绘制多边形&每日一言功能

    本篇文章主要介绍我的个人博客 程序猿刘川枫 中页面使用的美化功能(基于JS实现): 1.鼠标点击出现不同颜色爱心特效 2.页面浮动多边形跟随鼠标移动 3.每日一言功能 1.鼠标点击出现爱心特效 经常在 ...

  10. HTML5学习总结——canvas绘制象棋(canvas绘图)

    一.HTML5学习总结——canvas绘制象棋 1.第一次:canvas绘制象棋(笨方法)示例代码: <!DOCTYPE html> <html> <head> & ...

随机推荐

  1. JavaEE Day12 Xml

    今日内容Xml 1.概念 2.语法结构 3.解析xml 一.XML概述 1.概念 Markup Language Extensible Markup Language--可扩展标记语言 标记语言:标签 ...

  2. 【Shell案例】【for循环、seq生成】3、输出7的倍数

    描述写一个 bash脚本以输出数字 0 到 500 中 7 的倍数(0 7 14 21...)的命令 方法1:in方式循环 [if的括号是中括号,中间的条件要有空格] [循环体用do和done配对] ...

  3. Chaos 测试下的若干 NebulaGraph Raft 问题分析

    Raft 是一种广泛使用的分布式共识算法.NebulaGraph 底层采用 Raft 算法实现 metad 和 storaged 的分布式功能.Raft 算法使 NebulaGraph 中的 meta ...

  4. python 定时发送邮件

    import smtplib from email.mime.text import MIMEText from email.mime.multipart import MIMEMultipart f ...

  5. vue3+ts 全局事件总线mitt

    Mitt 在vue3中 $ on,$off 和 $once 实例方法已被移除,组件实例不再实现事件触发接口,因此大家熟悉的EventBus便无法使用了.然而我们习惯了使用EventBus,对于这种情况 ...

  6. [OpenCV实战]10 使用Hu矩进行形状匹配

    目录 1 什么是图像矩? 2 如何计算图像矩 2.1 质心获取 2.2 中心矩 2.3 Hu矩 3 基于Hu矩实现形状匹配 3.1 Hu矩的计算 3.2 基于matchShapes函数计算两个图形之间 ...

  7. Spring MVC的运行流程

    Spring MVC的运行流程 摘要:本文档主要结合官方给出的Spring MVC流程图结合一个简单的Spring MVC实例,分析并介绍了Spring MVC的运行流程. 目录 Spring MVC ...

  8. 突如其来的&amp;quot;中断异常&amp;quot;,我(Java)该如何处理?

    # **一.何为异常?** ## 1.生活中的实例 生活中存在许多不正常: 上班路上自行车掉链子 上厕所手机掉马桶 下班回家钥匙丢失 ....... 2.程序中的实例 我们的代码中也许存在许多纰漏,导 ...

  9. 算法之Dijkstra及其堆优化和SPFA:图上单源最短路径神器

    签到题-- 题目传送门 SPFA算法 本人曾经写过一篇有关Bellman-ford的博,但就算是挂了优化的ford也只能过这道题的弱化版. 今天就先填个坑,先讲SPFA. 在这里我直接认为你们已经有一 ...

  10. day10-AOP-03

    AOP-03 7.AOP-切入表达式 7.1切入表达式的具体使用 1.切入表达式的作用: 通过表达式的方式定义一个或多个具体的连接点. 2.语法细节: (1)切入表达式的语法格式: execution ...