Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bug in Mat3f.createRotationMatrix(Vec3f referenceDirection)? #19

Open
meaten opened this issue Jun 15, 2020 · 4 comments
Open

Bug in Mat3f.createRotationMatrix(Vec3f referenceDirection)? #19

meaten opened this issue Jun 15, 2020 · 4 comments
Assignees

Comments

@meaten
Copy link

meaten commented Jun 15, 2020

This function returns the following output (not a rotation matrix) when it gets Vec3f(0.0f, -1.0f, 0.0f)

X Axis: 0.000, 0.000, 0.000
Y Axis: 0.000, 0.000, 0.000
Z Axis: 0.000, -1.000, 0.000

As far as I read this code, this function fails in coping with Y-axis singularity.

I think it should be the following

X Axis: 1.000, 0.000, 0.000
Y Axis: 0.000, 0.000, -1.000
Z Axis: 0.000, -1.000, 0.000

This is my implementation suggestion I wrote to fix this.

I replaced this section
`

	if (referenceDirection.y == 1.0f) {
		referenceDirection.y -= 0.0001f;
		referenceDirection.normalise();
	}

by

	if (Math.abs(referenceDirection.y) > 0.9999f) {
		rotMat.setZBasis(referenceDirection);
		rotMat.setXBasis( new Vec3f(1.0f, 0.0f, 0.0f));
		rotMat.setYBasis( Vec3f.crossProduct( rotMat.getXBasis(), rotMat.getZBasis()).normalised());
		return rotMat;
	}`

Thank you.

@alansley
Copy link
Collaborator

Thanks so much for getting in touch - excellent find! Also: Oops! =/

I only tweaked that method in the v1.3.5 release because this version of the createRotationMatrix method produced less roll/spin than the existing method (you can see the commented out code for the previous version still inside the method body) - unfortunately it looks like I didn't get it quite right.

I've got some tight deadlines at the moment so while it might take me a few days I'll aim to rewrite the method as per your suggestion. Will also write some unit tests to ensure rotation matrices are always orthonormal in case I try and get clever and tweak the algorithm in the future, and then push a new release.

Just did a quick spot of googling because I was going to ask you if you had any preferred method of generating orthogonal matrices and came across this:
https://graphics.pixar.com/library/OrthonormalB/paper.pdf

Perhaps a re-write to listing 2 or 3 above. If using listing 3 then this will work as a 'copysignf' function:
https://stackoverflow.com/questions/2922619/how-to-efficiently-compare-the-sign-of-two-floating-point-values-while-handling

If you get a chance to give it a crack before I do maybe let me know how you get on, otherwise I'll get to it and do some testing as soon as my current deadlines allow.

Cheers!

@meaten
Copy link
Author

meaten commented Jun 17, 2020

Thanks for your reply!

I just tried to re-write listing 3 code but It didn't work well due to the different direction problem of XBasis and ZBasis e.g.

for XBasis
Vec3f.crossProduct( referenceDirection, new Vec3f(0.0f, 1.0f, 0.0f) )
or
Vec3f.crossProduct( new Vec3f(0.0f, 1.0f, 0.0f), referenceDirection )

I think the straight java re-writing of listing 3 code uses the latter one.
It caused the opposite hinge constraints and I stopped there.

This is my re-writing code(it didn't work well).

	float sign = Math.copySign(1.0f, referenceDirection.z);             
	float a = -1.0f / (sign + referenceDirection.z);                    
	float b = referenceDirection.x * referenceDirection.y * a;          
	rotMat.setZBasis(referenceDirection);
	rotMat.setXBasis( new Vec3f(1.0f + sign * referenceDirection.x * referenceDirection.x, sign * b, -sign * referenceDirection.x));
	rotMat.setYBasis( new Vec3f(b, sign + referenceDirection.y * referenceDirection.y * a, -referenceDirection.y));

Your implementation with my modification works pretty well for my case.
I very appreciate your great repo and I wish you success on your deadline.

@meaten meaten closed this as completed Jun 17, 2020
@alansley
Copy link
Collaborator

Thanks for getting back to me - I'll re-open this and assign it to myself so it doesn't fall off my radar, because it's something I want to dig into and experiment with (and also write those unit tests!).

I'm glad you've found Caliko useful, it was written as part of my PhD (which was the deadline I mentioned) - if you don't mind me asking, would you be willing to say what you're using Caliko for? As part of my exegesis submission I have to demonstrate that the software is actually useful and being used, so any examples of real-world use help me to make that case. No worries if you don't want to or aren't at liberty to discuss what you're working on though.

Cheers!

@alansley alansley reopened this Jun 18, 2020
@alansley alansley self-assigned this Jun 18, 2020
@meaten
Copy link
Author

meaten commented Jun 18, 2020

Hi!

I'm a master's student and I'm exploring IK algorithms as part of my research work. I haven't decided on the entire image of my research. So, I cannot say what caliko exactly for.

Cheers!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants