Archive

Archive for May 3, 2012

Scale a polygon?

May 3, 2012 1 comment

Following up on fun “bare-bones” retro coding, here is how you scale a polygon. While I can’t think of a single use for this in a real life application, I can paradoxically also think of a million uses for it. For instance, if you are making a paint program which uses polygon based brushes – you could use this to scale the same shape up and down. Well, I’ll leave the creativity up to you — it’s retro time!

Note: The example below is just one way of doing things. As a friend of mine pointed out, it would be considerably faster to use a matrix / linear approach.

Once again, this is written in Smart Mobile Studio‘s version of object pascal, but it should be easy to get it running on vanilla Delphi 🙂

type
TPointArray = array of TPoint;

Function ScalePolygon(factor:Float;InPoints:TPointArray;
         Const centerX,centerY:Float):TPointArray;
var
  i:   integer;
  r,p: float;
begin
  result.SetLength(inPoints.length);
  if inPoints.Length>0 then
  begin
    for i := 0 to inPoints.high do
    begin
      r:= factor * sqrt(sqr(InPoints[i].X - centerX) + sqr(InPoints[i].Y - centerY));
      p:= arcTan2(InPoints[i].Y - centerY, InPoints[i].X - centerX);
      Result[i].X := Round(centerX + r * cos(p));
      Result[i].Y := Round(centerY + r * sin(p));
    end;
  end;
end;

Incidentaly, here is Spaceballs – the Amiga polygon demo par excellence:

Old school but still cool

Old school but still cool

Rotate a polygon

May 3, 2012 Leave a comment

One of the benefits of writing an RTL from scratch is that you get the chance to wake up old gems from the past. For instance, how do you rotate a polygon (array of TPoints) around a variable axis? While my work at the office is extremely serious, I must admit that playing around with these routines is very entertaining.

Note: The example below is just one way of doing things. As a friend of mine pointed out, it would be considerably faster to use a matrix / linear approach.

While this example is for Smart Mobile Studio‘s flavour of object pascal, it should be fairly easy to get it running under vanilla Delphi or freepascal. Enjoy the retro feeling 🙂

type
TPointArray = array of TPoint;

function Rotate(const angle:Float;
         const aValues:TPointArray;
         const centerX,centerY:Float):TPointArray;
var
  i:    integer;
  r,p:  Float;
begin
  if aValues.Length>0 then
  Begin
    result.SetLength(aValues.Length);
    for i := 0 to aValues.length-1 do
    begin
      r:=sqrt(sqr(aValues[i].X - centerX) + sqr(aValues[i].Y - centerY));
      p := angle + arcTan2(aValues[i].Y - centerY, aValues[i].X - centerX);
      Result[i].X := Round(centerX + r * cos(p));
      Result[i].Y := Round(centerY + r * sin(p));
    end;
  end;
end;

Here is one way of using it:

  (* setup our array of points *)
  mItems.SetLength(0);
  mItems.add(Tpoint.Create(10,10));
  mItems.add(TPoint.Create(100,10));
  mItems.add(TPoint.create(100,100));
  mItems.add(TPoint.create(10,100));

  (* do the mambo *)
  mItems:=rotate(fbValue,mItems,gameview.width div 2,gameview.height div 2);

  (* Paint on our HTML5 canvas *)
  Canvas.MoveToF(mItems[0].x,mItems[0].y);
  for i:=1 to mItems.high do
  canvas.linetoF(mItems[i].x,mItems[i].y);
  canvas.linetoF(mItems[0].x,mItems[0].y);

And the end result (the cube rotates around the screen):

A static image hardly does it justice

A static image hardly does it justice

Here is a buffer we prepared earlier, using the numbers of life:

Archimedes spiral

Archimedes spiral + extra rotation