Feature request : Add option to draw a polygon at a certain position

Would be nicer if the polygon pts array contained just the shape data and let the fillPolygon set where it's drawn.

So you could define a shape like this...

var arrow = [ [1,1], [1,10], [10,5] ];

Then have it drawn at a certain location, for example,

fillPolygon(arrow, 10, 10)

i.e. draw the arrow polygon at 10,10.

Cool eh?! ;-)
  • This is how exactly how most 3d rendering is done. The object mesh (the points that make up a 3d model) are transformed from one coordinate system to another (and another, and another) and then displayed on screen.

    You can easily by transform the points from one coordinate system (where the object is drawn at the origin) to another (where the object is rendered on screen) with simple arithmetic/trigonometry. If you only need to translate...

    function fillPolygon(dc, dx, dy, points) {
    for (var i = 0; i < points.size(); ++i) {
    points[0] += dx;
    points[1] += dy;
    }

    dc.fillPolygon(points);
    }
    [/code]

    If you want to do rotation and translation...

    function fillPolygon(dc, dx, dy, theta, points) {
    var sin = Math.sin(theta);
    var cos = Math.cos(theta);

    for (var i = 0; i < points.size(); ++i) {
    var x = (points[0] * cos) - (points[1] * sin) + dx;
    var y = (points[0] * sin) + (points[1] * cos) + dy;

    points[0] = x;
    points[1] = y;
    }

    dc.fillPolygon(points);
    }
    [/code]

    If you want to do translation, rotation, and scale...

    function fillPolygon(dc, sx, sy, dx, dy, theta, points) {
    var sin = Math.sin(theta);
    var cos = Math.cos(theta);

    for (var i = 0; i < points.size(); ++i) {
    points[0] *= sx;
    points[1] *= sy;

    var x = (points[0] * cos) - (points[1] * sin) + dx;
    var y = (points[0] * sin) + (points[1] * cos) + dy;

    points[0] = x;
    points[1] = y;
    }

    dc.fillPolygon(points);
    }
    [/code]

    You can also do all of this with affine transformation matrices.
  • Woah. That's fantastic. Thank you very much!
  • It should be noted that, due to the way MonkeyC (and other languages) treat arrays, each of the above functions modifies the points array it is called on. If you intend to re-use the point data to draw multiple objects, you have to make a copy of the points and then modify/render them...

    function fillPolygon(dc, sx, sy, dx, dy, theta, points) {
    var sin = Math.sin(theta);
    var cos = Math.cos(theta);

    var coords = new [points.size()];
    for (var i = 0; i < points.size(); ++i) {

    // make a copy so as to not modify the points array
    coords= [ points[0] * sx, points[1] * sy ];

    var x = (coords[0] * cos) - (coords[1] * sin) + dx;
    var y = (coords[0] * sin) + (coords[1] * cos) + dy;

    coords[0] = x;
    coords[1] = y;
    }

    dc.fillPolygon(coords);
    }
    [/code]
  • It should be noted that, due to the way MonkeyC (and other languages) treat arrays, each of the above functions modifies the points array it is called on. If you intend to re-use the point data to draw multiple objects, you have to make a copy of the points and then modify/render them...

    function fillPolygon(dc, sx, sy, dx, dy, theta, points) {
    var sin = Math.sin(theta);
    var cos = Math.cos(theta);

    var coords = new [points.size()];
    for (var i = 0; i < points.size(); ++i) {

    // make a copy so as to not modify the points array
    coords= [ points[0] * sx, points[1] * sy ];

    var x = (coords[0] * cos) - (coords[1] * sin) + dx;
    var y = (coords[0] * sin) + (coords[1] * cos) + dy;

    coords[0] = x;
    coords[1] = y;
    }

    dc.fillPolygon(coords);
    }
    [/code]

    This is extremely helpful travis.vitek. Thank you for sharing!