在HTML 5画布上创建Reuleaux多边形的函数 [英] Function to create Reuleaux Polygons on an HTML 5 canvas

查看:112
本文介绍了在HTML 5画布上创建Reuleaux多边形的函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发一个使用HTML 5画布设计系统作品的项目。为了给我的作品更有机和多样的感觉,我想有一个功能,创造reuleaux多边形。我认为可能有一种方法将我的 draw_sharp_polygon(center_position,radius,number_of_sides,正则,逆时针)函数转换成我需要的函数,但我不知道如何做这个。 我需要使用大量的 context.lineTo()函数,或者我可以使用上下文。 arcTo() function以某种方式?

  function draw_sharp_polygon 
{
if(typeof center_position =='undefined')
center_position = new Position();
if(typeof radius =='undefined')
radius = dice_roll(diagonal);
if(typeof number_of_sides =='undefined'|| number_of_sides< 3)
number_of_sides = dice_roll(10);
if(typeof regular =='undefined')
regular = coin_toss();
if(typeof anticlockwise =='undefined')
anticlockwise = coin_toss();
context.moveTo(center_position.x + radius,center_position.y)
if(regular)
{
var circular_angle_division =(Math.PI * 2)/ number_of_sides;
circular_angle_division = anticlockwise? -1 * circular_angle_division:circular_angle_division;
for(var i = 1; i {
context.lineTo(radius * Math.cos(circular_angle_division * i),radius * Math.sin(circular_angle_division *一世));
}
}
else
{
var amount_of_circle_taken = 0;
var direction = anticlockwise? -1:1;
var sides_left = number_of_sides;
for(var i = 1; i< number_of_sides; i ++)
{
if(i {
var circular_angle_division = get_random_value 1,(((Math.PI * 2) - amount_of_circle_taken)/ number_of_sides *(sides_left / 2)))
amount_of_circle_taken + = circular_angle_division;
}
else
{
var circular_angle_division =(Math.PI * 2) - amount_of_circle_taken;
}
context.lineTo(radius * Math.cos(direction * circular_angle_division * i),radius * Math.sin(direction * circular_angle_division * i));
}
}
}

平边多边形。 我想知道是否有一种方法使用 context.arcTo()而不是 context.lineTo()创建reuleaux多边形。



我将要发布一个Reuleaux三角形的示例,声誉。维基百科有一个很好的例子。



我不使用jQuery在任何我的个人项目,因为我觉得他们大多数可以成为一个独立的JavaScript库的一部分。

解决方案

arcTo()实际上位于外接圆上,位于弧终点之间的中间。需要的半径可以用下式计算:

  reuleaux_radius = radius * sqrt(2 + 2 * cos(pi / number_of_sides))

相当于

  reuleaux_radius = radius * sqrt(2 + 2 * cos(angle2  -  angle1))

完整代码:



  var taget = document.getElementById('target'); var context = target.getContext('2d'); var sides = 3; var radius = 100; var center = new Position(150,150); // normal polygoncontext.beginPath(); draw_sharp_polygon(center,radius,sides); context.strokeStyle ='silver'; context.stroke ; // circlecontext.beginPath(); context.arc(center.x,center.y,radius,0,2 * Math.PI,false); context.strokeStyle ='silver'; context.stroke reuleaux polygoncontext.beginPath(); draw_reuleaux_polygon(center,radius,sides); context.strokeStyle ='black'; context.stroke(); function Position(x,y){this.x = x || 0; this.y = y || 0;} function draw_reuleaux_polygon(center_position,radius,number_of_sides){if(typeof center_position =='undefined')throw new Error(center_position not defined); if(typeof radius =='undefined')throw new Error(radius not defined); if(typeof number_of_sides =='undefined'|| number_of_sides< 3)throw new Error(number_of_sides not defined); context.moveTo(center_position.x + radius,center_position.y); for(var index1 = 0; index1  

 < canvas id =targetwidth =300height =300>< / canvas>  

http://jsfiddle.net/hebvseju/


I am working on a project to design systematic artworks using an HTML 5 canvas. To give my artworks a more organic and diverse feel I wanted to have a function that created reuleaux polygons. I think there may be a way to convert my draw_sharp_polygon(center_position, radius, number_of_sides, regular, anticlockwise) function into the function I need but I'm unsure of how to do this. Would I need to use a large amount of context.lineTo() functions or would I be able to use the context.arcTo() function in some way?

function draw_sharp_polygon(center_position, radius, number_of_sides, regular, anticlockwise)
{
    if(typeof center_position == 'undefined')
        center_position = new Position();
    if(typeof radius == 'undefined')
        radius = dice_roll(diagonal);
    if(typeof number_of_sides == 'undefined' || number_of_sides < 3)
        number_of_sides = dice_roll(10);
    if(typeof regular == 'undefined')
        regular = coin_toss();
    if(typeof anticlockwise == 'undefined')
        anticlockwise = coin_toss();
    context.moveTo(center_position.x + radius, center_position.y)
    if(regular)
    {
        var circular_angle_division = (Math.PI * 2)/number_of_sides;
        circular_angle_division = anticlockwise ? -1 * circular_angle_division : circular_angle_division;
        for(var i = 1; i < number_of_sides; i++)
        {
            context.lineTo(radius * Math.cos(circular_angle_division * i),radius * Math.sin(circular_angle_division * i));
        }
    }
    else
    {
        var amount_of_circle_taken = 0;
        var direction = anticlockwise ? -1 : 1;
        var sides_left = number_of_sides;
        for(var i = 1; i < number_of_sides; i++)
        {
            if(i < number_of_sides -1)
            {
                var circular_angle_division = get_random_value(1, (((Math.PI * 2) - amount_of_circle_taken)/number_of_sides*(sides_left / 2)));
                amount_of_circle_taken += circular_angle_division;
            }
            else
            {
                var circular_angle_division = (Math.PI * 2) - amount_of_circle_taken;
            }
            context.lineTo(radius * Math.cos(direction * circular_angle_division * i),radius * Math.sin(direction * circular_angle_division * i));
        }
    }
}

That's what I have for my flat edged polygons. I was wondering if there was a way to use context.arcTo() instead of context.lineTo() to create reuleaux polygons.

I was going to post an example of a Reuleaux Triangle but I don't have enough reputation. Wikipedia has a great example though.

P.S. I don't use jQuery in any of my personal projects yet because I feel that most of them could become part of a stand alone javascript library. So please no answers using jQuery.

解决方案

The tangent-point needed for arcTo() is actually on the circumcircle, halfway between the arc endpoints. The radius needed could be calculated with:

reuleaux_radius = radius * sqrt(2 + 2*cos(pi / number_of_sides))

which is equivalent to

reuleaux_radius = radius * sqrt(2 + 2*cos(angle2 - angle1))

Full code:

var taget = document.getElementById('target');
var context = target.getContext('2d');

var sides = 3;
var radius = 100;
var center = new Position(150,150);

// normal polygon
context.beginPath();
draw_sharp_polygon(center, radius, sides);
context.strokeStyle = 'silver';
context.stroke();

// circle
context.beginPath();
context.arc(center.x, center.y, radius, 0, 2*Math.PI, false);
context.strokeStyle = 'silver';
context.stroke();

// reuleaux polygon
context.beginPath();
draw_reuleaux_polygon(center,radius,sides);
context.strokeStyle = 'black';
context.stroke();

function Position(x, y)
{
    this.x = x || 0;
    this.y = y || 0;
}

function draw_reuleaux_polygon(center_position, radius, number_of_sides)
{
    if(typeof center_position == 'undefined')
        throw new Error("center_position not defined");
    if(typeof radius == 'undefined')
        throw new Error("radius not defined");
    if(typeof number_of_sides == 'undefined' || number_of_sides < 3)
        throw new Error("number_of_sides not defined");

    context.moveTo(center_position.x + radius, center_position.y);
    for (var index1 = 0; index1 < number_of_sides; index1++)
    {
        // point 1 = arc start
        // point 2 = tangent intersection
        // point 3 = arc end
        var index2 = (index1 + 0.5) % number_of_sides;
        var index3 = (index1 + 1) % number_of_sides;
        var angle1 = index1*2*Math.PI/number_of_sides;
        var angle2 = index2*2*Math.PI/number_of_sides;
        var angle3 = index3*2*Math.PI/number_of_sides;
        var p1 = new Position(center_position.x + radius*Math.cos(angle1), center_position.y + radius*Math.sin(angle1));
        var p2 = new Position(center_position.x + radius*Math.cos(angle2), center_position.y + radius*Math.sin(angle2));
        var p3 = new Position(center_position.x + radius*Math.cos(angle3), center_position.y + radius*Math.sin(angle3));

        var reuleaux_radius = radius*Math.sqrt(2 + 2*Math.cos(Math.PI/number_of_sides));
        
        context.arcTo(p2.x, p2.y, p3.x, p3.y, reuleaux_radius);
    }
    
    context.closePath();
}

function draw_sharp_polygon(center_position, radius, number_of_sides)
{
    if(typeof center_position == 'undefined')
        throw new Error("center_position not defined");
    if(typeof radius == 'undefined')
        throw new Error("radius not defined");
    if(typeof number_of_sides == 'undefined' || number_of_sides < 3)
        throw new Error("number_of_sides not defined");
    
    context.moveTo(center_position.x + radius, center_position.y);
    var circular_angle_division = (Math.PI * 2)/number_of_sides;
    for(var i = 1; i < number_of_sides; i++)
    {
        var x = center_position.x + radius * Math.cos(circular_angle_division * i);
        var y = center_position.y + radius * Math.sin(circular_angle_division * i);
        console.log(i,x,y);
        context.lineTo(x,y);
    }
    
    context.closePath();
}

<canvas id="target" width="300" height="300"></canvas>

http://jsfiddle.net/hebvseju/

这篇关于在HTML 5画布上创建Reuleaux多边形的函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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