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

fix: mathematical precision #938

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions packages/core/src/Transform.ts
Original file line number Diff line number Diff line change
Expand Up @@ -508,7 +508,7 @@ export class Transform extends Component {
const zAxis = Transform._tempVec30;
Vector3.subtract(this.worldPosition, targetPosition, zAxis);
let axisLen = zAxis.length();
if (axisLen <= MathUtil.zeroTolerance) {
if (axisLen < MathUtil.zeroTolerance) {
// The current position and the target position are almost the same.
return;
}
Expand All @@ -520,7 +520,7 @@ export class Transform extends Component {
xAxis.set(zAxis.z, 0, -zAxis.x);
}
axisLen = xAxis.length();
if (axisLen <= MathUtil.zeroTolerance) {
if (axisLen < MathUtil.zeroTolerance) {
// @todo:
// 1.worldUp is(0,0,0)
// 2.worldUp is parallel to zAxis
Expand Down
15 changes: 6 additions & 9 deletions packages/math/src/CollisionUtil.ts
Original file line number Diff line number Diff line change
Expand Up @@ -123,16 +123,13 @@ export class CollisionUtil {

const position = Vector3.dot(normal, ray.origin);
let distance = (-plane.distance - position) / dir;

if (distance < 0) {
if (distance < -zeroTolerance) {
return -1;
}

distance = 0;
if (distance >= 0) {
return distance;
} else if (distance > -zeroTolerance) {
return 0;
} else {
return -1;
}

return distance;
}

/**
Expand Down
4 changes: 2 additions & 2 deletions packages/math/src/MathUtil.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
*/
export class MathUtil {
/** The value for which all absolute numbers smaller than are considered equal to zero. */
static readonly zeroTolerance: number = 1e-6;
static readonly zeroTolerance: number = 1e-15;
/** The conversion factor that radian to degree. */
static readonly radToDegreeFactor: number = 180 / Math.PI;
/** The conversion factor that degree to radian. */
Expand All @@ -28,7 +28,7 @@ export class MathUtil {
* @returns True if a almost equal to b, false otherwise
*/
static equals(a: number, b: number): boolean {
return Math.abs(a - b) <= MathUtil.zeroTolerance;
return Math.abs(a - b) < MathUtil.zeroTolerance;
}

/**
Expand Down
2 changes: 1 addition & 1 deletion packages/math/src/Matrix.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1012,7 +1012,7 @@ export class Matrix implements IClone<Matrix>, ICopy<Matrix, Matrix> {
const e = this.elements;
let trace = e[0] + e[5] + e[10];

if (trace > MathUtil.zeroTolerance) {
if (trace >= MathUtil.zeroTolerance) {
let s = Math.sqrt(trace + 1.0) * 2;
out._w = 0.25 * s;
out._x = (e[6] - e[9]) / s;
Expand Down
16 changes: 8 additions & 8 deletions packages/math/src/Quaternion.ts
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,7 @@ export class Quaternion implements IClone<Quaternion>, ICopy<QuaternionLike, Qua
static invert(a: Quaternion, out: Quaternion): void {
const { _x: x, _y: y, _z: z, _w: w } = a;
const dot = x * x + y * y + z * z + w * w;
if (dot > MathUtil.zeroTolerance) {
if (dot >= MathUtil.zeroTolerance) {
const invDot = 1.0 / dot;
out._x = -x * invDot;
out._y = -y * invDot;
Expand Down Expand Up @@ -300,7 +300,7 @@ export class Quaternion implements IClone<Quaternion>, ICopy<QuaternionLike, Qua
static normalize(a: Quaternion, out: Quaternion): void {
const { _x, _y, _z, _w } = a;
let len = Math.sqrt(_x * _x + _y * _y + _z * _z + _w * _w);
if (len > MathUtil.zeroTolerance) {
if (len >= MathUtil.zeroTolerance) {
len = 1 / len;
out._x = _x * len;
out._y = _y * len;
Expand Down Expand Up @@ -557,14 +557,14 @@ export class Quaternion implements IClone<Quaternion>, ICopy<QuaternionLike, Qua
out._x = 1;
out._y = 0;
out._z = 0;

out._onValueChanged && out._onValueChanged();
return 0;
} else {
const inv = 1.0 / length;
out._x = this._x * inv;
out._y = this._y * inv;
out._z = this._z * inv;

out._x = _x * inv;
out._y = _y * inv;
out._z = _z * inv;
out._onValueChanged && out._onValueChanged();
return Math.acos(this._w) * 2.0;
}
}
Expand Down Expand Up @@ -789,7 +789,7 @@ export class Quaternion implements IClone<Quaternion>, ICopy<QuaternionLike, Qua
const xw = _x * _w;

out._y = Math.asin(2.0 * (xw - yz));
if (Math.cos(out.y) > MathUtil.zeroTolerance) {
if (Math.cos(out.y) >= MathUtil.zeroTolerance) {
out._z = Math.atan2(2.0 * (xy + zw), 1.0 - 2.0 * (zz + xx));
out._x = Math.atan2(2.0 * (zx + yw), 1.0 - 2.0 * (yy + xx));
} else {
Expand Down
2 changes: 1 addition & 1 deletion packages/math/src/Vector2.ts
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ export class Vector2 implements IClone<Vector2>, ICopy<Vector2Like, Vector2> {
static normalize(left: Vector2, out: Vector2): void {
const { _x, _y } = left;
let len = Math.sqrt(_x * _x + _y * _y);
if (len > MathUtil.zeroTolerance) {
if (len >= MathUtil.zeroTolerance) {
len = 1 / len;
out._x = _x * len;
out._y = _y * len;
Expand Down
7 changes: 5 additions & 2 deletions packages/math/src/Vector3.ts
Original file line number Diff line number Diff line change
Expand Up @@ -192,9 +192,12 @@ export class Vector3 implements IClone<Vector3>, ICopy<Vector3Like, Vector3> {
static normalize(a: Vector3, out: Vector3): void {
const { _x, _y, _z } = a;
let len = Math.sqrt(_x * _x + _y * _y + _z * _z);
if (len > MathUtil.zeroTolerance) {
if (len >= MathUtil.zeroTolerance) {
len = 1 / len;
out.set(_x * len, _y * len, _z * len);
out._x = _x * len;
out._y = _y * len;
out._z = _z * len;
out._onValueChanged && out._onValueChanged();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use out.set(_x * len, _y * len, _z * len); is better?

}
}

Expand Down
2 changes: 1 addition & 1 deletion packages/math/src/Vector4.ts
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ export class Vector4 implements IClone<Vector4>, ICopy<Vector4Like, Vector4> {
static normalize(a: Vector4, out: Vector4): void {
const { _x, _y, _z, _w } = a;
let len = Math.sqrt(_x * _x + _y * _y + _z * _z + _w * _w);
if (len > MathUtil.zeroTolerance) {
if (len >= MathUtil.zeroTolerance) {
len = 1 / len;
out._x = _x * len;
out._y = _y * len;
Expand Down