### 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

## Rotate a polygon

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);

(* 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

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

Archimedes spiral + extra rotation