Gustav
Gustav

Reputation: 347

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.

Upvotes: 0

Views: 769

Answers (2)

truefusion
truefusion

Reputation: 493

Kinetic.Transform allows us to calculate the position of a point from a transform matrix by passing in the point to Kinetic.Transform.point(). From the object you want to transform the points for, get its transform matrix with Kinetic.Node.getAbsoluteTransform().copy() (or Kinetic.Node.getTransform().copy(), whatever seems suitable for your purposes). Then we call Kinetic.Transform.scale(2,2) on the transform matrix to get a matrix with twice the scale. Then for each point, use Kinetic.Transform.point() to get its new position.

Upvotes: 0

markE
markE

Reputation: 105035

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>

Upvotes: 1

Related Questions