运用椭圆画法,45行代码画出任意正多边形

最近做Box2dWeb开发时,想写个创建正多边形的功能,可是由于学识尚浅,我在草稿纸上画了,想了一个上午也没有研究出什么好方法。后来翻抽屉的时候,找出了以前哥哥画的一张用同心圆画椭圆的示意图。看到这幅画,我不禁在想椭圆不就是一个N边形吗?圆不就是一个正N边形吗?如果把两个同心圆的半径设定为相等,画出来的椭圆不就是一个圆吗?因此,我立刻开始实验。原本我以为比较难,会用到圆的解析式之类的,没想到就45行代码就搞定了,主要用到的数学知识就是sin和cos。

也许有人不明白如何用同心圆画椭圆,我就借用网上找的一张图片给大家展示吧

这个画法很经典,做法简要概括一下就是:

画一个同心圆,然后以圆心为原点画一个二维坐标系;接着用N条过圆心的直线将圆等分,图中所示就是4条,把圆等分为了12份。每条直线都会与两个圆有交点,这时候我们就可以确定椭圆上的一个点——设直线与小圆的交点为(a, b),与大圆的交点为(c, d),确定的那个点的坐标则为(c, b);我们有N条直线就会得出2 * N + 4这样的点。可以看出,得到的点的坐标通式为:(与大圆的交点的x坐标, 与小圆的交点的y坐标)。要得到这些坐标,我们只用知道直线的条数N和大圆小圆的半径(或直径),然后用sin和cos进行计算即可。得到这些点后,把这些点连接起来就大致是个椭圆了;如果你把N的数目设定的越大,那么画出来的图形就更接近于椭圆。

与画椭圆不同的是,画正多边形不需要这么复杂,只需要一个圆就够了。而且也不要什么坐标系了,你要N 边形就画N条过圆心的直线,然后这些直线与圆的交点就是多变形的顶点。把顶点连接起来就是多变形。

现在,我们可以上代码了:

<!DOCTYPE html>
<html>
<head>
	<title>Make Regular Polygon</title>
	<meta charset="utf-8" />
	<script type="text/javascript">
	window.onload = function () {
		var canvasTag = document.getElementById("mycanvas");
		var c = canvasTag.getContext("2d");

		var vertices = getPolygonVertices(7, 100);

		c.beginPath();
		c.fillStyle = "lightgray";
		c.fillRect(0, 0, canvasTag.width, canvasTag.height);
		c.translate(canvasTag.width / 2, canvasTag.height / 2);
		c.moveTo(vertices[0][0], vertices[0][1]);
		for (var i = 1; i < vertices.length; i++) {
			c.lineTo(vertices[i][0], vertices[i][1]);
		}
		c.lineWidth = 5;
		c.closePath();
		c.stroke();
	};

	function getPolygonVertices (edges, r) {
		var ca = 0, aiv = 360 / edges, ata = Math.PI / 180, list = new Array();

		for (var k = 0; k < edges; k++) {
			var x = Math.cos(ca * ata) * r,
			y = Math.sin(ca * ata) * r;

			list.push([x, y]);

			ca += aiv;
		}

		return list;
	}
	</script>
</head>
<body>
	<canvas id="mycanvas" width="800" height="450"></canvas>
</body>
</html>

包括canvas渲染和html tag部分,一共45行。真正意义上的算法部分就只在getPolygonVertices函数里。 这个getPolygonVertices有两个参数,第一个参数是edges边数,第二个参数是圆的半径,决定多变形的大小。
算法在前面已经讲解过了,很简单很基础吧~

运行代码,画出七边形:

大家可以试着将getPolygonVertices的第一个参数改一改,画出其他多边形。

Ok,搞定收工~

本文到此结束,欢迎大家交流~

----------------------------------------------------------------

欢迎大家转载我的文章。

转载请注明:转自Yorhom‘s Game Box

http://blog.csdn.net/yorhomwang

欢迎继续关注我的博客

时间: 2024-10-25 05:11:53

运用椭圆画法,45行代码画出任意正多边形的相关文章

30 行代码绘出你的微信朋友统计图

前言 大家好,这里是「brucepk」爬虫 系列教程.此文首发于「brucepk」公众号,欢迎大家关注.此系列教程以实例项目为材料进行分析,从项目中学习 python 爬虫,跟着我一起学习,每天进步一点点. 学编程是一件枯燥的事情,比较好的方法是在实际项目中学习成长.今天带来的是 30 行代码画出你的微信朋友的性别统计图. 最近发现一个有意思的库:itchat,itchat 是一个开源的微信个人号接口.今天就用 itchat 来统计自己微信好友性别的比例并用柱形图展示出来. 项目环境:pytho

用 4 行代码画一幅中国地图

为什么是Python 先来聊聊为什么做数据分析一定要用Python或R语言.编程语言这么多种,Java, PHP都很成熟,但是为什么在最近热火的数据分析领域,很多人选择用Python语言? 数据分析只是一个需求,理论上来讲,任何语言都可以满足任何需求,只是麻烦与简易之别.Python这门语言诞生也相当之早,它的第一个版本是26年前发表的,曾经(或者说当前)也被用于web开发,但是就流行程度来说,远远干不过Java和PHP. 东方不亮西方亮,在与Java干仗失败的这20几年时光里,Python练就

神级程序员教你如何用四行代码画出一幅中国地图!Python就是牛逼

前面两行引入相应的库,真正的代码就4行,够简单吧.第1行甚至可以不写,它定义了图的大小.第2行我们创建一个地图,第3行把海岸线画上,第4行显示这个地图,就是这样: 你用 Java 的 4 行代码画一个地图出来? 然后我们开始画上国家,又是1行代码: m.drawcountries(linewidth=1.5) 就变成了这样: 看上去有点变形,这是因为我们没有添加任何投影的原因, Basemap 提供 24 种不同的投影方式,你可以自己一个个试一下,比较常用的是 兰勃特投影 ,我们添加一下: m

场景上一个任意三角形,用程序画出任意一个顶点所在的高,三角形由程序在某一个范围内随机生成

解析: 1.题目解析:已知三角形三个顶点的坐标例如A(x1,y1),B(x2,y2),C(x3,y3),画出任意一个顶点的高线,所有必须求出高另一个点(这里我们叫H点)的坐标,然后两个点连成线. 2.逻辑解析:要计算出高线的垂直点的坐标必须用一个方程组. 3.原理解析:根据数学里面的知识,已知两个顶点(例如B.C)的坐标,即可计算出这两个点连成线的直线方程 y = kx + b:其中 k 指的是直线方程中的斜率,b是一个未知常数,因为知道B.C两点的坐标,所以可以计算出直线BC的直线方程, 那么

反-反爬虫:用几行代码写出和人类一样的动态爬虫

欢迎大家前往腾讯云技术社区,获取更多腾讯海量技术实践干货哦~ 作者:李大伟 Phantomjs简介 什么是Phantomjs Phantomjs官网介绍是:不需要浏览器的完整web协议栈(Full web stack No browser required),也就是常说的无头浏览器--或者好听点叫做:无界面的web解析器. Phantomjs的特点 由于"无头"--免去了渲染可视化的网页界面,她的速度要比一般的浏览器快不少,又因为她是完整的web协议栈,所以不仅仅提供了JavaScri

使用java,画出任意大小的菱形

1 public class rhombic { 2 3 public static void main(String[] args){ 4 5 /** 6 * scriber()画菱形的方法,参数 9 是指菱形的对角线的长度 7 * 参数,在此处,只使用奇数, 8 * 如果,你想要使用偶数,请找我,否则自己处理,哈哈 9 */ 10 scriber(29); 11 12 } 13 14 /** 15 * 画出一个默认大小的菱形 16 * 功能已经完成,好像可以简化一下 17 */ 18 pri

C语言6行代码画圆

这一方法是受到milo大神用C语言画心的启发而想到的. 代码如下: #include<stdio.h> int main(){ for(double l=1;l>-1;l-=0.05,printf("\n")) for(double w=1;w>-1;w-=0.025) printf((l*l + w*w<=1)?"=":" "); } 效果: 事实上,代码的逻辑和背景知识是很简单的,就是从左到右,从上到下,用等号填

4行代码求出圆周率800位,供赏析

[email protected]:~/lab$ cat main.c  #include "stdio.h" int main(){ long a=10000,b,c=2800,d,e,f[2801],g; for(;b-c;) f[b++]=a/5; for(; d=0,g=c*2; c-=14,printf("%.4ld",e+d/a),e=d%a) for(b=c;d+=f[b]*a,f[b]=d%--g,d/=g--,--b;d*=b); } [email

七行代码搞定 任意数据库中的数据迁移

var et = new EntityTransform(); et.SrcConn = "YuanKu"; et.DesConn = "mubiaoku"; et.AllowInsertIdentity = true; foreach (var item in EntityFactory.LoadEntities(et.SrcConn, true)) { var eop = EntityFactory.CreateOperate(item); et.Transfo