Search code examples
javascriptkineticjs

Regular polygon with different height and width


I want to create a polygon with Kinetic.js and I know the width, height, rotation and number of points for the polygon.

I thought this would be possible by using the RegularPolygon object, but for it I have to set a value for radius. A triangle would be created like this:

var hexagon = new Kinetic.RegularPolygon({
    x: stage.width()/2,
    y: stage.height()/2,
    sides: 3,
    radius: 70,
    fill: 'red',
});

See a similar polygon being created here: http://www.html5canvastutorials.com/kineticjs/html5-canvas-kineticjs-regular-polygon-tutorial/

The result would look something like this:

enter image description here

But what if I want to create a triangle of which the width should be twice the height? Looking something like this:

enter image description here

As far as I understand, this not possible by just adjusting the radius.

How can I achieve this for any polygon? Note that I don't know the values for the points to begin with (they could be calculated though). I think that scaleX and scaleY might be possible to use, but is it possible to achieve it in an easier way? I would like just to set width and height directly.


Solution

  • KineticJS polygons are regular polygons (all sides are equal length).

    Scaling a regular-polygon is awkward if you want to stroke the polygon because the stroke is also scaled and therefore the stroke deforms.

    So your best solution might be to just draw a poly-line forming your triangles.

    enter image description here

    Here's example code and a Demo:

    var stage = new Kinetic.Stage({
      container: 'container',
      width: 350,
      height: 350
    });
    var layer = new Kinetic.Layer();
    stage.add(layer);
    
    var PI=Math.PI;
    var PI2=PI*2;
    
    scaledRegularPolygon(100,100,30,5,2,1,'red');
    
    function scaledRegularPolygon(cx,cy,radius,sides,scaleX,scaleY,fill){
      var points=[];
      for(var i=0;i<sides;i++){
        var sweep=PI2/sides;
        var midbottom=PI/2;
        var rightbottom=midbottom-sweep/2;
        var start=rightbottom-sweep;
        var angle=start+sweep*i;
        var x=cx+radius*Math.cos(angle);
        var y=cy+radius*Math.sin(angle);
        x=cx+(x-cx)*scaleX;
        y=cy+(y-cy)*scaleY;
        points.push(x,y);
      }
      var poly=new Kinetic.Line({
        points:points,
        closed:true,
        fill:fill,
        stroke: 'black',
        strokeWidth:4
      });
      layer.add(poly);
      layer.draw();
    }
    body{padding:20px;}
    #container{
      border:solid 1px #ccc;
      margin-top: 10px;
      width:350px;
      height:350px;
    }
    <script src="http://d3lp1msu2r81bx.cloudfront.net/kjs/js/lib/kinetic-v5.1.0.min.js"></script>
    <div id="container"></div>