Page 1 of 1

[fixed] How to use core::vector2di::rotateBy()

Posted: Tue Nov 25, 2008 4:54 pm
by maxi0361
by reading the document. this is a void return method with the following description :
rotates the point around a center by an amount of degrees.

so, I have two vector2di instance, A is what I what to rotate, O is the point I want to rotate around.
I invoke the method like this.

A.rotateBy(degree,O)

I tried degree = 90 and degree = 1 (I don't know the degree is in 'angle degree' or radian)
both of them result in setting my A = O

What is happening?

Posted: Tue Nov 25, 2008 5:05 pm
by maxi0361
I have looked at the soucre code of rotateBy

Code: Select all

00113         void rotateBy(f64 degrees, const vector2d<T>& center)
00114         {
00115                 degrees *= DEGTORAD64;
00116                 T cs = (T)cos(degrees);
00117                 T sn = (T)sin(degrees);
00118 
00119                 X -= center.X;
00120                 Y -= center.Y;
00121 
00122                 set(X*cs - Y*sn, X*sn + Y*cs);
00123 
00124                 X += center.X;
00125                 Y += center.Y;
00126         }
It looks alright, transform the center from 0,0 to center.X,center.Y
use a linear algebra anti clockwise transform formula.
and then transform the vector back to center with &center.

then what went wrong?

Posted: Tue Nov 25, 2008 5:21 pm
by maxi0361
I put the method source code into my code instead of invoking it from the .dll
then the vector value seems to be correct.

Is there something wrong in .dll or is it because of inline?

I am using 1.4.2

Posted: Tue Nov 25, 2008 5:27 pm
by rogerborg
Oops. Thanks for the report: I'd class this as a bug.

Code: Select all

const T cs = (T)cos(degrees);
It's probably best if we don't cast a value between 0.0 and 1.0 to an int... ;)

I'll get that in to 1.4 as a bugfix and then we'll percolate it to 1.5 and the trunk. Do be aware that the final X and Y that are set in the vector will be rounded down to ints though, so you will steadily lose magnitude if you keep rotating the same vector2di. Perhaps it would be better to hold a vector2df and then extract the values and cast to int when you need them.

Fixed code (if you want to modify your local copy):

Code: Select all

	vector2d<T>& rotateBy(f64 degrees, const vector2d<T>& center)
	{
		degrees *= DEGTORAD64;
		const f64 cs = cos(degrees);
		const f64 sn = sin(degrees);

		X -= center.X;
		Y -= center.Y;

		set((T)(X*cs - Y*sn), (T)(X*sn + Y*cs));

		X += center.X;
		Y += center.Y;
		return *this;
	}

Posted: Tue Nov 25, 2008 6:30 pm
by maxi0361
Thank you for your fast reply RogerBorg.

I think using s32 will lose accuracy makes sense.
I know I should use f64 for accuracy, I am just testing my ideas.

But this fix is great. thank you

Posted: Tue Nov 25, 2008 8:27 pm
by hybrid
Wow, this poblem has be in Irrlicht since revision 1 :lol: I guess most people just skipped the integer positions right away. But this should still be fixed.

Posted: Sat Nov 29, 2008 12:06 pm
by rogerborg
Thanks for reporting this. It flushed out a whole bunch of issues in vector2d, and also that we've never had a core::equals(f64, f64, f64) function!

SVN 1871 should fix this for the 1.5 branch, including adding a regression test. I'm a bit wary about backporting it to 1.4 without porting the test suite back there as well though.

Next: look into vector3d and see if the same issues exist there.