public final void setAngle(int i_x, int i_y, int i_z) { /* * |cos(a) -sin(a) 0| |cos(b) 0 sin(b)| |cos(a-c) sin(a-c) 0| rot = |sin(a) cos(a) 0| |0 1 0 | |-sin(a-c) cos(a-c) 0| |0 0 1| |-sin(b) 0 cos(b)| |0 0 1| */ long Sa, Sb, Ca, Cb, Sac, Cac, CaCb, SaCb; Sa = NyMath.sinFixedFloat24(i_x); Ca = NyMath.cosFixedFloat24(i_x); Sb = NyMath.sinFixedFloat24(i_y); Cb = NyMath.cosFixedFloat24(i_y); Sac = NyMath.sinFixedFloat24(i_x - i_z); Cac = NyMath.cosFixedFloat24(i_x - i_z); CaCb = (Ca * Cb) >> 24; SaCb = (Sa * Cb) >> 24; this.m00 = (CaCb * Cac + Sa * Sac) >> 24; this.m01 = (CaCb * Sac - Sa * Cac) >> 24; this.m02 = (Ca * Sb) >> 24; this.m10 = (SaCb * Cac - Ca * Sac) >> 24; this.m11 = (SaCb * Sac + Ca * Cac) >> 24; this.m12 = (Sa * Sb) >> 24; this.m20 = (-Sb * Cac) >> 24; this.m21 = (-Sb * Sac) >> 24; this.m22 = Cb; // angleを逆計算せずに直接代入 this._angle.x = i_x; this._angle.y = i_y; this._angle.z = i_z; return; }
public final void initRotBySquare( final NyARLinear[] i_linear, final NyARFixedFloat16Point2d[] i_sqvertex) throws NyARException { final NyARFixedFloatRotVector vec1 = this.__initRot_vec1; final NyARFixedFloatRotVector vec2 = this.__initRot_vec2; // 向かい合った辺から、2本のベクトルを計算 // 軸1 vec1.exteriorProductFromLinear(i_linear[0], i_linear[2]); vec1.checkVectorByVertex(i_sqvertex[0], i_sqvertex[1]); // 軸2 vec2.exteriorProductFromLinear(i_linear[1], i_linear[3]); vec2.checkVectorByVertex(i_sqvertex[3], i_sqvertex[0]); // 回転の最適化? NyARFixedFloatRotVector.checkRotation(vec1, vec2); this.m00 = vec1.v1 << 8; this.m10 = vec1.v2 << 8; this.m20 = vec1.v3 << 8; this.m01 = vec2.v1 << 8; this.m11 = vec2.v2 << 8; this.m21 = vec2.v3 << 8; // 最後の軸を計算 final long w02 = (vec1.v2 * vec2.v3 - vec1.v3 * vec2.v2) >> 16; // S16 final long w12 = (vec1.v3 * vec2.v1 - vec1.v1 * vec2.v3) >> 16; // S16 final long w22 = (vec1.v1 * vec2.v2 - vec1.v2 * vec2.v1) >> 16; // S16 final long w = NyMath.sqrtFixdFloat((w02 * w02 + w12 * w12 + w22 * w22) >> 16, 16); // S16 this.m02 = (w02 << 24) / w; this.m12 = (w12 << 24) / w; this.m22 = (w22 << 24) / w; // Matrixからangleをロード this.updateAngleFromMatrix(); return; }
/** * int arGetAngle( double rot[3][3], double *wa, double *wb, double *wc ) * Optimize:2008.04.20:STEP[481→433] 3x3変換行列から、回転角を復元して返します。 * * @param o_angle * @return */ private final void updateAngleFromMatrix() { int a, b, c; long sina, cosa, sinb, cosb, sinc, cosc; if (this.m22 > NyMath.FIXEDFLOAT24_1) { // <Optimize/>if( rot[2][2] > 1.0 ) { this.m22 = NyMath.FIXEDFLOAT24_1; // <Optimize/>rot[2][2] = 1.0; } else if (this.m22 < -NyMath.FIXEDFLOAT24_1) { // <Optimize/>}else if( rot[2][2] < -1.0 ) { this.m22 = -NyMath.FIXEDFLOAT24_1; // <Optimize/>rot[2][2] = -1.0; } cosb = this.m22; // <Optimize/>cosb = rot[2][2]; b = NyMath.acosFixedFloat16((int) cosb); sinb = (long) NyMath.sinFixedFloat24(b); final long rot02 = this.m02; final long rot12 = this.m12; if (sinb != 0) { cosa = (rot02 << 24) / sinb; // <Optimize/>cosa = rot[0][2] / sinb; sina = (rot12 << 24) / sinb; // <Optimize/>sina = rot[1][2] / sinb; if (cosa > NyMath.FIXEDFLOAT24_1) { /* printf("cos(alph) = %f\n", cosa); */ cosa = NyMath.FIXEDFLOAT24_1; sina = 0; } if (cosa < -NyMath.FIXEDFLOAT24_1) { /* printf("cos(alph) = %f\n", cosa); */ cosa = -NyMath.FIXEDFLOAT24_1; sina = 0; } if (sina > NyMath.FIXEDFLOAT24_1) { /* printf("sin(alph) = %f\n", sina); */ sina = NyMath.FIXEDFLOAT24_1; cosa = 0; } if (sina < -NyMath.FIXEDFLOAT24_1) { /* printf("sin(alph) = %f\n", sina); */ sina = -NyMath.FIXEDFLOAT24_1; cosa = 0; } a = NyMath.acosFixedFloat16((int) cosa); if (sina < 0) { a = -a; } // <Optimize> // sinc = (rot[2][1]*rot[0][2]-rot[2][0]*rot[1][2])/(rot[0][2]*rot[0][2]+rot[1][2]*rot[1][2]); // cosc = // -(rot[0][2]*rot[2][0]+rot[1][2]*rot[2][1])/(rot[0][2]*rot[0][2]+rot[1][2]*rot[1][2]); final long tmp = DIV0CANCEL + ((rot02 * rot02 + rot12 * rot12) >> 24); sinc = (this.m21 * rot02 - this.m20 * rot12) / tmp; cosc = -(rot02 * this.m20 + rot12 * this.m21) / tmp; // </Optimize> if (cosc > NyMath.FIXEDFLOAT24_1) { /* printf("cos(r) = %f\n", cosc); */ cosc = NyMath.FIXEDFLOAT24_1; sinc = 0; } if (cosc < -NyMath.FIXEDFLOAT24_1) { /* printf("cos(r) = %f\n", cosc); */ cosc = -NyMath.FIXEDFLOAT24_1; sinc = 0; } if (sinc > NyMath.FIXEDFLOAT24_1) { /* printf("sin(r) = %f\n", sinc); */ sinc = NyMath.FIXEDFLOAT24_1; cosc = 0; } if (sinc < -NyMath.FIXEDFLOAT24_1) { /* printf("sin(r) = %f\n", sinc); */ sinc = -NyMath.FIXEDFLOAT24_1; cosc = 0; } c = (int) NyMath.acosFixedFloat16((int) cosc); if (sinc < 0) { c = -c; } } else { a = b = 0; cosa = cosb = NyMath.FIXEDFLOAT24_1; sina = sinb = 0; cosc = this.m00; // cosc = rot[0];// <Optimize/>cosc = rot[0][0]; sinc = this.m01; // sinc = rot[1];// <Optimize/>sinc = rot[1][0]; if (cosc > NyMath.FIXEDFLOAT24_1) { /* printf("cos(r) = %f\n", cosc); */ cosc = NyMath.FIXEDFLOAT24_1; sinc = 0; } if (cosc < -NyMath.FIXEDFLOAT24_1) { /* printf("cos(r) = %f\n", cosc); */ cosc = -NyMath.FIXEDFLOAT24_1; sinc = 0; } if (sinc > NyMath.FIXEDFLOAT24_1) { /* printf("sin(r) = %f\n", sinc); */ sinc = NyMath.FIXEDFLOAT24_1; cosc = 0; } if (sinc < -NyMath.FIXEDFLOAT24_1) { /* printf("sin(r) = %f\n", sinc); */ sinc = -NyMath.FIXEDFLOAT24_1; cosc = 0; } c = NyMath.acosFixedFloat16((int) cosc); if (sinc < 0) { c = -c; } } this._angle.x = (long) a; // wa.value=a;//*wa = a; this._angle.y = (long) b; // wb.value=b;//*wb = b; this._angle.z = (long) c; // wc.value=c;//*wc = c; return; }