} // not public /** * @brief 独自の球面線形補間(回転角度を保つ)。y軸90度、z軸90度の回転をSLERPで計算する場合、t が変化した時、軸は最小距離を移動するが、角度は、90度ではなく小さな値となる。この計算を 90度の回転を保って、中心を通る計算についてテスト実装 * @param &q1 クォータニオン(EQuat)をセットする * @param t 補間位置を表す数値をセットする * @return 補間結果を返す */ LDQuat mySlerp(LDQuat q1, ld_float t) { LDQuat q0 = this; // 範囲外の時は端点を返す if (t <= 0.0f) { return(q0); } if (t >= 1.0f) { return(q1); } LDVector3 n0 = q0.getAxis(); LDVector3 n1 = q1.getAxis(); ld_float a0 = q0.getAngle(); ld_float a1 = q1.getAngle(); // ld_float adiff = LDMathUtil.getAngleDiff(a1, a0); ld_float at = a0 + adiff * t; LDVector3 nt = LDVector3.blend(n0, n1, 1 - t, t); nt.normalize(); LDQuat ret = new LDQuat(); ret.setToRotateAxis(nt, at); return(ret); }
public void getAxisTest() { LDQuat quat = new LDQuat(0.0f, 0.0f, 0.0f, 0.0f); LDVector3 actual = new LDVector3(); LDVector3 expected = new LDVector3(); //ld_float delta = 0.00001f; // Input : x = 0.0, y = 0.0, z = 0.0, w = 0.0 (ゼロクォータニオン) expected.zero(); actual = quat.getAxis(); TestUtil.COMPARE(expected.x, actual.x); TestUtil.COMPARE(expected.y, actual.y); TestUtil.COMPARE(expected.z, actual.z); // Input : x = 0.0, y = 0.0, z = 0.0, w = 1.0 (単位クォータニオン) quat.x = 0.0f; quat.y = 0.0f; quat.z = 0.0f; quat.w = 1.0f; expected.x = 1.0f; expected.y = 0.0f; expected.z = 0.0f; actual = quat.getAxis(); TestUtil.COMPARE(expected.x, actual.x); TestUtil.COMPARE(expected.y, actual.y); TestUtil.COMPARE(expected.z, actual.z); // Input : x = 1.0, y = 2.0, z = 3.0, w = 0.5 (任意の値) quat.x = 1.0f; quat.y = 2.0f; quat.z = 3.0f; quat.w = 0.5f; expected.x = quat.x * 1.0f / (float)Math.Sqrt(1.0f - quat.w * quat.w); expected.y = quat.y * 1.0f / (float)Math.Sqrt(1.0f - quat.w * quat.w); expected.z = quat.z * 1.0f / (float)Math.Sqrt(1.0f - quat.w * quat.w); actual = quat.getAxis(); TestUtil.COMPARE(expected.x, actual.x); TestUtil.COMPARE(expected.y, actual.y); TestUtil.COMPARE(expected.z, actual.z); }
public void mySlerpTest() { LDQuat quat1 = new LDQuat(); LDQuat quat2 = new LDQuat(); LDQuat actual = new LDQuat(); LDQuat expected = new LDQuat(); //ld_float delta = 0.00001f; ld_float t; // Input : quat1{x = 1.0, y = 2.0, z = 3.0, w = 0.1}, quat2{x = 4.0, y = 5.0, z = 6.0, w = 0.2}, t = 0.0 // 範囲外t <= 0.0fのケース quat1.x = 1.0f; quat1.y = 2.0f; quat1.z = 3.0f; quat1.w = 0.1f; quat2.x = 4.0f; quat2.y = 5.0f; quat2.z = 6.0f; quat2.w = 0.2f; t = 0.0f; expected.x = 4.0f; expected.y = 5.0f; expected.z = 6.0f; expected.w = 0.2f; actual = quat2.mySlerp(quat1, t); TestUtil.COMPARE(expected.x, actual.x); TestUtil.COMPARE(expected.y, actual.y); TestUtil.COMPARE(expected.z, actual.z); TestUtil.COMPARE(expected.w, actual.w); // Input : quat1{x = 1.0, y = 2.0, z = 3.0, w = 0.1}, quat2{x = 4.0, y = 5.0, z = 6.0, w = 0.2}, t = 1.0 // 範囲外t >= 1.0fのケース quat1.x = 1.0f; quat1.y = 2.0f; quat1.z = 3.0f; quat1.w = 0.1f; quat2.x = 4.0f; quat2.y = 5.0f; quat2.z = 6.0f; quat2.w = 0.2f; t = 1.0f; expected.x = 1.0f; expected.y = 2.0f; expected.z = 3.0f; expected.w = 0.1f; actual = quat2.mySlerp(quat1, t); TestUtil.COMPARE(expected.x, actual.x); TestUtil.COMPARE(expected.y, actual.y); TestUtil.COMPARE(expected.z, actual.z); TestUtil.COMPARE(expected.w, actual.w); // Input : quat1{x = 0.49, y = 0.5, z = 0.5, w = 0.5}, quat2{x = 0.5, y = 0.49, z = 0.5, w = 0.5}, t = 0.5 // cosOmega <= 0.9999fのケース quat1.x = 0.49f; quat1.y = 0.5f; quat1.z = 0.5f; quat1.w = 0.5f; quat2.x = 0.5f; quat2.y = 0.49f; quat2.z = 0.5f; quat2.w = 0.5f; t = 0.5f; LDVector3 n0 = quat2.getAxis(); LDVector3 n1 = quat1.getAxis(); ld_float a0 = quat2.getAngle(); ld_float a1 = quat1.getAngle(); ld_float adiff = LDMathUtil.getAngleDiff(a1, a0); ld_float at = a0 + adiff * t; LDVector3 nt = LDVector3.blend(n0, n1, 1 - t, t); nt.normalize(); expected.setToRotateAxis(nt, at); actual = quat2.mySlerp(quat1, t); TestUtil.COMPARE(expected.x, actual.x); TestUtil.COMPARE(expected.y, actual.y); TestUtil.COMPARE(expected.z, actual.z); TestUtil.COMPARE(expected.w, actual.w); }
/** * @brief 独自の球面線形補間(回転角度を保つ)。y軸90度、z軸90度の回転をSLERPで計算する場合、t が変化した時、軸は最小距離を移動するが、角度は、90度ではなく小さな値となる。この計算を 90度の回転を保って、中心を通る計算についてテスト実装 * @param &q1 クォータニオン(EQuat)をセットする * @param t 補間位置を表す数値をセットする * @return 補間結果を返す */ public LDQuat mySlerp(LDQuat q1, ld_float t) { LDQuat q0 = this; // 範囲外の時は端点を返す if (t <= 0.0f) { return q0; } if (t >= 1.0f) { return q1; } LDVector3 n0 = q0.getAxis(); LDVector3 n1 = q1.getAxis(); ld_float a0 = q0.getAngle(); ld_float a1 = q1.getAngle(); // ld_float adiff = LDMathUtil.getAngleDiff(a1, a0); ld_float at = a0 + adiff * t; LDVector3 nt = LDVector3.blend(n0, n1, 1 - t, t); nt.normalize(); LDQuat ret = new LDQuat(); ret.setToRotateAxis(nt, at); return ret; }