Javascript 在正方形内创建n个角的多边形的算法(HTML5-Canvas)?
请考虑以下设置: CSS:Javascript 在正方形内创建n个角的多边形的算法(HTML5-Canvas)?,javascript,html,algorithm,canvas,polygon,Javascript,Html,Algorithm,Canvas,Polygon,请考虑以下设置: CSS: div{ 位置:绝对位置; 顶部:50px; 左:50px; 高度:200px; 宽度:200px; 边框:2件纯黑; } HTML: <div id="container"> <canvas id="my-canvas"/> </div> 但是有5个角或n个角的多边形呢 var corners = 5; var c = document.getElementById('my-canvas').getContext('2
div{
位置:绝对位置;
顶部:50px;
左:50px;
高度:200px;
宽度:200px;
边框:2件纯黑;
}
HTML:
<div id="container">
<canvas id="my-canvas"/>
</div>
但是有5个角或n个角的多边形呢
var corners = 5;
var c = document.getElementById('my-canvas').getContext('2d');
var side = (document.getElementById('container').clientHeight * 4) / corners;
c.fillStyle = '#f00';
c.beginPath();
c.moveTo(0, 0);
// ok the following is totally wrong, but I'm sure there is a loop involved and that the x & y
// should increment/decrement each time around in some way, relevant to the value of *side*
for (var i=0; i<corners; i++) {
c.lineTo((side*i), side);
}
c.closePath();
c.fill();
var=5;
var c=document.getElementById('my-canvas').getContext('2d');
var side=(document.getElementById('container').clientHeight*4)/角;
c、 fillStyle='#f00';
c、 beginPath();
c、 moveTo(0,0);
//好的,下面是完全错误的,但我确信这涉及到一个循环,x&y
//应以某种方式每次递增/递减,与*side的值相关*
对于(var i=0;i,这实际上不是一个简单的问题。首先,让我们不那么含糊地陈述这个问题:
给定边长S的平方和整数n≥ 3、确定最大长度L,从而可以构造一个n边长度为L的正凸多边形,以便:
多边形的一侧位于正方形的一侧
多边形包含在正方形中
请注意,这并不要求多边形接触正方形的任何位置,而不是位于正方形一侧的一侧。(尽管对于n>3,不太难显示将存在其他接触点。)
一旦有了边长L,就很容易构建多边形本身。让我们先这样做(因为它有助于第一部分)。从简单的三角,多边形的中心将是一个距离
h=L/(2)⋅ tan(π/n))
位于多边形底面的中心上方,该中心(从对称性来看)也是正方形底面的中心。对于其余部分,让我们假设多边形的中心是坐标系的原点,+X轴向右,+Y轴向上。(请注意,我们的Y轴与通常的计算机图形坐标系相反。)多边形的半径(从中心到每个顶点的距离)将为
r=L/(2)⋅ sin(π/n))
让我们调用上面的方程1;我们将在结尾处再次引用它。顶点将由以下公式给出:
xi=r⋅ cos(θ0+2)⋅ π ⋅ i/n)
yi=r⋅ sin(θ0+2)⋅ π ⋅ i/n)
其中θ0是确定多边形旋转的“相位角”。我们希望旋转使多边形的底面水平。如果我们希望第一个顶点(i=0)是多边形底部的右顶点,那么我们应该使用
θ0=−π/2
通过该替换,我们的坐标方程简化为:
xi=r⋅ 罪(2)⋅ π ⋅ i/n)
yi=−R⋅ cos(2⋅ π ⋅ i/n)
作为将来的参考,上面的公式将是方程2。现在我们需要确定L。我认为,倒过来比较容易:对于给定的L,最小的s是多少,使得边长s的平方可以包含多边形,而边长s的一侧包含多边形的一侧。然后,我们可以缩放所有内容以匹配给定的边长s的平方原来的问题。但是这很简单。让我们使用L=1。对于n偶数,多边形的直径d(多边形上点之间的最大距离)为
d=2⋅ r=1/sin(π/n)(n偶数)
对于n奇数,不难看出直径是从底部的一个顶点到多边形顶部顶点的距离。通过一点构造(留给读者)和余弦定律,结果是:
d=sqrt([1+cos(π/n)]/[2⋅ sin2(π/n)](n奇数)
在这两种情况下,很容易确定多边形的至少一个直径是水平的。因此,包含多边形的最小正方形(多边形底部位于正方形底部)的边必须至少是直径,并且(根据多边形直径的定义)正方形永远不必更大
由于我们想缩放所有物体,使正方形的侧面测量给定的量S,因此我们最终得到:
L=S/d
因此,构造多边形的算法是首先确定L,如我们刚才所述,然后使用方程1计算r,最后使用方程2计算顶点,这些顶点应按顺序连接以形成多边形。简单
- 将圆分成x个边,360/x=边角
- 计算形状的每个点
- 计算面的角度
- 旋转形状,使面平放在容器中
- 重新缩放点以适应边界
有任何疑问,请检查下面的代码
//加载数据
var c=document.getElementById('canvas').getContext('2d');
var width=document.getElementById('canvas').clientWidth;
var height=document.getElementById('canvas').clientHeight;
var=5;
//初步计算
var半径=1;
变量角度=(Math.PI*2)/角点;
//构建点
var点=[];
对于(vari=0;iinscripted行:P1=[sin(a*n)*r+Cx,cos(a*n)*r+Cy];P2=[sin(a*(n+1))*r+Cx,cos(a*(n+1))*r+Cy];n=0..Nc
。我是在Java中做的(作为多边形)。基本上,你从矩形的中心开始,用x/y半径以n顶点的步长绕一圈,每个角度增加2*PI/#顶点。如果你想看代码,请告诉我有趣的等式,但我不知道什么是P1
,P2
,a
,r
,Cx
,Cy
representation。我猜n
是角数吗?谢谢ControlAltDel。是的,我不想看到代码,但最好你把它作为一个通用算法发布,这样我就可以想到它的JS版本了。:-)请注意你的要求“始终在一边有优势”无法实现。即使像六边形这样简单的东西也不能在rec的边上有两个相邻的顶点
var corners = 5;
var c = document.getElementById('my-canvas').getContext('2d');
var side = (document.getElementById('container').clientHeight * 4) / corners;
c.fillStyle = '#f00';
c.beginPath();
c.moveTo(0, 0);
// ok the following is totally wrong, but I'm sure there is a loop involved and that the x & y
// should increment/decrement each time around in some way, relevant to the value of *side*
for (var i=0; i<corners; i++) {
c.lineTo((side*i), side);
}
c.closePath();
c.fill();