getting a vector's angle, modifications

Post those lines of code you feel like sharing or find what you require for your project here; or simply use them as tutorials.
Post Reply
Mirror
Posts: 218
Joined: Sat Dec 01, 2007 4:09 pm

getting a vector's angle, modifications

Post by Mirror »

I would like to suggest that the getHorizontalAngle ( in vector3d.h ) gets replaced by the following function for two reasons :

a) the following is faster by 50%

b) it returns the angles in a more "correct" way : the angles are measured from (0,1,0) which coincides with the default upvector and also coincides with the default "north pole", which makes this point (0,1,0) a better candidate for the point from which we should count the angles. Coinciding with the default upvector means that you can just do a vec.rotateXZby(-angle.Y,center); vec.rotateYZby(-angle.X,center); in order to align "vec" with the (0,1,0) axis.

Code: Select all

		vector3d<T> getPolarCoordinates()
		{
			vector3d<T> angle=vector3d<T>(0,0,0);
			f32 length=getLength();

			if (length) { 

				if (X!=0) {
					if (X < 0) angle.Y = 90 + (T)atan(Z / X) * RADTODEG;
					else angle.Y = 270 + (T)atan(Z / X) * RADTODEG;
				}
				else {
					if (Z>=0) angle.Y=0;
					else angle.Y=180;
				}

				angle.X = (T)acos(Y / length) * RADTODEG;
			}

			return angle;
		}
test app with which you can verify the functionality :

Code: Select all

#include "stdafx.h"
#include "time.h"
#include <irrlicht.h>

using namespace std;

using namespace irr;

using namespace core;
using namespace scene;
using namespace video;
using namespace io;
using namespace gui;

#pragma comment(lib, "Irrlicht.lib")
//#pragma comment(linker, "/SUBSYSTEM:windows /ENTRY:mainCRTStartup")
vector3df ppos;
f32 thi,phi,chi;

vector3df ReturnPolarCoordinates() {
		
			vector3df angle=vector3df(0,0,0);
			f32 length=ppos.getLength();

			if (length) { 

				if (ppos.X!=0) {
					if (ppos.X < 0) angle.Y = 90 + atan(ppos.Z / ppos.X) * RADTODEG;
					else angle.Y = 270 + atan(ppos.Z / ppos.X) * RADTODEG;
				}
				else {
					if (ppos.Z>=0) angle.Y=0;
					else angle.Y=180;
				}

				angle.X = acos(ppos.Y / length) * RADTODEG;
			}

			return angle;
}



int main(int argc, char *argv[])
{
	core::vector3df ang1, ang2, ang3, cen=vector3df(0,0,0);
	int i;
	IrrlichtDevice *device = createDevice(video::EDT_DIRECT3D9, dimension2d<s32>(1024, 768), 32, true, true, false, 0);
	ppos=core::vector3df(100,0,0);

	u32 t1,t2,dt=0;

	printf("initial: X=%f Y=%f Z=%f\n\n", ppos.X, ppos.Y, ppos.Z);
	t1 = device->getTimer()->getRealTime();
	for(i=1;i<=10000000;i++) {
		ang1=ppos.getHorizontalAngle();
	}
	t2 = device->getTimer()->getRealTime();
	dt=t2-t1;
	printf("HA: Thi=%f Phi=%f dt=%d\n\n", ang1.X, ang1.Y, dt);

	t1 = device->getTimer()->getRealTime();
	for(i=1;i<=10000000;i++) {
		ang2=ReturnPolarCoordinates();
	}
	t2 = device->getTimer()->getRealTime();
	dt=t2-t1;
	printf("PC: Thi=%f Phi=%f dt=%d\n\n", ang2.X, ang2.Y, dt);

	t1 = device->getTimer()->getRealTime();
	for(i=1;i<=10000000;i++) {
		ang3=ppos.getPolarCoordinates();
	}
	t2 = device->getTimer()->getRealTime();
	dt=t2-t1;
	printf("gPC: Thi=%f Phi=%f dt=%d\n\n", ang3.X, ang3.Y, dt);
	ppos.rotateXZBy(-ang3.Y,cen);
	ppos.rotateYZBy(-ang3.X,cen);
	printf("rotated: X=%f Y=%f Z=%f\n\n", ppos.X, ppos.Y, ppos.Z);

	device->drop();
	return 0;
}
results :

Code: Select all

initial: X=100.000000 Y=0.000000 Z=0.000000

HA: Thi=0.000000 Phi=90.000000 dt=4555

PC: Thi=90.000000 Phi=270.000000 dt=2101

gPC: Thi=90.000000 Phi=270.000000 dt=2046

rotated: X=0.000001 Y=100.000000 Z=-0.000004
Last edited by Mirror on Sat Jun 07, 2008 7:10 pm, edited 2 times in total.
Halifax
Posts: 1424
Joined: Sun Apr 29, 2007 10:40 pm
Location: $9D95

Post by Halifax »

Nice, but I would just like to say that a better topic name would have probably gotten more reads as it would have been more understandable.

Also, you might want to make a patch, and upload to the patch tracker so that the developers can take care of it. Otherwise, good job.
TheQuestion = 2B || !2B
Mirror
Posts: 218
Joined: Sat Dec 01, 2007 4:09 pm

Post by Mirror »

yes you are right, i changed the topic's title and i also think the best place to put this topic would be in the code snipets section so please some moderator move it there if you consider that, that section is the right place to be.

about the rest, i don't know how to make a patch ( i've only seen mainly rogerborg's patches but i don't know how he makes them ) and i also don't know what i am required to do in order to upload patches in the tracker.
Halifax
Posts: 1424
Joined: Sun Apr 29, 2007 10:40 pm
Location: $9D95

Post by Halifax »

Mirror wrote:yes you are right, i changed the topic's title and i also think the best place to put this topic would be in the code snipets section so please some moderator move it there if you consider that, that section is the right place to be.

about the rest, i don't know how to make a patch ( i've only seen mainly rogerborg's patches but i don't know how he makes them ) and i also don't know what i am required to do in order to upload patches in the tracker.
Ah, okay that's understandable.

To create patches though you will need someway to access the Irrlicht SVN. If you are on Windows, then I recommend TortoiseSVN.

With TortoiseSVN, to create a patch, all you do is edit the file from the SVN, then you save the file, from your IDE or whatever, then go to the file, right-click on it, select TortoiseSVN->Create Patch..., and click that. Then just choose the name and place to save it to or something.

It's pretty easy if you have TortoiseSVN, but I don't know about command-line.
TheQuestion = 2B || !2B
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Post by hybrid »

command line provide a 'svn diff' command which does the same, you just have to pipe it into a file.
Mirror
Posts: 218
Joined: Sat Dec 01, 2007 4:09 pm

Post by Mirror »

done :D
Post Reply