SRL Archive - Help and Support

Can some one help with some TPA stuff.


Noob King

2012-10-05 02:23:09

Before I start confusing you with my thoughts from my head, here is a picture of what I am trying to do.


There needs to be 4 objects
~Legend~
Black Boxes: Objects
Red Box: Square around all the current objects
Green Box: Missing object (Will always be at a 90 degree angle between two black boxes.)

I can find the Black Boxes and the Red Box, but I can't find where the last box (Green Box) should be (so which corner of the Red Box doesn't have a Black Square).

I find the Red Box with a TPA, and the Black Boxes from splitting the TPA and checking lengths. I thought about comparing the distance of the black boxes coordinates, but the black boxes won't always be the same distance from each other horizontally, so I don't think that will work.

Can anyone suggest how I might accomplish this?

Runaway

2012-10-05 02:43:29

Is there always a 90 degree angle (excluding the camera height) between the green box and the 2 closest black boxes?

Noob King

2012-10-05 02:47:19

From: Runaway
Is there always a 90 degree angle (excluding the camera height) between the green box and the 2 closest black boxes?


Yes. Sorry if it is an obvious solution, I am not the best with Math / Geometry.

Runaway

2012-10-05 14:55:08

From: Noob King
Yes. Sorry if it is an obvious solution, I am not the best with Math / Geometry.


It's not very obvious :p

I would use some sort of minesweep-esque method. I highly doubt this is the best way to do it, but it will work and that's a good start! Here's some code to explain what I mean:


program new;
{$I SRL/SRL.simba}

type
TRadial = record
Length: Integer;
Angle: Extended;
end;

function RadialFromPts(P1, P2: TPoint): TRadial;
begin
Result.Length := Round(Hypot(P2.x - P1.x, P2.y - P1.y));
Result.Angle := Degrees(FixRad((ArcTan2(P1.y - P2.y, P1.x - P2.x) + Radians(90)) - Pi));
end;

var
TPA: TPointArray;
tmpTPA: array[0..2] of TPoint;
tmpP: TPoint;
Val: array[0..1] of Integer;
Len, Dist, tmpDist, a, p, i, ii: Integer;
Angles: array[0..1] of Extended;
tmpA: Extended;

begin
// Simulate the situation
SetLength(TPA, 0);
while (Length(TPA) < 3) do
begin
for i := 0 to 1 do
begin
case Random(2) of
0: Val[i] := 50;
1: Val[i] := 100;
end;
end;
tmpP := Point(Val[0], Val[1]);
if PointInTPA(tmpP, TPA) then
Continue;
Inc(Len);
SetLength(TPA, Len);
TPA[Len - 1] := tmpP;
end;

// Check angles between points
for i := 0 to High(TPA) do
begin
a := 0;
for ii := 0 to High(TPA) do
begin
if (i = ii) then
Continue;
Angles[a] := RadialFromPts(TPA[i], TPA[ii]).Angle;
Inc(a);
end;
tmpA := FixD(Angles[1] - Angles[0]) / 90.0;
//Writeln(tmpA);
case (tmpA - Floor(tmpA)) of
0..0.1, 0.9..1: tmpTPA[2] := TPA[i];
else
begin
tmpTPA[p] := TPA[i];
Inc(p);
end;
end;
end;

// Extrapolate missing point
i := 0;
Dist := RadialFromPts(tmpTPA[0], tmpTPA[1]).Length;
while (i < 2) and not InRange(tmpDist, Dist - (Dist / 10), Dist + (Dist / 10)) do
begin
tmpP.x := tmpTPA[i].x;
tmpP.y := tmpTPA[iAbs(i - 1)].y;
tmpDist := RadialFromPts(tmpP, tmpTPA[2]).Length;
Inc(i);
end;

//Writeln(TPA);
Writeln(tmpTPA);
Writeln(tmpP);
end.

It seems to be working with the example points I'm using. Basically, the script checks the 3 angles between the known points and finds the 2 points that don't form a 90 degree angle with the others. It can then extrapolate the missing point by using the x & y coords from those 2 points.

If you're confused about any of the code, let me know. I can explain it much more in-depth if you'd like :)

Noob King

2012-10-06 23:26:18

From: Runaway
It's not very obvious :p

I would use some sort of minesweep-esque method. I highly doubt this is the best way to do it, but it will work and that's a good start! Here's some code to explain what I mean:



It seems to be working with the example points I'm using. Basically, the script checks the 3 angles between the known points and finds the 2 points that don't form a 90 degree angle with the others. It can then extrapolate the missing point by using the x & y coords from those 2 points.

If you're confused about any of the code, let me know. I can explain it much more in-depth if you'd like :)


I will give that a try, Thank-you :rolleyes: