SRL Archive - Help and Support

Creating a TPACircle


Cstrike

2010-12-04 22:09:27

I want to create code where I'm able to generate a TPA from X points (realistic amount of points), but I don't know how to go about doing this.

For example:

TPAFromCircle (Radius, NumberOfTPoints: Integer; Center: TPoint): TPointArray;


For example, NumberOfTPoints would return this:
4:

8:
Image broken

One way I was thinking of it was dividing 2*pi radians by NumberOfTPoints, doing some trigonometry to find out:

Use sine/cosine laws to get the x/y changed, then apply that to the center point.
Is there an easier way to do this? Are there any functions we have that will do this for me?

Wanted

2010-12-04 22:36:09

{.include SRL\SRL.scar}
{.include SRL\SRL\Misc\Debug.scar}

function PolygonCorners(NumberOfPoints, Radius: LongInt; Center: TPoint): TPointArray;
var
AngleShare, Angle: Extended;
I: LongInt;
begin
SetLength(Result, NumberOfPoints);
AngleShare := 360 / NumberOfPoints;
for I := 0 to NumberOfPoints - 1 do
begin
Angle := AngleShare * I;
Result[I] := Point(Round(Radius * Sin(Angle * Pi / 180)) + Center.X, Round(Radius * Cos(Angle * Pi / 180)) + Center.Y);
end;
end;

var
TPA: TPointArray;

begin
SetUpSRL;
TPA := PolygonCorners(8, 100, Point(50, 50));
DebugTPA(TPA, '');
end.

Plugin would probably be faster.

Cstrike

2010-12-04 22:41:51

Looks great :)
When you run that in Simba, does it crash for you at all? If not, just me then.
I have the includes and all set up properly

Wanted

2010-12-04 22:47:17

From: cstrike
Looks great :)
When you run that in Simba, does it crash for you at all? If not, just me then.
I have the includes and all set up properly


Does for me, but only if you call DebugTPA or whatever, not sure..

Edit: Ah, simba can't handle negatives in the bitmap canvas or some shit, change the center from 50, 50 to 150, 150

Bad Boy JH

2010-12-05 20:48:18

Don't know if you still want it, but I think this looks better…
function TPAFromCircle (Radius, NumberOfTPoints: Integer; Center: TPoint): TPointArray;
var
I: Integer;
begin
SetLength(Result, NumberOfTPoints);
for I := 0 to NumberOfTPoints - 1 do
Result[i] := Point(Round(Sin(Radians(360.0 * I / NumberofTPoints)) * Radius) + Center.x, Round(Cos(Radians(360.0 * I / NumberofTPoints)) * Radius) + Center.y);
end;

Wanted

2010-12-05 21:07:01

From: Bad Boy JH
Don't know if you still want it, but I think this looks better…
function TPAFromCircle (Radius, NumberOfTPoints: Integer; Center: TPoint): TPointArray;
var
I: Integer;
begin
SetLength(Result, NumberOfTPoints);
for I := 0 to NumberOfTPoints - 1 do
Result[i] := Point(Round(Sin(Radians(360.0 * I / NumberofTPoints)) * Radius) + Center.x, Round(Cos(Radians(360.0 * I / NumberofTPoints)) * Radius) + Center.y);
end;


Mind you, the only reason I did not code it like this^ is because mine will be slightly faster as it uses variables instead of multiplying multiple times.

Bad Boy JH

2010-12-06 07:40:11

I misread your code the first time, and thought it would stuff up under cetrain conditions, however I was inccorrect, one thing I would change on your code… you could just have the angle as Radians in the first place.
function PolygonCorners(NumberOfPoints, Radius: LongInt; Center: TPoint): TPointArray;
var
AngleShare, Angle: Extended;
I: LongInt;
begin
SetLength(Result, NumberOfPoints);
AngleShare := 2 * Pi NumberOfPoints;
for I := 0 to NumberOfPoints - 1 do
begin
Angle := AngleShare * I;
Result[I] := Point(Round(Radius * Sin(Angle)) + Center.X, Round(Radius * Cos(Angle)) + Center.Y);
end;
end;

Wizzup?

2010-12-06 09:32:37

From: IceFire908
Edit: Ah, simba can't handle negatives in the bitmap canvas or some shit, change the center from 50, 50 to 150, 150


How does it crash? (Also, you shouldn't ever use a negative point since it's not valid. It's basically just out of bounds. But Simba should catch this.)

E: Nevermind. Simba doesn't crash. It just raises an exception because you're accessing invalid points:

Error: Exception: TMWindow.ReturnData: The parameters passed are wrong; xs,ys -50,-50 width,height 201,201 at line 101

Nava2

2010-12-06 10:42:38

From: Bad Boy JH
I misread your code the first time, and thought it would stuff up under cetrain conditions, however I was inccorrect, one thing I would change on your code… you could just have the angle as Radians in the first place.


Try this:
function PolygonCorners(NumberOfPoints, Radius: LongInt; Center: TPoint): TPointArray;
var
AngleShare, Angle: Extended;
i, j: Integer;
begin
SetLength(Result, NumberOfPoints);
AngleShare := 2 * Pi / NumberOfPoints;
j := 0;
dec(NumberOfPoints);
try
for i := 0 to NumberOfPoints do
begin
Angle := AngleShare * j;
Result[i] := Point(Round(Radius * Sin(Angle)) + Center.X, Round(Radius * Cos(Angle)) + Center.Y);
inc(j);
end;
except
errorFound := True;
end;
if (errorFound) then
setLength(Result, j+1);
end;

It should never allow an exception to pass, if it does then it will adjust and just make the array smaller. So if you have a circle that goes over the needed space, it`ll asjust and fix the array. So, there would be a line of cut off points where the points were invalid, however the function will not crash, and the valid points will remain in an array of the appropriate size.

Wizzup?

2010-12-06 11:00:33

From: Nava2
Try this:
function PolygonCorners(NumberOfPoints, Radius: LongInt; Center: TPoint): TPointArray;
var
AngleShare, Angle: Extended;
i, j: Integer;
begin
SetLength(Result, NumberOfPoints);
AngleShare := 2 * Pi / NumberOfPoints;
j := 0;
dec(NumberOfPoints);
try
for i := 0 to NumberOfPoints do
begin
Angle := AngleShare * j;
Result[i] := Point(Round(Radius * Sin(Angle)) + Center.X, Round(Radius * Cos(Angle)) + Center.Y);
inc(j);
end;
except
errorFound := True;
end;
if (errorFound) then
setLength(Result, j+1);
end;

It should never allow an exception to pass, if it does then it will adjust and just make the array smaller. So if you have a circle that goes over the needed space, it`ll asjust and fix the array. So, there would be a line of cut off points where the points were invalid, however the function will not crash, and the valid points will remain in an array of the appropriate size.


Those exceptions are generally not to be caught. :p
As you can see it is trying to copy the client starting from -50,-50, which is just plain nonsense. That's why Simba throws this exception.

Wanted

2010-12-06 12:28:25

From: Bad Boy JH
I misread your code the first time, and thought it would stuff up under cetrain conditions, however I was inccorrect, one thing I would change on your code… you could just have the angle as Radians in the first place.
function PolygonCorners(NumberOfPoints, Radius: LongInt; Center: TPoint): TPointArray;
var
AngleShare, Angle: Extended;
I: LongInt;
begin
SetLength(Result, NumberOfPoints);
AngleShare := 2 * Pi NumberOfPoints;
for I := 0 to NumberOfPoints - 1 do
begin
Angle := AngleShare * I;
Result[I] := Point(Round(Radius * Sin(Angle)) + Center.X, Round(Radius * Cos(Angle)) + Center.Y);
end;
end;


Ah I see.

Nava2

2010-12-06 12:37:42

I made some logic errors:

function PolygonCorners(NumberOfPoints, Radius: LongInt; Center: TPoint): TPointArray;
var
AngleShare, Angle: Extended;
i, j: Integer;
begin
SetLength(Result, NumberOfPoints);
AngleShare := 2 * Pi / NumberOfPoints;
j := 0; errorFound := False;
dec(NumberOfPoints);
for i := 0 to NumberOfPoints do
try
Angle := AngleShare * j;
Result[j] := Point(Round(Radius * Sin(Angle)) + Center.X, Round(Radius * Cos(Angle)) + Center.Y);
inc(j);
except
errorFound := True;
end;
if (errorFound) then
setLength(Result, j+1);
end;