Game Development Community

Acquiring a direction that points to the center of a circle

by Dave Calabrese · in Technical Issues · 06/24/2005 (5:42 am) · 17 replies

Need to code up a quick bit of TorqueScript that will get the rotational angle for pointing at the center of a circle. Currently, I have a function that will draw objects in a circle, and I next just need to make everything point into the center. Here's the function as it currently stands:

function worldPositionController_getWorldPositions( %totalIncrements,
                                                    %distanceFromCenter,
                                                    %centerX,
                                                    %centerY,
						    %zCoord)
{
   $returnObject = new scriptObject();
   %pi = 3.14159;
   %rotationAngle = ( 360 / %totalIncrements);
   %currentRotation = 0;
   for (%i = 0; %i < %totalIncrements; %i++)
    {
      %objCount++;
      %currentAngle = %i/%totalIncrements * 2 * %pi;
      %x = %distanceFromCenter * mCos(%currentAngle) + %centerX;
      %y = %distanceFromCenter * mSin(%currentAngle) + %centerY;
      %r = %currentRotation = (%currentRotation) + (%rotationAngle) - 180;
      $returnObject.positions[%objCount] = ( %X SPC %Y SPC %zCoord SPC "0 0 1" SPC %R);
    }
    
  return $returnObject;
}

The function works like a dream - until it comes down to getting that darned rotation. The objects seem to start rotating in the right direction, but eventually start pointing way outside of the circle. It seems like all I would need to do is the above - or something along the lines of getting the vector from the point on the outside of the circle to the point on the inside of the circle.

Think any of you math guru's out there could lend a hand?

Thanks,
-Dave C.

#1
06/24/2005 (5:58 am)
I cant see where you rotate object to look at the center of the circle. You need some thing like lookAt(*coords*) or just rotate you object on the same angel that goed for it position computation.
#2
06/24/2005 (6:20 am)
In the code, I'm first acquiring the angle to rotate:

%rotationAngle = ( 360 / %totalIncrements);
   %currentRotation = 0;


And then rotating the transform for that matrix by that amount on each pass through the for loop.

%r = %currentRotation = (%currentRotation) + (%rotationAngle) - 180;


At least, that's what I'm trying to do...
#3
06/24/2005 (7:37 am)
In the code, I'm first acquiring the angle to rotate:

%rotationAngle = ( 360 / %totalIncrements);
   %currentRotation = 0;


And then rotating the transform for that matrix by that amount on each pass through the for loop.

%r = %currentRotation = (%currentRotation) + (%rotationAngle) - 180;


At least, that's what I'm trying to do...
#4
06/24/2005 (8:08 am)
Look at this

i6.photobucket.com/albums/y245/ViiKzzz/A_2.jpg
3) i=2 currentRotation=0 deg

if I cleary anderstand your code - you need to check your math. Calculate coordinates and angels by hand and see what you have in rezult for each itteration of loop.
#5
06/24/2005 (8:38 am)
Thanks for all the help so far... I really appriciate it! =)

Okay, looked over my code, looked at my math, did some changes, and... it's still not working. Maybe I'm just math-stupid (which I sorta am), but on the calculator, this seriously seems like it should work... (plus I also fixed it so the rotations are now in radians, which appears to be a lot more precise - only now it's pointing more outwards than inwards, and even then is still somewhat off.

function worldPositionController_getWorldPositions( %totalIncrements,
                                                    %distanceFromCenter,
                                                    %centerX,
                                                    %centerY,
						    %zCoord)
{
   $returnObject = new scriptObject();
   %pi = 3.14159;
   %rotationAngle = ( 360 / %totalIncrements);
   %currentRotation = 0;
   for (%i = 0; %i < %totalIncrements; %i++)
    {
      %objCount++;
      %currentAngle = %i/%totalIncrements * 2 * %pi;
      %x = %distanceFromCenter * mCos(%currentAngle) + %centerX;
      %y = %distanceFromCenter * mSin(%currentAngle) + %centerY;
      %r = %currentRotation = (%currentRotation) + (%rotationAngle);
      %r = mDegToRad(%r);
      $returnObject.positions[%objCount] = ( %X SPC %Y SPC %zCoord SPC "0 0 1" SPC %R);
    }
    
  return $returnObject;
}

Any ideas?
#6
06/24/2005 (9:13 am)
Not 240 on picture - it must be 270 :)

I too not very good at math, but why you use:
%r = %currentRotation = (%currentRotation) + (%rotationAngle);

I think error is there, maybe this is a solution:
%r = %currentRotation =%currentAngle + 180;

this will work if all of your objects have zero degres rotation when initialized.
#7
06/24/2005 (9:27 am)
Hrm... just tried your suggestion of..
%r = %currentRotation =%currentAngle + 180;

However, it caused all the objects in the ring to now face the EXACT SAME direction, instead of all pointing in the center.


My reasoning behind using
%r = %currentRotation = (%currentRotation) + (%rotationAngle);


Was because I figured I would need to first get the angle that each object would have to face based on how many objects that this ring is made out of, which would be %rotationAngle. %currentRotation would start at 0, then go up in intervals on each pass. So if we had 4 objects, then %rotationAngle = 90, making the rotation amount go up by 90 each time. My rotation angles would then be, in succession: 90, 180, 270, 360.
#8
06/24/2005 (10:14 am)
i6.photobucket.com/albums/y245/ViiKzzz/a1.jpg
step by step:
for example all your objects rotated at 0 deg by default
when you calculate coords of objects
%x = %distanceFromCenter * mCos(135) + %centerX;
%y = %distanceFromCenter * mSin(135) + %centerY;

you get x,y and if you rotate object for the same angel (stored in currentAngle) your object will by directed opposing to the center (135deg), and if you add 180 deg for rotation again it will dericted execly to the center (315).
#9
06/24/2005 (11:09 am)
Dave I cant be sure without trying it myself but it looks to me like these are you problems:

in the first code snippet:

%r = %currentRotation = (%currentRotation) + (%rotationAngle) - 180;

why are you subtracting 180? if you dont subtract 180 this should work.

in the second code snippet:

%r = mDegToRad(%r);

you can use radians if youre more familiar with them but torque uses degrees for its rotation parameter. it seems to me if you use the first one without the -180 it should work.

you could also do:

%r=(%i+1)*(%rotationAngle);

i also just realized that it depends greatly on each objects initial rotation.
#10
06/24/2005 (11:18 am)
I think this thread is highly related:
www.garagegames.com/mg/forums/result.thread.php?qt=28227

edit: nice illustrations, viktor !
#11
06/24/2005 (12:57 pm)
Thank's for everyone's help, I appriciate it all! =)

I've been jumping back to this through the day when work allows it... been trying what everyone says here, but still having no luck. It's just ending up looking like a 'sawblade' (in terms of where things are pointing), but with some teeth pointing inward. The objects are rotating, but they're not always facing the center... to give people an idea of what all I've tried, I've just been commenting things out as they fail:


function worldPositionController_getWorldPositions( %totalIncrements,
                                                    %distanceFromCenter,
                                                    %centerX,
                                                    %centerY,
						    %zCoord)
{
   $returnObject = new scriptObject();
   %pi = 3.14159;
   %rotationAngle = ( 360 / %totalIncrements );
   %currentRotation = 0;
   error("-------------------");
   for (%i = 0; %i < %totalIncrements; %i++)
    {
      %objCount++;
      %currentAngle = %i/%totalIncrements * 2 * %pi;
      error(mRadToDeg(%currentAngle) );
      %x = %distanceFromCenter * mCos(%currentAngle) + %centerX;
      %y = %distanceFromCenter * mSin(%currentAngle) + %centerY;
      //%r = %currentRotation = (%currentAngle) + 180;
      //%r = %currentRotation = (%currentRotation) + (%rotationAngle);
      //%r = %currentAngle - 180;
      //%r = %currentRotation = %currentRotation + (%rotationAngle + 180) % 360;
      //%r = ( (%currentAngle) + 180 ) % 360
      %R = (mRadToDeg(%currentAngle)) - 180;
      //%R = (%R) - ( (%R) * 2 );
      $returnObject.positions[%objCount] = ( %X SPC %Y SPC %zCoord SPC "0 0 1" SPC %R);
    }
    error("-------------------");
    
  return $returnObject;
}

I get the feeling this is gonna be a loooong night.
#12
06/24/2005 (12:58 pm)
I guess one thing that is really confusing me, is why I can't just use the value of %currentAngle after it's converted to an angle. In the echo, it seems like it should work... just make it a negative and it's good to go according to the math. But that never actually display's correctly...
#13
06/24/2005 (1:32 pm)
You can use current angle, but the implementation is largely dependent upon the objects initial relative rotation when its created. if the object is facing the center at 0 degrees, then at currentangle=45 degrees, you should be able to rotate the object by the exact same angle to get it to face the center, according to the math.
#14
06/24/2005 (2:00 pm)
Dave -
can you describe again what you want this function to do,
without using code ?

function doSomething( %totalIncrements,
                      %distanceFromCenter,
                      %centerX,
                      %centerY,
                      %zCoord)
#15
06/24/2005 (2:09 pm)
This function is to get the position of an array of objects around a center point, with each object having its X axis pointing at the center point. Since the number of objects and the distance from the center can change, and the center point itself can change, AND the height can change, this all has to be input into this function. It will then return an object that contains an array which contains the positions.


And this function works great and perfectly fine. The only problem with it is the objects X axis is not pointing at the center, they are instead pointing in all other directions.
#16
06/24/2005 (3:24 pm)
Gotcha.

your code looks rightish but if it's not working there must be something wrong.

so,
first figure out for sure whether you should be returning degrees or radians:
try hardwiring the R value to a constant 90, and see if that gets what you would expect.
if it doesn't, try hardwiring it to PI/2.
If neither of those give you guys who are looking 90-degrees away from when you hardwire them to zero,
somethings deeply wrong.

assuming it wants degrees instead of radians,
in your code above it seems like if your replaced
%R = (mRadToDeg(%currentAngle)) - 180;
with:
%R = (%rotationAngle * %i) - 180;
it should work.

assuming it's radians, try this instead:
%R = mDegToRad((%rotationAngle * %i) - 180);



as for why your current code isn't working, i don't know, so this likely may not help.
is there possibly some weird order of operations or conversion to integer going on in the line
%currentAngle = %i/%totalIncrements * 2 * %pi;
?
#17
06/24/2005 (3:39 pm)
W00t!!! I got it to work!!!

Here's the final code:

function worldPositionController_getWorldPositions( %totalIncrements,
                                                    %distanceFromCenter,
                                                    %centerX,
                                                    %centerY,
						    %zCoord)
{
   $returnObject = new scriptObject();
   %pi = 3.14159;
   %rotationAngle = ( 360 / %totalIncrements );
   %currentRotation = 0;
   for (%i = 0; %i < %totalIncrements; %i++)
    {
      %objCount++;
      %currentAngle = %i/%totalIncrements * 2 * %pi;
      error(mRadToDeg(%currentAngle) );
      %x = %distanceFromCenter * mCos(%currentAngle) + %centerX;
      %y = %distanceFromCenter * mSin(%currentAngle) + %centerY;
      %R = mDegToRad((%rotationAngle * %i) + 180);
      $returnObject.positions[%objCount] = ( %X SPC %Y SPC %zCoord SPC "0 0 -1" SPC %R);
    }
    
  return $returnObject;
}

Thanks everyone for your help!! You guys rock!
-Dave C.