rotation around point

If you are a new Irrlicht Engine user, and have a newbie-question, this is the forum for you. You may also post general programming questions here.
Post Reply
serengeor
Posts: 1712
Joined: Tue Jan 13, 2009 7:34 pm
Location: Lithuania

rotation around point

Post by serengeor »

I'm not very good at vector maths so I'm asking you guys to help me figure out on how to achieve this kind of rotation (don't know if thats the right word to use )

This is a picture illustrating what I want this to make:
Image

So the object is black circle and it moves in the direction of yellow arrow
my other object has to go behind the black circle in a circular motion (have constant distance from black circle)

I need to make this work with angular velocity.
Working on game: Marrbles (Currently stopped).
DarkDepths
Posts: 126
Joined: Sun Apr 02, 2006 1:21 am
Location: Canada

Post by DarkDepths »

Perhaps I'm misunderstanding the question, so I'd ask that you please clarify.

It sounds to me like you want the point of Origin for th rotation to be the blackCircleObject.

I'm afraid I'm not well enough acquainted with Irrlicht to tell you how this can be achieved specifically. There may be a function which will allow you to set the Node's rotation origin. I don't know about that, but if there is not one, then I think I might do something like:

1) Create an empty SceneNode at (0,0,0).
2) Create the blackCircle object.
3) Create the Rotating object at (radius, 0, 0).
4) Attach the Rotating object as a child of the empty SceneNode.
5) Every frame, move the empty SceneNode to the same position as the blackCircle object.
6) Rotate the empty SceneNode.


I think that would achieve what you want.... I think :D
serengeor
Posts: 1712
Joined: Tue Jan 13, 2009 7:34 pm
Location: Lithuania

Post by serengeor »

thanks for this idea :wink:, but I would like to do this the maths way( I mean I want to learn how this can be done the 'maths' way with sines and cosines)


So any ideas how this could be done ? :roll:
Working on game: Marrbles (Currently stopped).
DarkDepths
Posts: 126
Joined: Sun Apr 02, 2006 1:21 am
Location: Canada

Post by DarkDepths »

This is just off the top of my head, and it is also 4:45 AM, so please excuse me if the following makes absolutely no sense!

To start, I'll be working on only a 2D, xz plane.

First of all, you said that the rotating object will have a constant radius, and thus it will travel in a circular motion around the "black circle" (which, from now onwards I will simply call the "origin"). So, if we look at this system as a simple circle, the problem really comes down to trying to find the x,z coordinates at a certain point on the circle, so that if you wish to rotate the object around the origin, you can predict it's next position, given that you know it's "orbiting speed."

Fortunately, it shouldn't be too difficult. If we look at as a circle, then, no matter which point we pick on the circumference, if we draw a line from that point to the origin (tracing the radius to that point), we can also draw a vertical line from the point on the circumference such that it's secondary 'z-value' is equal to the 'z-value' of the origin, and a horizontal line from the origin to the secondary end-point of the vertical line. This gives us a right angle triangle.

Before I go any further, I need to state two things. First, I assume that your method will take an angle for the xz plane. Secondly, I assume this angle is between 0 - 360.

OK, now, the angle you pass in will be interpreted as the internal angle, ie the angle between the hypotenuse and the horizontal line. To get this angle, you will need to know which quadrant the point is in, I suppose, so you would have to do something like:

float[] getPositionOnCircle(float angle, float radius, float originX, float originY)

Code: Select all


int quad;
float tZ, tX, newX, newZ, tAngle;

if ( angle >= 0 && angle < 180 )
{
if (angle < 90)
{
quad = 1;
tAngle = angle;
}
else
{
quad = 2;
tAngle = 180 - angle;
}
}
else
{
if (angle <= 270)
{
quad = 3;
tAngle = abs(180-angle);
}
else
{
quad = 4;
tAngle = 360 - angle;
}
}

// Now to get the Z-Offset
tZ = radius*sin(tAngle);

// And with a little help from our friend Pythagoras...
tX = sqrt((radius^2) - (tZ^2));

// These are only Offsets though, so we need to find the actual location:

switch (quad)
{
case 1:
newX = originX+tX;
newZ = originY-tZ;
break;

case 2:
newX = originX - tX;
newZ = originY - tZ;
break;

case 3:
newX = originX - tX;
newZ = originY + tZ;
break;

case 4:
newX = originX + tX;
newZ = originY + tZ;
break;

default:
break; 
}

// Now you can just put newX and newY into an array of floats and return it.

If you want to add a third dimension and also retrieve the Y value, you should be able to repeat the process nearly as it is. You will be working on a circle still, but it will be on a different plane. So you will also need to add a dimension for the angle, my suggestion would be a second parameter indicating the "y-angle." This would simply describe the angle between the origin and the point on the y axis.

Again, sorry if none of this makes sense, or if it doesn't work at all, it is way to late/early for me to be trying to do this stuff :D
[/code]
BlindSide
Admin
Posts: 2821
Joined: Thu Dec 08, 2005 9:09 am
Location: NZ!

Post by BlindSide »

Check out core::vector3df rotateXYBy, rotateXZBy and rotateYZBy ;) (They take a "Center" parameter)
ShadowMapping for Irrlicht!: Get it here
Need help? Come on the IRC!: #irrlicht on irc://irc.freenode.net
serengeor
Posts: 1712
Joined: Tue Jan 13, 2009 7:34 pm
Location: Lithuania

Post by serengeor »

I need my second object to orient in the opposite direction of the circle's velocity, what angle do i have to get?
Angle between second object and circles linear velocity? :oops:

Code: Select all

float radius = 200.0f;
float angle = this->player->getLinearVelocity().angle(irrVecToBt(cam->getAbsolutePosition()));
int quad; 	
float tZ, tX, newX, newZ, tAngle; 

if ( angle >= 0 && angle < 180 ) 
{ 
if (angle < 90) 
{ 
quad = 1; 
tAngle = angle; 
} 
else 
{ 
quad = 2; 
tAngle = 180 - angle; 
} 
} 
else 
{ 
if (angle <= 270) 
{ 
quad = 3; 
tAngle = abs(180-angle); 
} 
else 
{ 
quad = 4; 
tAngle = 360 - angle; 
} 
} 

// Now to get the Z-Offset 
tZ = radius*sin(tAngle); 

// And with a little help from our friend Pythagoras... 
tX = sqrt((radius*radius) - (tZ*tZ)); 

// These are only Offsets though, so we need to find the actual location: 

switch (quad) 
{ 
	case 1: 
	newX = this->player->getWorldTransform().getOrigin().getX() +tX; 
	newZ = this->player->getWorldTransform().getOrigin().getZ() -tZ; 
	break; 
	
	case 2: 
	newX = this->player->getWorldTransform().getOrigin().getX() - tX; 
	newZ = this->player->getWorldTransform().getOrigin().getZ() - tZ; 
	break; 
	
	case 3: 
	newX = this->player->getWorldTransform().getOrigin().getX() - tX; 
	newZ = this->player->getWorldTransform().getOrigin().getZ() + tZ; 
	break; 
	
	case 4: 
	newX = this->player->getWorldTransform().getOrigin().getX() + tX; 
	newZ = this->player->getWorldTransform().getOrigin().getZ() + tZ; 
	break; 
	
	default: 
	break; 
} 

	vec.X = newX ;
	vec.Z =	newZ;
	vec.Y = this->player->getWorldTransform().getOrigin().getY()+150;
	this->cam->setPosition(vec);
	this->cam->setTarget(irr::core::vector3df(this->player->getWorldTransform().getOrigin().getX(),this->player->getWorldTransform().getOrigin().getY(),this->player->getWorldTransform().getOrigin().getZ()));
	cam->updateAbsolutePosition();
doesn't seem to work :cry:
Working on game: Marrbles (Currently stopped).
DarkDepths
Posts: 126
Joined: Sun Apr 02, 2006 1:21 am
Location: Canada

Post by DarkDepths »

Hey, if you are trying to use my code, then I think that 0 degrees would lie on the x-axis (positive), and 180 would lie on the x-axis (negative). So, you just need to know what direction the origin Object is moving in in this angle system. This should be fairly simple to get. Once you have that, the angle you want is simply abs(originObjectsAngle - 180);

Also, WHY AM I STILL AWAKE!!!! :P
DarkDepths
Posts: 126
Joined: Sun Apr 02, 2006 1:21 am
Location: Canada

Post by DarkDepths »

Well, now that Blindside has made us aware of these functions, it seems a waste not to use them, or at least try to. It would make for much more elegant, and readable code, in any case.

So, I think the function you want is rotateXZBy(degrees, center);

Now just to fill in the blanks.

First, the center is easy: player->getAbsolutePosition();

Degrees might be a bit more tricky, there may be a nice function for that too, but it's now 7:04 AM and I am too tired to search for it :) So instead, I will try and show a simple way of figuring it out.

You will need to store the x,y,z coordinates of the player from the previous frame.

So you can do something like:

Code: Select all

float prevX, prevZ;

// Whenever you move the player do something like:
prevX = player->getAbsolutePosition().X;
prevZ = player->getAbsolutePosition().Z;

// -- moving code --
To find the angle in which the player traveled, then, you just do simple math:

Code: Select all

float deltaX = player->getAbsolutePosition().X - prevX;
float deltaZ = player->getAbsolutePosition().Z - prevZ;

float tempAngle = atan(deltaz/deltax) - 180;

//But, I think that rotateXZBy does rotates by a specified amount, not to a specific angle, so we need to get the current rotation of the object, and subtract.

float angle = yourObject->getRotation().Y - tempAngle;

// Then, rotate!

yourObject->rotateXZBy(angle, player->getAbsolutePosition());

Again, I'm not going to garuntee that this will work, and you might need to alter the code (I've been dealing in Java as of late :P), but I think this should do the sort of thing you are after.

Oh, and by the way, atan is in "cmath.h" I think.

Good luck, again :P
serengeor
Posts: 1712
Joined: Tue Jan 13, 2009 7:34 pm
Location: Lithuania

Post by serengeor »

I would like it to rotate according to LinearVelocity (Bullet physics vector)
and not by objects rotation because my object rotates on all axis since its a physics object ( sphere )
Working on game: Marrbles (Currently stopped).
Iyad
Posts: 140
Joined: Sat Mar 07, 2009 1:18 am
Location: Montreal, Canada

Post by Iyad »

You could take a look at the FlyCircle animator, there is already the algorithm written, all you have to do is to tweak it a bit.
#include <Iyad.h>
serengeor
Posts: 1712
Joined: Tue Jan 13, 2009 7:34 pm
Location: Lithuania

Post by serengeor »

Iyad wrote:You could take a look at the FlyCircle animator, there is already the algorithm written, all you have to do is to tweak it a bit.
You should trust people more, I have tried at least 6~ algorithms so far and all of them gave me a messed up result. like camera, the best one so far was the one I had 'invented' :lol: It followed the sphere pretty good but the radius that I gave would only be the max radius for some reason, Tough now I wish I hadn't deleted the code.
I'll try to make this thing myself, still waiting for your suggestions tough
:wink:
Working on game: Marrbles (Currently stopped).
kaliber
Posts: 117
Joined: Sat Jan 17, 2009 12:51 pm

Post by kaliber »

maybe you can use third person camera algorithm

change the camera with the object you want to rotate
Post Reply