Archive
Scale a polygon?
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:
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); 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):
Here is a buffer we prepared earlier, using the numbers of life:
You must be logged in to post a comment.