feat: Quaternion
This commit is contained in:
51
src/quaternion.ts
Normal file
51
src/quaternion.ts
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
import { Vec3 } from "./vec";
|
||||||
|
|
||||||
|
export class Quaternion {
|
||||||
|
public constructor(
|
||||||
|
public x: number,
|
||||||
|
public y: number,
|
||||||
|
public z: number,
|
||||||
|
public w: number,
|
||||||
|
) {}
|
||||||
|
|
||||||
|
public fromXYZ({
|
||||||
|
x,
|
||||||
|
y,
|
||||||
|
z,
|
||||||
|
w,
|
||||||
|
}: {
|
||||||
|
x: number;
|
||||||
|
y: number;
|
||||||
|
z: number;
|
||||||
|
w: number;
|
||||||
|
}) {
|
||||||
|
return new Quaternion(x, y, z, w);
|
||||||
|
}
|
||||||
|
|
||||||
|
public toEuler(): Vec3 {
|
||||||
|
const { x, y, z, w } = this;
|
||||||
|
|
||||||
|
const sinr_cosp = 2 * (w * x + y * z);
|
||||||
|
const cosr_cosp = 1 - 2 * (x * x + y * y);
|
||||||
|
const roll = math.atan2(sinr_cosp, cosr_cosp);
|
||||||
|
|
||||||
|
const sinp = 2 * (w * y - z * x);
|
||||||
|
let pitch: number;
|
||||||
|
if (math.abs(sinp) >= 1) {
|
||||||
|
pitch = (sign(sinp) * Math.PI) / 2;
|
||||||
|
} else {
|
||||||
|
pitch = math.asin(sinp);
|
||||||
|
}
|
||||||
|
|
||||||
|
const siny_cosp = 2 * (w * z + x * y);
|
||||||
|
const cosy_cosp = 1 - 2 * (y * y + z * z);
|
||||||
|
const yaw = math.atan2(siny_cosp, cosy_cosp);
|
||||||
|
|
||||||
|
return new Vec3(roll, pitch, yaw);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// fast sign without zero
|
||||||
|
function sign(v: number) {
|
||||||
|
return v > 0 ? 1 : -1;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user