算法创建的n个角的多边形的正方形内(HTML5 - 画布)? [英] Algorithm creating polygon of n corners inside a square (HTML5 - Canvas)?

查看:139
本文介绍了算法创建的n个角的多边形的正方形内(HTML5 - 画布)?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

考虑以下设置:

CSS:

DIV {     位置:绝对的;     顶:50像素;     左:50像素;     高度:200像素;     宽度:200像素;     边界:2px的纯黑色; }

HTML:

 < D​​IV ID =容器>
    <帆布ID =我的画布/>
< / DIV>
 

现在#我的画布我希望能够利用任意数量的角落总是坐在其一侧(与没有一个多边形内部的角)。高度和宽度的多边形将占用应始终等于其父(在这种情况下,200像素X 200像素),我们将假设它总是将是一个正方形。

有一个标准的算法来实现这一(不使用任何JS库)?

绘图与4个角的多边形内部的#我的容器是最简单的我猜你会基本上要创建大小相等的正方形:

 变种C =的document.getElementById('我的画布)的getContext(2D)。
VAR方=的document.getElementById('集装箱')clientHeight。
c.fillStyle ='#F00;
c.beginPath();
c.moveTo(0,0);
c.lineTo(0,侧);
c.lineTo(边,面);
c.lineTo(侧,0);
c.closePath();
c.fill();
 

但是,我们有5角或N角的多边形?

  VAR角= 5;
变种C =的document.getElementById('我的画布)的getContext(2D)。
VAR侧=(的document.getElementById('集装箱')clientHeight * 4)/角;
c.fillStyle ='#F00;
c.beginPath();
c.moveTo(0,0);
// OK,以下是完全错误的,但我敢肯定有参与循环,而在X和放大器; ÿ
//应增加/减少周围每次以某种方式,相​​关的*侧的值*
对于(VAR I = 0; I<角落;我++){
   c.lineTo((方* I),侧);
}
c.closePath();
c.fill();
 

感谢您在您的帮助!

注意:

我感兴趣的只是多边形,其边长度相等的(我想这就是你所谓的正规的多边形?)。

由于我们是在HTML / CSS的宇宙中,允许的最小的一面显然会是1px的的长度。因此,这是唯一的限制。

多边形我指的是在底部发现那些类型离开<一href="http://upload.wikimedia.org/wikipedia/commons/thumb/e/eb/Polygon_types.svg/750px-Polygon_types.svg.png"相对=nofollow>这个图片。显然,他们的类型是正规凸的?道歉,但我不是一个数学家。

解决方案

简单..

  • 将一个圆形变成双方x的量,360 / X =角边
  • 在计算出每个点的形状
  • 在计算一个面的角度
  • 在旋转形状,面是平的放入容器中
  • 重规模点,以适应边界

任何疑问..只是检查以下

在code

//加载数据 变种C =的document.getElementById('画布')的getContext(2D)。 VAR WIDTH =的document.getElementById('画布')clientWidth。 VAR HEIGHT =的document.getElementById('画布')clientHeight。 VAR角= 5; //初始计算 变种半径= 1; VAR角=(Math.PI * 2)/角落; //建点 VAR分= []; 对于(VAR I = 0; I&LT;角落;我++) {     VAR一个=角度*我;     //罪和COS swithced,0点是底面合一     变种,X =(Math.sin(一)*半径);     变种Y =(Math.cos(一)*半径);     points.push({         X:X         ,Y:Y     }) } //取得一侧的角 VAR sideangle = Math.atan2(点[1] .Y点[0] .Y,点[1] .X点[0] .X) 围绕底端的//旋转点 变种O =点[0]; 对于(VAR I = 1; I&LT; points.length;我++) {     点[i] = {         X:Math.cos(sideangle)*(点[I] .X - 牛) - Math.sin(sideangle)*(点[I] .yo.y)+牛         ,Y的:Math.sin(sideangle)*(点[I] .X - 牛)+ Math.cos(sideangle)*(点[I] .Y - OY)+ OY     }; } //这个点的数字是平放在地板上让测量其大小 VAR RECT = {顶:2,左:2,右:-2,底部:-2}; 对于(VAR I = 0; I&LT; points.length;我++) {     rect.top = Math.min(rect.top,点[I] .Y);     rect.bottom = Math.max(rect.bottom,点[I] .Y);     rect.left = Math.min(rect.left,点[I] .X);     rect.right = Math.max(rect.right,点[I] .X); } rect.width = Math.abs(rect.right - rect.left); rect.height = Math.abs(rect.bottom - rect.top); 矩形的//使相对点左上角 对于(VAR I = 0; I&LT; points.length;我++) {     点[i] = {         X:点[我] .X - rect.left         ,Y:点[我] .Y - rect.top     }; } //允许刻度和根据它的矩形聚定位 VAR ratioX =宽/ rect.width VAR ratioY =身高/ rect.height VAR比率= Math.min(ratioX,ratioY); 对于(VAR I = 0; I&LT; points.length;我++) {     点[i] = {         X:(点[我] .X *比)         ,Y:(点[我] .Y *比)     }; } //绘制路径 c.beginPath(); c.moveTo(点[0] .X,点[0] .Y); 对于(VAR I = 1; I&LT; points.length;我++)     c.lineTo(分[I] .X,点[I] .Y); c.closePath(); //绘制 c.strokeStyle ='#F00 c.stroke(); c.fillStyle ='#F00; //c.fill();

画布{     位置:绝对的;     顶:50像素;     左:50像素;     边界:2px的纯黑色; }

&LT;! - 大小必须被定义为属性 - &GT; &LT;画布宽度=300高度=200ID =画布/&GT;

Consider the following setup :

CSS :

div {
    position :absolute;
    top: 50px;
    left: 50px;
    height: 200px;
    width: 200px;
    border: 2px solid black;
}

HTML :

<div id="container">
    <canvas id="my-canvas"/>
</div>

Now inside #my-canvas I want to be able to draw a polygon with any number of corners that always sits on one of its sides (and not one of its corners). The height and width that the polygon will "take up" should always be equal to that of its parent (in this case 200px X 200px) which we will assume that it's always going to be a square.

Is there a standard algorithm to achieve that (without using any JS libraries)?

Drawing a polygon with 4 corners inside #my-container is the easiest I guess as you will basically be creating a square of equal size :

var c = document.getElementById('my-canvas').getContext('2d');
var side = document.getElementById('container').clientHeight;
c.fillStyle = '#f00';
c.beginPath();
c.moveTo(0, 0);
c.lineTo(0, side);
c.lineTo(side, side);
c.lineTo(side, 0);
c.closePath();
c.fill();

But what about a polygon with 5 corners or n corners ?

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

Thank you in advance for any help!

NOTE :

I am only interested in polygons whose sides are of equal length (I guess this is what you'd call a "regular" polygon?).

Since we're in the HTML/CSS universe, the smallest side allowed will obviously be that of a length of 1px. So this is the only restriction.

The type of polygons I'm referring to are the ones found at the bottom left of this image. Apparently they are of type "regular convex" ? Apologies but I'm not a mathematician.

解决方案

Simple..

  • divide a circle into x amount of sides, 360 / x = angle of side
  • calculate each point of shape
  • calculate the angle of a face
  • rotate shape so face is flat into the container
  • re-scale points to fit boundaries

any doubts.. just check the code below

//load data
var c = document.getElementById('canvas').getContext('2d');
var width = document.getElementById('canvas').clientWidth;
var height = document.getElementById('canvas').clientHeight;
var corners = 5;
//initial calculation
var radius = 1;
var angle = (Math.PI * 2) / corners;

//build points 
var points = [];
for (var i=0; i<corners; i++)
{
    var a = angle * i;
    //sin and cos are swithced,point 0 is bottom one
    var x = (Math.sin(a)*radius);
    var y = (Math.cos(a)*radius);
    points.push({
        x:x
        ,y:y
    })
} 
//get the angle of a side
var sideangle = Math.atan2(points[1].y-points[0].y, points[1].x-points[0].x)
//rotate point around bottom one
var o = points[0];
for (var i=1; i<points.length; i++)
{
    points[i] = {
        x:Math.cos(sideangle) * (points[i].x - o.x) - Math.sin(sideangle) * (points[i].y-o.y) + o.x
        ,y:Math.sin(sideangle) * (points[i].x - o.x) + Math.cos(sideangle) * (points[i].y - o.y) + o.y
    };
}
//by this point the figure is "flat on the floor" lets measure its size
var rect = {top:2,left:2,right:-2,bottom:-2};
for (var i=0; i<points.length; i++)
{
    rect.top = Math.min(rect.top,points[i].y);
    rect.bottom = Math.max(rect.bottom,points[i].y);
    rect.left = Math.min(rect.left,points[i].x);
    rect.right = Math.max(rect.right,points[i].x);
}
rect.width = Math.abs(rect.right - rect.left);
rect.height = Math.abs(rect.bottom - rect.top);
//make points relative to top left of rect
for (var i=0; i<points.length; i++)
{
    points[i] = {
        x: points[i].x - rect.left
        ,y: points[i].y - rect.top
    };
}
//lets scale and position the poly based on its rect
var ratioX = width / rect.width
var ratioY = height / rect.height
var ratio = Math.min(ratioX, ratioY);

for (var i=0; i<points.length; i++)
{
    points[i] = {
        x: (points[i].x * ratio)
        ,y: (points[i].y * ratio)
    };
}

//draw path
c.beginPath();

c.moveTo(points[0].x, points[0].y);
for (var i=1; i<points.length; i++)
    c.lineTo(points[i].x, points[i].y);
c.closePath();
//draw
c.strokeStyle='#f00'
c.stroke();
c.fillStyle = '#f00';
//c.fill();

canvas{
    position :absolute;
    top: 50px;
    left: 50px;
    border: 2px solid black;
}

<!--size must be defined as attribute-->
<canvas width='300' height='200' id="canvas"/>

这篇关于算法创建的n个角的多边形的正方形内(HTML5 - 画布)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆