PDA

View Full Version : Sprite rotation, math problem



Senap
02-01-2008, 09:07 PM
Hi

I'm using Andorra2D (http://www.pascalgamedevelopment.com/viewtopic.php?t=4123&highlight=andorra) to make a utility, similar to a map editor, for a game. The utility displays several rectangular zones and I want to connect all of these with lines.

Instead of simply drawing static lines on the canvas, I am trying to use sprites to connect the rectangular sprites. This way I can drag the lines and manipulate them in various ways along with storing variables in the sprite objects.

I am having trouble figuring out how to determine the rotation angle of the line sprite. Can you give me pointers as to how I can solve this math problem? I have the x/y positions of two rectangles and I can of course figure out the length between the two, but I'm stuck and can't get any further.

Hopefully someone can help me, I feel stupid for not being able to solve this on my own :oops:

chronozphere
02-01-2008, 10:15 PM
I recall having a function for that. I've looked it up:


function Direction2d(x1,y1,x2,y2: single): single;
begin
Result := radtodeg( arctan2((x2-x1) , (y2-y1)) )
end;


The use of arctan2 is the key to the sollution of your problem. You must make sure that the second parameter is not zero. So you should add some if and then's to handle those cases.

The routine returns the angle in degrees. You only have to figure out, in which direction "zero degrees" points.

Hope to have helped you ;)

Traveler
02-01-2008, 11:05 PM
moved to math section

Pyrogine
02-01-2008, 11:36 PM
const
{ Degree/Radians }
P2D_RadToDeg = 180.0 / PI;
P2D_DegToRad = PI / 180.0;


type
{ TP2DVector3s }
PP2DVector3s = ^TP2DVector3s;
TP2DVector3s = packed record
x: Single;
y: Single;
z: Single;
end;

procedure TP2DMath.VectorSub(aSrcVector, aDestVector: PP2DVector3s);
begin
aSrcVector.x := aSrcVector.x - aDestVector.x;
aSrcVector.y := aSrcVector.y - aDestVector.y;
aSrcVector.z := aSrcVector.z - aDestVector.z;
end;

function TP2DMath.VectorMag(aSrcVector: PP2DVector3s): Single;
begin
with aSrcVector^ do
begin
Result := Sqrt((X*X) + (Y*Y));
end;
end;


procedure TP2DMath.VectorNorm(aSrcVector: PP2DVector3s);
var
Len, OOL: Single;
begin
Len := VectorMag(aSrcVector);

if Len <> 0 then
begin
OOL := 1.0 / Len;
with aSrcVector^ do
begin
X := X * OOL;
Y := Y * OOL;
end;
end;
end;


function TP2DMath.VectorAngle(aSrcVector, aDestVector: PP2DVector3s): Single;
var
xoy: Single;
R : TP2DVector3s;
begin
R := aSrcVector^;

VectorSub(@R, aDestVector);

VectorNorm(@R);

if R.y = 0 then
begin
R.y := 0.001;
end;

xoy := R.x/R.y;

Result := ArcTan(xoy) * P2D_RadToDeg;
if R.y < 0 then
Result := Result + 180.0;
end;


This code is from Pyrogine2D which I use in many places in the library. VectorAngle will give you the angle in degrees between two points. I use this in the polygon class (keeps track of rotated line segments) and in the Entity class which provides several rotateToXXX routines (rotate to angle, rotate to position and so on). Note it properly handles the situation that chronozphere pointed out. Hope this helps.

Senap
03-01-2008, 09:43 PM
Thanks so much guys, I'll try out your solutions and report back.

EDIT: chronozphere and Pyrogine, I tried out your suggestions and it works great - thanks again! :D

/ Senap