Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/458.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 在正方形内创建n个角的多边形的算法(HTML5-Canvas)?_Javascript_Html_Algorithm_Canvas_Polygon - Fatal编程技术网

Javascript 在正方形内创建n个角的多边形的算法(HTML5-Canvas)?

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

请考虑以下设置:

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