Skip to content

Quaternion.setFromUnitVectors precision issues #31286

@nkallen

Description

@nkallen

Related issue: #21477

Description

Quaternion.setFromUnitVectors uses the dot product and Number.EPSILON to test if two vectors are antiparallel. I think Number.EPSILON is too precise -- it basically means any floating point operations on the input vectors will fail the antiparallel test. The dot product introduces its own numerical error. Number.EPSILON is typically used to determine if two float numbers are effectively identical within floating point resolution, not that they are within a reasonable geometrical tolerance (i.e., after a small number of operations such as addition, multiplication, etc).

There are perhaps other ways of testing this (like not using dot product) and a more reasonable epsilon (2 * 10 * Number.EPSILON) or we can take other geometry libraries as a reference (1e-11 radians is angular precision in Parasolid for example; however we don't want to involve cosines here).

But just like as an example of how Number.EPSILON probably should not be used:

console.log(1-((1+1.111)-1.111) < Number.EPSILON) // false

Reproduction steps

Please see attached code

Code

const Z = new THREE.Vector3(0,0,1);
const a = new THREE.Vector3(0, 2.2204460492503128e-16, -0.9999999999999996);
const q = new THREE.Quaternion().setFromUnitVectors(Z, a);

console.log(new THREE.Vector3(0,0,1).applyQuaternion(q));
Vector3 {x: 0, y: 0.7999999999999998, z: 0.6000000000000001} // this seems implausible to me

Live example

Screenshots

No response

Version

r175

Device

No response

Browser

No response

OS

No response

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions