package jp.nyatla.nyartoolkit.core;
import jp.nyatla.nyartoolkit.NyARException;
interface NyARTransRot
{
public double[] getArray
();
/**
*
* @param trans
* @param vertex
* @param pos2d
* [n*2]配列
* @return
* @throws NyARException
*/
public double modifyMatrix
(double trans
[],
double vertex
[][],
double pos2d
[][]) throws NyARException
;
public void initRot
(NyARSquare marker_info,
int i_direction
) throws NyARException
;
public void initRotByPrevResult
(NyARTransMatResult i_prev_result
);
}
/**
* NyARTransRot派生クラスで共通に使いそうな関数類をまとめたもの。
*
*/
abstract class NyARTransRot_OptimizeCommon
implements NyARTransRot
{
protected final int number_of_vertex
;
protected final double[] array=
new double[9];
protected final NyARParam cparam
;
public final void initRotByPrevResult
(NyARTransMatResult i_prev_result
)
{
double[][] prev_array=i_prev_result.
getArray();
double[] pt
;
final double[] L_rot=
this.
array;
pt=prev_array
[0];
L_rot
[0*3+
0]=pt
[0];
L_rot
[0*3+
1]=pt
[1];
L_rot
[0*3+
2]=pt
[2];
pt=prev_array
[1];
L_rot
[1*3+
0]=pt
[0];
L_rot
[1*3+
1]=pt
[1];
L_rot
[1*3+
2]=pt
[2];
pt=prev_array
[2];
L_rot
[2*3+
0]=pt
[0];
L_rot
[2*3+
1]=pt
[1];
L_rot
[2*3+
2]=pt
[2];
}
public final double[] getArray
()
{
return this.
array;
}
/**
* インスタンスを準備します。
* @param i_param
* nullを指定した場合、一部の関数が使用不能になります。
*/
public NyARTransRot_OptimizeCommon
(NyARParam i_param,
int i_number_of_vertex
) throws NyARException
{
number_of_vertex=i_number_of_vertex
;
cparam=i_param
;
}
private final double[] wk_check_dir_world=
new double[6];
private final double[] wk_check_dir_camera=
new double[4];
private final NyARMat wk_check_dir_NyARMat=
new NyARMat
( 3,
3 );
/**
* static int check_dir( double dir[3], double st[2], double ed[2],double cpara[3][4] )
* Optimize:STEP[526->468]
* @param dir
* @param st
* @param ed
* @param cpara
*
* @throws NyARException
*/
protected final void check_dir
( double dir
[],
double st
[],
double ed
[],
double cpara
[]) throws NyARException
{
double h
;
int i, j
;
NyARMat mat_a =
this.
wk_check_dir_NyARMat;//ここ、事前に初期化できそう
double[][] a_array=mat_a.
getArray();
for(j=
0;j
<3;j++
){
for(i=
0;i
<3;i++
){
a_array
[j
][i
]=cpara
[j
*4+i
];//m[j*3+i] = cpara[j][i];
}
}
// JartkException.trap("未チェックのパス");
mat_a.
matrixSelfInv();
double[] world=wk_check_dir_world
;//[2][3];
//<Optimize>
//world[0][0] = a_array[0][0]*st[0]*10.0+ a_array[0][1]*st[1]*10.0+ a_array[0][2]*10.0;//mat_a->m[0]*st[0]*10.0+ mat_a->m[1]*st[1]*10.0+ mat_a->m[2]*10.0;
//world[0][1] = a_array[1][0]*st[0]*10.0+ a_array[1][1]*st[1]*10.0+ a_array[1][2]*10.0;//mat_a->m[3]*st[0]*10.0+ mat_a->m[4]*st[1]*10.0+ mat_a->m[5]*10.0;
//world[0][2] = a_array[2][0]*st[0]*10.0+ a_array[2][1]*st[1]*10.0+ a_array[2][2]*10.0;//mat_a->m[6]*st[0]*10.0+ mat_a->m[7]*st[1]*10.0+ mat_a->m[8]*10.0;
//world[1][0] = world[0][0] + dir[0];
//world[1][1] = world[0][1] + dir[1];
//world[1][2] = world[0][2] + dir[2];
world
[0] = a_array
[0][0]*st
[0]*10.0+ a_array
[0][1]*st
[1]*10.0+ a_array
[0][2]*10.0;//mat_a->m[0]*st[0]*10.0+ mat_a->m[1]*st[1]*10.0+ mat_a->m[2]*10.0;
world
[1] = a_array
[1][0]*st
[0]*10.0+ a_array
[1][1]*st
[1]*10.0+ a_array
[1][2]*10.0;//mat_a->m[3]*st[0]*10.0+ mat_a->m[4]*st[1]*10.0+ mat_a->m[5]*10.0;
world
[2] = a_array
[2][0]*st
[0]*10.0+ a_array
[2][1]*st
[1]*10.0+ a_array
[2][2]*10.0;//mat_a->m[6]*st[0]*10.0+ mat_a->m[7]*st[1]*10.0+ mat_a->m[8]*10.0;
world
[3] = world
[0] + dir
[0];
world
[4] = world
[1] + dir
[1];
world
[5] = world
[2] + dir
[2];
//</Optimize>
double[] camera=wk_check_dir_camera
;//[2][2];
for( i =
0; i
< 2; i++
) {
h = cpara
[2*4+
0] * world
[i
*3+
0]+ cpara
[2*4+
1] * world
[i
*3+
1]+ cpara
[2*4+
2] * world
[i
*3+
2];
if( h ==
0.0 ){
throw new NyARException
();
}
camera
[i
*2+
0] =
(cpara
[0*4+
0] * world
[i
*3+
0]+ cpara
[0*4+
1] * world
[i
*3+
1]+ cpara
[0*4+
2] * world
[i
*3+
2]) / h
;
camera
[i
*2+
1] =
(cpara
[1*4+
0] * world
[i
*3+
0]+ cpara
[1*4+
1] * world
[i
*3+
1]+ cpara
[1*4+
2] * world
[i
*3+
2]) / h
;
}
//<Optimize>
//v[0][0] = ed[0] - st[0];
//v[0][1] = ed[1] - st[1];
//v[1][0] = camera[1][0] - camera[0][0];
//v[1][1] = camera[1][1] - camera[0][1];
double v=
(ed
[0]-st
[0])*(camera
[2]-camera
[0])+
(ed
[1]-st
[1])*(camera
[3]-camera
[1]);
//</Optimize>
if(v
<0) {//if( v[0][0]*v[1][0] + v[0][1]*v[1][1] < 0 ) {
dir
[0] = -dir
[0];
dir
[1] = -dir
[1];
dir
[2] = -dir
[2];
}
}
/*int check_rotation( double rot[2][3] )*/
protected final static void check_rotation
( double rot
[][] ) throws NyARException
{
double[] v1=
new double[3], v2=
new double[3], v3=
new double[3];
double ca, cb, k1, k2, k3, k4
;
double a, b, c, d
;
double p1, q1, r1
;
double p2, q2, r2
;
double p3, q3, r3
;
double p4, q4, r4
;
double w
;
double e1, e2, e3, e4
;
int f
;
v1
[0] = rot
[0][0];
v1
[1] = rot
[0][1];
v1
[2] = rot
[0][2];
v2
[0] = rot
[1][0];
v2
[1] = rot
[1][1];
v2
[2] = rot
[1][2];
v3
[0] = v1
[1]*v2
[2] - v1
[2]*v2
[1];
v3
[1] = v1
[2]*v2
[0] - v1
[0]*v2
[2];
v3
[2] = v1
[0]*v2
[1] - v1
[1]*v2
[0];
w =
Math.
sqrt( v3
[0]*v3
[0]+v3
[1]*v3
[1]+v3
[2]*v3
[2] );
if( w ==
0.0 ){
throw new NyARException
();
}
v3
[0] /= w
;
v3
[1] /= w
;
v3
[2] /= w
;
cb = v1
[0]*v2
[0] + v1
[1]*v2
[1] + v1
[2]*v2
[2];
if( cb
< 0 ) cb
*= -
1.0;
ca =
(Math.
sqrt(cb+
1.0) +
Math.
sqrt(1.0-cb
)) * 0.5;
if( v3
[1]*v1
[0] - v1
[1]*v3
[0] !=
0.0 ) {
f =
0;
}
else {
if( v3
[2]*v1
[0] - v1
[2]*v3
[0] !=
0.0 ) {
w = v1
[1]; v1
[1] = v1
[2]; v1
[2] = w
;
w = v3
[1]; v3
[1] = v3
[2]; v3
[2] = w
;
f =
1;
}
else {
w = v1
[0]; v1
[0] = v1
[2]; v1
[2] = w
;
w = v3
[0]; v3
[0] = v3
[2]; v3
[2] = w
;
f =
2;
}
}
if( v3
[1]*v1
[0] - v1
[1]*v3
[0] ==
0.0 ){
throw new NyARException
();
}
k1 =
(v1
[1]*v3
[2] - v3
[1]*v1
[2]) /
(v3
[1]*v1
[0] - v1
[1]*v3
[0]);
k2 =
(v3
[1] * ca
) /
(v3
[1]*v1
[0] - v1
[1]*v3
[0]);
k3 =
(v1
[0]*v3
[2] - v3
[0]*v1
[2]) /
(v3
[0]*v1
[1] - v1
[0]*v3
[1]);
k4 =
(v3
[0] * ca
) /
(v3
[0]*v1
[1] - v1
[0]*v3
[1]);
a = k1
*k1 + k3
*k3 +
1;
b = k1
*k2 + k3
*k4
;
c = k2
*k2 + k4
*k4 -
1;
d = b
*b - a
*c
;
if( d
< 0 ){
throw new NyARException
();
}
r1 =
(-b +
Math.
sqrt(d
))/a
;
p1 = k1
*r1 + k2
;
q1 = k3
*r1 + k4
;
r2 =
(-b -
Math.
sqrt(d
))/a
;
p2 = k1
*r2 + k2
;
q2 = k3
*r2 + k4
;
if( f ==
1 ) {
w = q1
; q1 = r1
; r1 = w
;
w = q2
; q2 = r2
; r2 = w
;
w = v1
[1]; v1
[1] = v1
[2]; v1
[2] = w
;
w = v3
[1]; v3
[1] = v3
[2]; v3
[2] = w
;
f =
0;
}
if( f ==
2 ) {
w = p1
; p1 = r1
; r1 = w
;
w = p2
; p2 = r2
; r2 = w
;
w = v1
[0]; v1
[0] = v1
[2]; v1
[2] = w
;
w = v3
[0]; v3
[0] = v3
[2]; v3
[2] = w
;
f =
0;
}
if( v3
[1]*v2
[0] - v2
[1]*v3
[0] !=
0.0 ) {
f =
0;
}else {
if( v3
[2]*v2
[0] - v2
[2]*v3
[0] !=
0.0 ) {
w = v2
[1]; v2
[1] = v2
[2]; v2
[2] = w
;
w = v3
[1]; v3
[1] = v3
[2]; v3
[2] = w
;
f =
1;
}
else {
w = v2
[0]; v2
[0] = v2
[2]; v2
[2] = w
;
w = v3
[0]; v3
[0] = v3
[2]; v3
[2] = w
;
f =
2;
}
}
if( v3
[1]*v2
[0] - v2
[1]*v3
[0] ==
0.0 ){
throw new NyARException
();
}
k1 =
(v2
[1]*v3
[2] - v3
[1]*v2
[2]) /
(v3
[1]*v2
[0] - v2
[1]*v3
[0]);
k2 =
(v3
[1] * ca
) /
(v3
[1]*v2
[0] - v2
[1]*v3
[0]);
k3 =
(v2
[0]*v3
[2] - v3
[0]*v2
[2]) /
(v3
[0]*v2
[1] - v2
[0]*v3
[1]);
k4 =
(v3
[0] * ca
) /
(v3
[0]*v2
[1] - v2
[0]*v3
[1]);
a = k1
*k1 + k3
*k3 +
1;
b = k1
*k2 + k3
*k4
;
c = k2
*k2 + k4
*k4 -
1;
d = b
*b - a
*c
;
if( d
< 0 ){
throw new NyARException
();
}
r3 =
(-b +
Math.
sqrt(d
))/a
;
p3 = k1
*r3 + k2
;
q3 = k3
*r3 + k4
;
r4 =
(-b -
Math.
sqrt(d
))/a
;
p4 = k1
*r4 + k2
;
q4 = k3
*r4 + k4
;
if( f ==
1 ) {
w = q3
; q3 = r3
; r3 = w
;
w = q4
; q4 = r4
; r4 = w
;
w = v2
[1]; v2
[1] = v2
[2]; v2
[2] = w
;
w = v3
[1]; v3
[1] = v3
[2]; v3
[2] = w
;
f =
0;
}
if( f ==
2 ) {
w = p3
; p3 = r3
; r3 = w
;
w = p4
; p4 = r4
; r4 = w
;
w = v2
[0]; v2
[0] = v2
[2]; v2
[2] = w
;
w = v3
[0]; v3
[0] = v3
[2]; v3
[2] = w
;
f =
0;
}
e1 = p1
*p3+q1
*q3+r1
*r3
;
if( e1
< 0 ){
e1 = -e1
;
}
e2 = p1
*p4+q1
*q4+r1
*r4
;
if( e2
< 0 ){
e2 = -e2
;
}
e3 = p2
*p3+q2
*q3+r2
*r3
;
if( e3
< 0 ){
e3 = -e3
;
}
e4 = p2
*p4+q2
*q4+r2
*r4
;
if( e4
< 0 ){
e4 = -e4
;
}
if( e1
< e2
) {
if( e1
< e3
) {
if( e1
< e4
) {
rot
[0][0] = p1
;
rot
[0][1] = q1
;
rot
[0][2] = r1
;
rot
[1][0] = p3
;
rot
[1][1] = q3
;
rot
[1][2] = r3
;
}
else {
rot
[0][0] = p2
;
rot
[0][1] = q2
;
rot
[0][2] = r2
;
rot
[1][0] = p4
;
rot
[1][1] = q4
;
rot
[1][2] = r4
;
}
}
else {
if( e3
< e4
) {
rot
[0][0] = p2
;
rot
[0][1] = q2
;
rot
[0][2] = r2
;
rot
[1][0] = p3
;
rot
[1][1] = q3
;
rot
[1][2] = r3
;
}
else {
rot
[0][0] = p2
;
rot
[0][1] = q2
;
rot
[0][2] = r2
;
rot
[1][0] = p4
;
rot
[1][1] = q4
;
rot
[1][2] = r4
;
}
}
}
else {
if( e2
< e3
) {
if( e2
< e4
) {
rot
[0][0] = p1
;
rot
[0][1] = q1
;
rot
[0][2] = r1
;
rot
[1][0] = p4
;
rot
[1][1] = q4
;
rot
[1][2] = r4
;
}
else {
rot
[0][0] = p2
;
rot
[0][1] = q2
;
rot
[0][2] = r2
;
rot
[1][0] = p4
;
rot
[1][1] = q4
;
rot
[1][2] = r4
;
}
}
else {
if( e3
< e4
) {
rot
[0][0] = p2
;
rot
[0][1] = q2
;
rot
[0][2] = r2
;
rot
[1][0] = p3
;
rot
[1][1] = q3
;
rot
[1][2] = r3
;
}
else {
rot
[0][0] = p2
;
rot
[0][1] = q2
;
rot
[0][2] = r2
;
rot
[1][0] = p4
;
rot
[1][1] = q4
;
rot
[1][2] = r4
;
}
}
}
}
/**
* パラメタa,b,cからrotを計算してインスタンスに保存する。
* rotを1次元配列に変更
* Optimize:2008.04.20:STEP[253→186]
* @param a
* @param b
* @param c
* @param o_rot
*/
protected final static void arGetRot
( double a,
double b,
double c,
double[] o_rot
)
{
double sina, sinb, sinc
;
double cosa, cosb, cosc
;
sina =
Math.
sin(a
);
cosa =
Math.
cos(a
);
sinb =
Math.
sin(b
);
cosb =
Math.
cos(b
);
sinc =
Math.
sin(c
);
cosc =
Math.
cos(c
);
//Optimize
double CACA,SASA,SACA,SASB,CASB,SACACB
;
CACA =cosa
*cosa
;
SASA =sina
*sina
;
SACA =sina
*cosa
;
SASB =sina
*sinb
;
CASB =cosa
*sinb
;
SACACB=SACA
*cosb
;
o_rot
[0] = CACA
*cosb
*cosc+SASA
*cosc+SACACB
*sinc-SACA
*sinc
;
o_rot
[1] = -CACA
*cosb
*sinc-SASA
*sinc+SACACB
*cosc-SACA
*cosc
;
o_rot
[2] = CASB
;
o_rot
[3] = SACACB
*cosc-SACA
*cosc+SASA
*cosb
*sinc+CACA
*sinc
;
o_rot
[4] = -SACACB
*sinc+SACA
*sinc+SASA
*cosb
*cosc+CACA
*cosc
;
o_rot
[5] = SASB
;
o_rot
[6] = -CASB
*cosc-SASB
*sinc
;
o_rot
[7] = CASB
*sinc-SASB
*cosc
;
o_rot
[8] = cosb
;
}
/**
* int arGetAngle( double rot[3][3], double *wa, double *wb, double *wc )
* Optimize:2008.04.20:STEP[481→433]
* @param rot
* 2次元配列を1次元化してあります。
* @param o_abc
* @return
*/
protected final int arGetAngle
(double[] o_abc
)
{
double a, b, c,tmp
;
double sina, cosa, sinb, cosb, sinc, cosc
;
double[] rot=array
;
if( rot
[8] > 1.0 ) {//<Optimize/>if( rot[2][2] > 1.0 ) {
rot
[8] =
1.0;//<Optimize/>rot[2][2] = 1.0;
}else if( rot
[8] < -
1.0 ) {//<Optimize/>}else if( rot[2][2] < -1.0 ) {
rot
[8] = -
1.0;//<Optimize/>rot[2][2] = -1.0;
}
cosb = rot
[8];//<Optimize/>cosb = rot[2][2];
b =
Math.
acos( cosb
);
sinb =
Math.
sin( b
);
if( b
>=
0.000001 || b
<= -
0.000001) {
cosa = rot
[2] / sinb
;//<Optimize/>cosa = rot[0][2] / sinb;
sina = rot
[5] / sinb
;//<Optimize/>sina = rot[1][2] / sinb;
if( cosa
> 1.0 ) {
/* printf("cos(alph) = %f\n", cosa); */
cosa =
1.0;
sina =
0.0;
}
if( cosa
< -
1.0 ) {
/* printf("cos(alph) = %f\n", cosa); */
cosa = -
1.0;
sina =
0.0;
}
if( sina
> 1.0 ) {
/* printf("sin(alph) = %f\n", sina); */
sina =
1.0;
cosa =
0.0;
}
if( sina
< -
1.0 ) {
/* printf("sin(alph) = %f\n", sina); */
sina = -
1.0;
cosa =
0.0;
}
a =
Math.
acos( 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]);
tmp =
(rot
[2]*rot
[2]+rot
[5]*rot
[5]);
sinc =
(rot
[7]*rot
[2]-rot
[6]*rot
[5])/ tmp
;
cosc = -
(rot
[2]*rot
[6]+rot
[5]*rot
[7])/ tmp
;
//</Optimize>
if( cosc
> 1.0 ) {
/* printf("cos(r) = %f\n", cosc); */
cosc =
1.0;
sinc =
0.0;
}
if( cosc
< -
1.0 ) {
/* printf("cos(r) = %f\n", cosc); */
cosc = -
1.0;
sinc =
0.0;
}
if( sinc
> 1.0 ) {
/* printf("sin(r) = %f\n", sinc); */
sinc =
1.0;
cosc =
0.0;
}
if( sinc
< -
1.0 ) {
/* printf("sin(r) = %f\n", sinc); */
sinc = -
1.0;
cosc =
0.0;
}
c =
Math.
acos( cosc
);
if( sinc
< 0 ){
c = -c
;
}
}else {
a = b =
0.0;
cosa = cosb =
1.0;
sina = sinb =
0.0;
cosc = rot
[0];//<Optimize/>cosc = rot[0][0];
sinc = rot
[1];//<Optimize/>sinc = rot[1][0];
if( cosc
> 1.0 ) {
/* printf("cos(r) = %f\n", cosc); */
cosc =
1.0;
sinc =
0.0;
}
if( cosc
< -
1.0 ) {
/* printf("cos(r) = %f\n", cosc); */
cosc = -
1.0;
sinc =
0.0;
}
if( sinc
> 1.0 ) {
/* printf("sin(r) = %f\n", sinc); */
sinc =
1.0;
cosc =
0.0;
}
if( sinc
< -
1.0 ) {
/* printf("sin(r) = %f\n", sinc); */
sinc = -
1.0;
cosc =
0.0;
}
c =
Math.
acos( cosc
);
if( sinc
< 0 ){
c = -c
;
}
}
o_abc
[0]=a
;//wa.value=a;//*wa = a;
o_abc
[1]=b
;//wb.value=b;//*wb = b;
o_abc
[2]=c
;//wc.value=c;//*wc = c;
return 0;
}
}
/**
* NyARModifyMatrixの最適化バージョン1
* 配列の1次元化、計算ステップの圧縮等の最適化をしてみた。
*
*/
class NyARTransRot_O1
extends NyARTransRot_OptimizeCommon
{
public NyARTransRot_O1
(NyARParam i_param,
int i_number_of_vertex
) throws NyARException
{
super(i_param,i_number_of_vertex
);
}
/**
* int arGetInitRot( ARMarkerInfo *marker_info, double cpara[3][4], double rot[3][3] )
* Optimize:2008.04.20:STEP[716→698]
* @param marker_info
* @param i_direction
* @param i_param
* @throws NyARException
*/
public final void initRot
(NyARSquare marker_info,
int i_direction
) throws NyARException
{
double cpara
[]= cparam.
get34Array();
double[][] wdir=
new double[3][3];
double w, w1, w2, w3
;
int dir
;
int j
;
dir = i_direction
;
for( j =
0; j
< 2; j++
) {
w1 = marker_info.
line[(4-dir+j
)%4
][0] * marker_info.
line[(6-dir+j
)%4
][1]- marker_info.
line[(6-dir+j
)%4
][0] * marker_info.
line[(4-dir+j
)%4
][1];
w2 = marker_info.
line[(4-dir+j
)%4
][1] * marker_info.
line[(6-dir+j
)%4
][2]- marker_info.
line[(6-dir+j
)%4
][1] * marker_info.
line[(4-dir+j
)%4
][2];
w3 = marker_info.
line[(4-dir+j
)%4
][2] * marker_info.
line[(6-dir+j
)%4
][0]- marker_info.
line[(6-dir+j
)%4
][2] * marker_info.
line[(4-dir+j
)%4
][0];
wdir
[j
][0] = w1
*(cpara
[0*4+
1]*cpara
[1*4+
2]-cpara
[0*4+
2]*cpara
[1*4+
1])+ w2
*cpara
[1*4+
1]- w3
*cpara
[0*4+
1];
wdir
[j
][1] = -w1
*cpara
[0*4+
0]*cpara
[1*4+
2]+ w3
*cpara
[0*4+
0];
wdir
[j
][2] = w1
*cpara
[0*4+
0]*cpara
[1*4+
1];
w =
Math.
sqrt( wdir
[j
][0]*wdir
[j
][0]+ wdir
[j
][1]*wdir
[j
][1]+ wdir
[j
][2]*wdir
[j
][2] );
wdir
[j
][0] /= w
;
wdir
[j
][1] /= w
;
wdir
[j
][2] /= w
;
}
//以下3ケースは、計算エラーのときは例外が発生する。
check_dir
(wdir
[0], marker_info.
sqvertex[(4-dir
)%4
],marker_info.
sqvertex[(5-dir
)%4
], cpara
);
check_dir
(wdir
[1], marker_info.
sqvertex[(7-dir
)%4
],marker_info.
sqvertex[(4-dir
)%4
], cpara
);
check_rotation
(wdir
);
wdir
[2][0] = wdir
[0][1]*wdir
[1][2] - wdir
[0][2]*wdir
[1][1];
wdir
[2][1] = wdir
[0][2]*wdir
[1][0] - wdir
[0][0]*wdir
[1][2];
wdir
[2][2] = wdir
[0][0]*wdir
[1][1] - wdir
[0][1]*wdir
[1][0];
w =
Math.
sqrt( wdir
[2][0]*wdir
[2][0]+ wdir
[2][1]*wdir
[2][1]+ wdir
[2][2]*wdir
[2][2] );
wdir
[2][0] /= w
;
wdir
[2][1] /= w
;
wdir
[2][2] /= w
;
/*
if( wdir[2][2] < 0 ) {
wdir[2][0] /= -w;
wdir[2][1] /= -w;
wdir[2][2] /= -w;
}
else {
wdir[2][0] /= w;
wdir[2][1] /= w;
wdir[2][2] /= w;
}
*/
//<Optimize>
//rot[0][0] = wdir[0][0];
//rot[1][0] = wdir[0][1];
//rot[2][0] = wdir[0][2];
//rot[0][1] = wdir[1][0];
//rot[1][1] = wdir[1][1];
//rot[2][1] = wdir[1][2];
//rot[0][2] = wdir[2][0];
//rot[1][2] = wdir[2][1];
//rot[2][2] = wdir[2][2];
double[] rot=
this.
array;
rot
[0] = wdir
[0][0];
rot
[3] = wdir
[0][1];
rot
[6] = wdir
[0][2];
rot
[1] = wdir
[1][0];
rot
[4] = wdir
[1][1];
rot
[7] = wdir
[1][2];
rot
[2] = wdir
[2][0];
rot
[5] = wdir
[2][1];
rot
[8] = wdir
[2][2];
//</Optimize>
}
private final double[] wk_arModifyMatrix_combo=
new double[12];//[3][4];
private final double[] wk_arModifyMatrix_abc=
new double[3];
private final double[] wk_arModifyMatrix_rot=
new double[9];
/**
* Optimize:2008.04.20:STEP[456→-]
* @param rot
* [3x3]配列
* @param trans
* @param vertex
* @param pos2d
* @param num
* @return
*/
public final double modifyMatrix
(double trans
[],
double vertex
[][],
double pos2d
[][]) throws NyARException
{
int num=
this.
number_of_vertex;
double factor
;
double a1, b1, c1
;
double a2, b2, c2
;
double ma =
0.0, mb =
0.0, mc =
0.0;
double hx, hy, h, x, y
;
double err, minerr=
0;
int t1, t2, t3
;
int s1 =
0, s2 =
0, s3 =
0;
int i, j
;
double[] combo=
this.
wk_arModifyMatrix_combo;//arGetNewMatrixで初期化されるので初期化不要//new double[3][4];
double[] abc=wk_arModifyMatrix_abc
;
double[] rot=wk_arModifyMatrix_rot
;
arGetAngle
(abc
);//arGetAngle( rot, &a, &b, &c );
a2 = abc
[0];
b2 = abc
[1];
c2 = abc
[2];
factor =
10.0*Math.
PI/
180.0;
for( j =
0; j
< 10; j++
) {
minerr =
1000000000.0;
for(t1=-
1;t1
<=
1;t1++
) {
for(t2=-
1;t2
<=
1;t2++
) {
for(t3=-
1;t3
<=
1;t3++
) {
a1 = a2 + factor
*t1
;
b1 = b2 + factor
*t2
;
c1 = c2 + factor
*t3
;
arGetRot
( a1, b1, c1,rot
);
arGetNewMatrix
(rot,trans,
null, combo
);
err =
0.0;
for( i =
0; i
< num
; i++
) {
hx = combo
[0] * vertex
[i
][0]+ combo
[1] * vertex
[i
][1]+ combo
[2] * vertex
[i
][2]+ combo
[3];
hy = combo
[4] * vertex
[i
][0]+ combo
[5] * vertex
[i
][1]+ combo
[6] * vertex
[i
][2]+ combo
[7];
h = combo
[8] * vertex
[i
][0]+ combo
[9] * vertex
[i
][1]+ combo
[10] * vertex
[i
][2]+ combo
[11];
x = hx / h
;
y = hy / h
;
err +=
(pos2d
[i
][0] - x
) * (pos2d
[i
][0] - x
)+
(pos2d
[i
][1] - y
) * (pos2d
[i
][1] - y
);
}
if( err
< minerr
) {
minerr = err
;
ma = a1
;
mb = b1
;
mc = c1
;
s1 = t1
;
s2 = t2
;
s3 = t3
;
}
}
}
}
if( s1 ==
0 && s2 ==
0 && s3 ==
0 ){
factor
*=
0.5;
}
a2 = ma
;
b2 = mb
;
c2 = mc
;
}
arGetRot
(ma, mb, mc,
this.
array);
/* printf("factor = %10.5f\n", factor*180.0/MD_PI); */
return minerr/num
;
}
private final double[] wk_cpara2_arGetNewMatrix=
new double[12];//[3][4];
/**
* Optimize:2008.04.20:STEP[569->432]
* @param i_rot
* [9]
* @param trans
* @param trans2
* @param ret
* double[3x4]配列
* @return
*/
private final int arGetNewMatrix
(double[] i_rot,
double trans
[],
double trans2
[][],
double ret
[]) throws NyARException
{
final double cpara
[]=cparam.
get34Array();
final double[] cpara2
; //この関数で初期化される。
int j,j_idx
;
// double[] cpara_pt;
//cparaの2次元配列→1次元に変換して計算
if( trans2
!=
null ) {
cpara2=wk_cpara2_arGetNewMatrix
; //この関数で初期化される。
for( j =
0; j
< 3; j++
) {
// Optimize(使わないから最適化してない)
NyARException.
trap("未チェックのパス");
cpara2
[j
*4+
0] = cpara
[j
*4+
0] * trans2
[0][0]+ cpara
[j
*4+
1] * trans2
[1][0]+ cpara
[j
*4+
2] * trans2
[2][0];
cpara2
[j
*4+
1] = cpara
[j
*4+
0] * trans2
[0][1]+ cpara
[j
*4+
1] * trans2
[1][1]+ cpara
[j
*4+
2] * trans2
[2][1];
cpara2
[j
*4+
2] = cpara
[j
*4+
0] * trans2
[0][2]+ cpara
[j
*4+
1] * trans2
[1][2]+ cpara
[j
*4+
2] * trans2
[2][2];
cpara2
[j
*4+
3] = cpara
[j
*4+
0] * trans2
[0][3]+ cpara
[j
*4+
1] * trans2
[1][3]+ cpara
[j
*4+
2] * trans2
[2][3];
}
}else{
cpara2=cpara
;//cparaの値をそのまま使う
}
for( j =
0; j
< 3; j++
) {
//cpara2_pt=cpara2[j];
j_idx=j
*4;
//<Optimize>
//ret[j][0] = cpara2_pt[0] * rot[0][0]+ cpara2_pt[1] * rot[1][0]+ cpara2_pt[2] * rot[2][0];
//ret[j][1] = cpara2_pt[0] * rot[0][1]+ cpara2_pt[1] * rot[1][1]+ cpara2_pt[2] * rot[2][1];
//ret[j][2] = cpara2_pt[0] * rot[0][2]+ cpara2_pt[1] * rot[1][2]+ cpara2_pt[2] * rot[2][2];
//ret[j][3] = cpara2_pt[0] * trans[0]+ cpara2_pt[1] * trans[1]+ cpara2_pt[2] * trans[2]+ cpara2_pt[3];
ret
[j_idx+
0] = cpara2
[j_idx+
0] * i_rot
[0]+ cpara2
[j_idx+
1] * i_rot
[3]+ cpara2
[j_idx+
2] * i_rot
[6];
ret
[j_idx+
1] = cpara2
[j_idx+
0] * i_rot
[1]+ cpara2
[j_idx+
1] * i_rot
[4]+ cpara2
[j_idx+
2] * i_rot
[7];
ret
[j_idx+
2] = cpara2
[j_idx+
0] * i_rot
[2]+ cpara2
[j_idx+
1] * i_rot
[5]+ cpara2
[j_idx+
2] * i_rot
[8];
ret
[j_idx+
3] = cpara2
[j_idx+
0] * trans
[0]+ cpara2
[j_idx+
1] * trans
[1]+ cpara2
[j_idx+
2] * trans
[2]+ cpara2
[j_idx+
3];
//</Optimize>
}
return(0);
}
}
/**
* NyARModifyMatrixの最適化バージョン2
* 計算手順の変更、構造変更など含む最適化をしたもの
*
*/
class NyARTransRot_O2
extends NyARTransRot_OptimizeCommon
{
public NyARTransRot_O2
(NyARParam i_param,
int i_number_of_vertex
) throws NyARException
{
super(i_param,i_number_of_vertex
);
}
//private double CACA,SASA,SACA,CA,SA;
private double CACA,SASA,SACA,CA,SA
;
final public void arGetRotA
( double a
)
{
double sina,cosa
;
sina =
Math.
sin(a
);
cosa =
Math.
cos(a
);
//Optimize
CACA=cosa
*cosa
;
SASA=sina
*sina
;
SACA=sina
*cosa
;
CA=cosa
;
SA=sina
;
}
private double CACACB,SACACB,SASACB,CASB,SASB
;
final public void arGetRotB
(double b,
double[] o_rot
)
{
double sinb,cosb
;
sinb =
Math.
sin(b
);
cosb =
Math.
cos(b
);
CACACB=CACA
*cosb
;
SACACB=SACA
*cosb
;
SASACB=SASA
*cosb
;
CASB=CA
*sinb
;
SASB=SA
*sinb
;
o_rot
[2] = CASB
;
o_rot
[5] = SASB
;
o_rot
[8] = cosb
;
}
/**
* 分割arGetRot
* @param c
*/
public final void arGetRotC
(double c,
double[] o_rot
)
{
double sinc,cosc
;
sinc =
Math.
sin(c
);
cosc =
Math.
cos(c
);
double SACASC,SACACBSC,SACACBCC,SACACC
;
SACASC=SACA
*sinc
;
SACACC=SACA
*cosc
;
SACACBSC=SACACB
*sinc
;
SACACBCC=SACACB
*cosc
;
o_rot
[0] = CACACB
*cosc+SASA
*cosc+SACACBSC-SACASC
;
o_rot
[1] = -CACACB
*sinc-SASA
*sinc+SACACBCC-SACACC
;
o_rot
[3] = SACACBCC-SACACC+SASACB
*sinc+CACA
*sinc
;
o_rot
[4] = -SACACBSC+SACASC+SASACB
*cosc+CACA
*cosc
;
o_rot
[6] = -CASB
*cosc-SASB
*sinc
;
o_rot
[7] = CASB
*sinc-SASB
*cosc
;
}
private final double[][] wk_initRot_wdir=
new double[3][3];
/**
* int arGetInitRot( ARMarkerInfo *marker_info, double cpara[3][4], double rot[3][3] )
* Optimize:2008.04.20:STEP[716→698]
* @param marker_info
* @param i_direction
* @param i_param
* @throws NyARException
*/
public void initRot
(NyARSquare marker_info,
int i_direction
) throws NyARException
{
double cpara
[]= cparam.
get34Array();
double[][] wdir=wk_initRot_wdir
;//この関数で初期化される
double w, w1, w2, w3
;
int dir
;
int j
;
dir = i_direction
;
for( j =
0; j
< 2; j++
) {
w1 = marker_info.
line[(4-dir+j
)%4
][0] * marker_info.
line[(6-dir+j
)%4
][1]- marker_info.
line[(6-dir+j
)%4
][0] * marker_info.
line[(4-dir+j
)%4
][1];
w2 = marker_info.
line[(4-dir+j
)%4
][1] * marker_info.
line[(6-dir+j
)%4
][2]- marker_info.
line[(6-dir+j
)%4
][1] * marker_info.
line[(4-dir+j
)%4
][2];
w3 = marker_info.
line[(4-dir+j
)%4
][2] * marker_info.
line[(6-dir+j
)%4
][0]- marker_info.
line[(6-dir+j
)%4
][2] * marker_info.
line[(4-dir+j
)%4
][0];
wdir
[j
][0] = w1
*(cpara
[0*4+
1]*cpara
[1*4+
2]-cpara
[0*4+
2]*cpara
[1*4+
1])+ w2
*cpara
[1*4+
1]- w3
*cpara
[0*4+
1];
wdir
[j
][1] = -w1
*cpara
[0*4+
0]*cpara
[1*4+
2]+ w3
*cpara
[0*4+
0];
wdir
[j
][2] = w1
*cpara
[0*4+
0]*cpara
[1*4+
1];
w =
Math.
sqrt( wdir
[j
][0]*wdir
[j
][0]+ wdir
[j
][1]*wdir
[j
][1]+ wdir
[j
][2]*wdir
[j
][2] );
wdir
[j
][0] /= w
;
wdir
[j
][1] /= w
;
wdir
[j
][2] /= w
;
}
//以下3ケースは、計算エラーのときは例外が発生する。
check_dir
(wdir
[0], marker_info.
sqvertex[(4-dir
)%4
],marker_info.
sqvertex[(5-dir
)%4
], cpara
);
check_dir
(wdir
[1], marker_info.
sqvertex[(7-dir
)%4
],marker_info.
sqvertex[(4-dir
)%4
], cpara
);
check_rotation
(wdir
);
wdir
[2][0] = wdir
[0][1]*wdir
[1][2] - wdir
[0][2]*wdir
[1][1];
wdir
[2][1] = wdir
[0][2]*wdir
[1][0] - wdir
[0][0]*wdir
[1][2];
wdir
[2][2] = wdir
[0][0]*wdir
[1][1] - wdir
[0][1]*wdir
[1][0];
w =
Math.
sqrt( wdir
[2][0]*wdir
[2][0]+ wdir
[2][1]*wdir
[2][1]+ wdir
[2][2]*wdir
[2][2] );
wdir
[2][0] /= w
;
wdir
[2][1] /= w
;
wdir
[2][2] /= w
;
//<Optimize>
//rot[0][0] = wdir[0][0];
//rot[1][0] = wdir[0][1];
//rot[2][0] = wdir[0][2];
//rot[0][1] = wdir[1][0];
//rot[1][1] = wdir[1][1];
//rot[2][1] = wdir[1][2];
//rot[0][2] = wdir[2][0];
//rot[1][2] = wdir[2][1];
//rot[2][2] = wdir[2][2];
double[] rot=
this.
array;
rot
[0] = wdir
[0][0];
rot
[3] = wdir
[0][1];
rot
[6] = wdir
[0][2];
rot
[1] = wdir
[1][0];
rot
[4] = wdir
[1][1];
rot
[7] = wdir
[1][2];
rot
[2] = wdir
[2][0];
rot
[5] = wdir
[2][1];
rot
[8] = wdir
[2][2];
//</Optimize>
}
private final double[] wk_arModifyMatrix_combo=
new double[12];//[3][4];
private final double[] wk_arModifyMatrix_abc=
new double[3];
private final double[] wk_arModifyMatrix_rot=
new double[9];
/**
* arGetRot計算を階層化したModifyMatrix
* @param nyrot
* @param trans
* @param vertex
* @param pos2d
* @param num
* @return
* @throws NyARException
*/
public double modifyMatrix
(double trans
[],
double vertex
[][],
double pos2d
[][]) throws NyARException
{
int num=
this.
number_of_vertex;
double factor
;
double a1, b1, c1
;
double a2, b2, c2
;
double ma =
0.0, mb =
0.0, mc =
0.0;
double hx, hy, h, x, y
;
double err, minerr=
0;
int t1, t2, t3
;
int s1 =
0, s2 =
0, s3 =
0;
int i, j
;
final double[] combo=
this.
wk_arModifyMatrix_combo;//arGetNewMatrixで初期化されるので初期化不要//new double[3][4];
final double[] abc=wk_arModifyMatrix_abc
;
double[] rot=wk_arModifyMatrix_rot
;
arGetAngle
(abc
);//arGetAngle( rot, &a, &b, &c );
a2 = abc
[0];
b2 = abc
[1];
c2 = abc
[2];
factor =
10.0*Math.
PI/
180.0;
nyatla_arGetNewMatrix_row3
(trans,combo
);//comboの3行目を先に計算
for( j =
0; j
< 10; j++
) {
minerr =
1000000000.0;
for(t1=-
1;t1
<=
1;t1++
) {
a1 = a2 + factor
*t1
;
arGetRotA
(a1
);
for(t2=-
1;t2
<=
1;t2++
) {
b1 = b2 + factor
*t2
;
arGetRotB
(b1,rot
);
for(t3=-
1;t3
<=
1;t3++
) {
c1 = c2 + factor
*t3
;
arGetRotC
(c1,rot
);
//comboの0-2行目を計算
nyatla_arGetNewMatrix_row012
(rot,trans,combo
);//第二パラメタは常にnull//arGetNewMatrix(trans, null, combo );
err =
0.0;
for( i =
0; i
< num
; i++
) {
hx = combo
[0] * vertex
[i
][0]+ combo
[1] * vertex
[i
][1]+ combo
[2] * vertex
[i
][2]+ combo
[3];
hy = combo
[4] * vertex
[i
][0]+ combo
[5] * vertex
[i
][1]+ combo
[6] * vertex
[i
][2]+ combo
[7];
h = combo
[8] * vertex
[i
][0]+ combo
[9] * vertex
[i
][1]+ combo
[10] * vertex
[i
][2]+ combo
[11];
x = hx / h
;
y = hy / h
;
err +=
(pos2d
[i
][0] - x
) * (pos2d
[i
][0] - x
)+
(pos2d
[i
][1] - y
) * (pos2d
[i
][1] - y
);
}
if( err
< minerr
) {
minerr = err
;
ma = a1
;
mb = b1
;
mc = c1
;
s1 = t1
;
s2 = t2
;
s3 = t3
;
}
}
}
}
if( s1 ==
0 && s2 ==
0 && s3 ==
0 ){
factor
*=
0.5;
}
a2 = ma
;
b2 = mb
;
c2 = mc
;
}
arGetRot
(ma,mb,mc,
this.
array);
/* printf("factor = %10.5f\n", factor*180.0/MD_PI); */
return minerr/num
;
}
/**
* arGetNewMatrixの0-2行目を初期化する関数
* Optimize:2008.04.20:STEP[569->144]
* @param i_rot
* @param trans
* @param trans2
* @param ret
* double[3x4]配列
* @return
*/
private final void nyatla_arGetNewMatrix_row012
(double i_rot
[],
double trans
[],
double ret
[]) throws NyARException
{
int j
;
double c0,c1,c2
;
final double cpara2
[]=cparam.
get34Array();
for( j =
0; j
< 3; j++
) {
//cpara2_pt=cpara2[j];
c0=cpara2
[j
*4+
0];
c1=cpara2
[j
*4+
1];
c2=cpara2
[j
*4+
2];
ret
[j
*4+
0] = c0
* i_rot
[0]+ c1
* i_rot
[3]+ c2
* i_rot
[6];
ret
[j
*4+
1] = c0
* i_rot
[1]+ c1
* i_rot
[4]+ c2
* i_rot
[7];
ret
[j
*4+
2] = c0
* i_rot
[2]+ c1
* i_rot
[5]+ c2
* i_rot
[8];
//</Optimize>
}
return;
}
/**
* arGetNewMatrixの3行目を初期化する関数
* @param trans
* @param ret
* @throws NyARException
*/
private final void nyatla_arGetNewMatrix_row3
(double trans
[],
double ret
[]) throws NyARException
{
final double cpara2
[]=cparam.
get34Array();
int j,j_idx
;
for( j =
0; j
< 3; j++
) {
j_idx=j
*4;
ret
[j_idx+
3] = cpara2
[j_idx+
0] * trans
[0]+ cpara2
[j_idx+
1] * trans
[1]+ cpara2
[j_idx+
2] * trans
[2]+ cpara2
[j_idx+
3];
}
return;
}
}
/**
* NyARModifyMatrixの最適化バージョン3
* O3版の演算テーブル版
* 計算速度のみを追求する
*
*/
class NyARTransRot_O3
extends NyARTransRot_OptimizeCommon
{
public NyARTransRot_O3
(NyARParam i_param,
int i_number_of_vertex
) throws NyARException
{
super(i_param,i_number_of_vertex
);
if(i_number_of_vertex
!=
4){
//4以外の頂点数は処理しない
throw new NyARException
();
}
}
//private double CACA,SASA,SACA,CA,SA;
private final double[][] wk_initRot_wdir=
new double[3][3];
/**
* int arGetInitRot( ARMarkerInfo *marker_info, double cpara[3][4], double rot[3][3] )
* Optimize:2008.04.20:STEP[716→698]
* @param marker_info
* @param i_direction
* @param i_param
* @throws NyARException
*/
public void initRot
(NyARSquare marker_info,
int i_direction
) throws NyARException
{
double cpara
[]= cparam.
get34Array();
double[][] wdir=wk_initRot_wdir
;//この関数で初期化される
double w, w1, w2, w3
;
int dir
;
int j
;
dir = i_direction
;
for( j =
0; j
< 2; j++
) {
w1 = marker_info.
line[(4-dir+j
)%4
][0] * marker_info.
line[(6-dir+j
)%4
][1]- marker_info.
line[(6-dir+j
)%4
][0] * marker_info.
line[(4-dir+j
)%4
][1];
w2 = marker_info.
line[(4-dir+j
)%4
][1] * marker_info.
line[(6-dir+j
)%4
][2]- marker_info.
line[(6-dir+j
)%4
][1] * marker_info.
line[(4-dir+j
)%4
][2];
w3 = marker_info.
line[(4-dir+j
)%4
][2] * marker_info.
line[(6-dir+j
)%4
][0]- marker_info.
line[(6-dir+j
)%4
][2] * marker_info.
line[(4-dir+j
)%4
][0];
wdir
[j
][0] = w1
*(cpara
[0*4+
1]*cpara
[1*4+
2]-cpara
[0*4+
2]*cpara
[1*4+
1])+ w2
*cpara
[1*4+
1]- w3
*cpara
[0*4+
1];
wdir
[j
][1] = -w1
*cpara
[0*4+
0]*cpara
[1*4+
2]+ w3
*cpara
[0*4+
0];
wdir
[j
][2] = w1
*cpara
[0*4+
0]*cpara
[1*4+
1];
w =
Math.
sqrt( wdir
[j
][0]*wdir
[j
][0]+ wdir
[j
][1]*wdir
[j
][1]+ wdir
[j
][2]*wdir
[j
][2] );
wdir
[j
][0] /= w
;
wdir
[j
][1] /= w
;
wdir
[j
][2] /= w
;
}
//以下3ケースは、計算エラーのときは例外が発生する。
check_dir
(wdir
[0], marker_info.
sqvertex[(4-dir
)%4
],marker_info.
sqvertex[(5-dir
)%4
], cpara
);
check_dir
(wdir
[1], marker_info.
sqvertex[(7-dir
)%4
],marker_info.
sqvertex[(4-dir
)%4
], cpara
);
check_rotation
(wdir
);
wdir
[2][0] = wdir
[0][1]*wdir
[1][2] - wdir
[0][2]*wdir
[1][1];
wdir
[2][1] = wdir
[0][2]*wdir
[1][0] - wdir
[0][0]*wdir
[1][2];
wdir
[2][2] = wdir
[0][0]*wdir
[1][1] - wdir
[0][1]*wdir
[1][0];
w =
Math.
sqrt( wdir
[2][0]*wdir
[2][0]+ wdir
[2][1]*wdir
[2][1]+ wdir
[2][2]*wdir
[2][2] );
wdir
[2][0] /= w
;
wdir
[2][1] /= w
;
wdir
[2][2] /= w
;
double[] rot=
this.
array;
rot
[0] = wdir
[0][0];
rot
[3] = wdir
[0][1];
rot
[6] = wdir
[0][2];
rot
[1] = wdir
[1][0];
rot
[4] = wdir
[1][1];
rot
[7] = wdir
[1][2];
rot
[2] = wdir
[2][0];
rot
[5] = wdir
[2][1];
rot
[8] = wdir
[2][2];
//</Optimize>
}
private final double[][] wk_arModifyMatrix_double1D=
new double[8][3];
/**
* arGetRot計算を階層化したModifyMatrix
* 896
* @param nyrot
* @param trans
* @param vertex
* [m][3]
* @param pos2d
* [n][2]
* @return
* @throws NyARException
*/
public double modifyMatrix
(double trans
[],
double vertex
[][],
double pos2d
[][]) throws NyARException
{
double factor
;
double a2, b2, c2
;
double ma =
0.0, mb =
0.0, mc =
0.0;
double h, x, y
;
double err, minerr=
0;
int t1, t2, t3
;
int s1 =
0, s2 =
0, s3 =
0;
factor =
10.0*Math.
PI/
180.0;
double rot0,rot1,rot3,rot4,rot6,rot7
;
double combo00,combo01,combo02,combo03,combo10,combo11,combo12,combo13,combo20,combo21,combo22,combo23
;
double combo02_2,combo02_5,combo02_8,combo02_11
;
double combo22_2,combo22_5,combo22_8,combo22_11
;
double combo12_2,combo12_5,combo12_8,combo12_11
;
//vertex展開
final double VX00,VX01,VX02,VX10,VX11,VX12,VX20,VX21,VX22,VX30,VX31,VX32
;
double[] d_pt
;
d_pt=vertex
[0];VX00=d_pt
[0];VX01=d_pt
[1];VX02=d_pt
[2];
d_pt=vertex
[1];VX10=d_pt
[0];VX11=d_pt
[1];VX12=d_pt
[2];
d_pt=vertex
[2];VX20=d_pt
[0];VX21=d_pt
[1];VX22=d_pt
[2];
d_pt=vertex
[3];VX30=d_pt
[0];VX31=d_pt
[1];VX32=d_pt
[2];
final double P2D00,P2D01,P2D10,P2D11,P2D20,P2D21,P2D30,P2D31
;
d_pt=pos2d
[0];P2D00=d_pt
[0];P2D01=d_pt
[1];
d_pt=pos2d
[1];P2D10=d_pt
[0];P2D11=d_pt
[1];
d_pt=pos2d
[2];P2D20=d_pt
[0];P2D21=d_pt
[1];
d_pt=pos2d
[3];P2D30=d_pt
[0];P2D31=d_pt
[1];
final double cpara
[]=cparam.
get34Array();
final double CP0,CP1,CP2,CP3,CP4,CP5,CP6,CP7,CP8,CP9,CP10
;
CP0=cpara
[0];CP1=cpara
[1];CP2=cpara
[2];CP3=cpara
[3];
CP4=cpara
[4];CP5=cpara
[5];CP6=cpara
[6];CP7=cpara
[7];
CP8=cpara
[8];CP9=cpara
[9];CP10=cpara
[10];
combo03 = CP0
* trans
[0]+ CP1
* trans
[1]+ CP2
* trans
[2]+ CP3
;
combo13 = CP4
* trans
[0]+ CP5
* trans
[1]+ CP6
* trans
[2]+ CP7
;
combo23 = CP8
* trans
[0]+ CP9
* trans
[1]+ CP10
* trans
[2]+ cpara
[11];
double CACA,SASA,SACA,CA,SA
;
double CACACB,SACACB,SASACB,CASB,SASB
;
double SACASC,SACACBSC,SACACBCC,SACACC
;
final double[][] double1D=
this.
wk_arModifyMatrix_double1D;
final double[] abc =double1D
[0];
final double[] a_factor=double1D
[1];
final double[] sinb =double1D
[2];
final double[] cosb =double1D
[3];
final double[] b_factor=double1D
[4];
final double[] sinc =double1D
[5];
final double[] cosc =double1D
[6];
final double[] c_factor=double1D
[7];
double w,w2
;
double wsin,wcos
;
arGetAngle
(abc
);//arGetAngle( rot, &a, &b, &c );
a2 = abc
[0];
b2 = abc
[1];
c2 = abc
[2];
//comboの3行目を先に計算
for(int i =
0; i
< 10; i++
) {
minerr =
1000000000.0;
//sin-cosテーブルを計算(これが外に出せるとは…。)
for(int j=
0;j
<3;j++
){
w2=factor
*(j-
1);
w= a2 + w2
;
a_factor
[j
]=w
;
w= b2 + w2
;
b_factor
[j
]=w
;
sinb
[j
]=
Math.
sin(w
);
cosb
[j
]=
Math.
cos(w
);
w= c2 + w2
;
c_factor
[j
]=w
;
sinc
[j
]=
Math.
sin(w
);
cosc
[j
]=
Math.
cos(w
);
}
//
for(t1=
0;t1
<3;t1++
) {
SA =
Math.
sin(a_factor
[t1
]);
CA =
Math.
cos(a_factor
[t1
]);
//Optimize
CACA=CA
*CA
;
SASA=SA
*SA
;
SACA=SA
*CA
;
for(t2=
0;t2
<3;t2++
) {
wsin=sinb
[t2
];
wcos=cosb
[t2
];
CACACB=CACA
*wcos
;
SACACB=SACA
*wcos
;
SASACB=SASA
*wcos
;
CASB=CA
*wsin
;
SASB=SA
*wsin
;
//comboの計算1
combo02 = CP0
* CASB+ CP1
* SASB+ CP2
* wcos
;
combo12 = CP4
* CASB+ CP5
* SASB+ CP6
* wcos
;
combo22 = CP8
* CASB+ CP9
* SASB+ CP10
* wcos
;
combo02_2 =combo02
* VX02 + combo03
;
combo02_5 =combo02
* VX12 + combo03
;
combo02_8 =combo02
* VX22 + combo03
;
combo02_11=combo02
* VX32 + combo03
;
combo12_2 =combo12
* VX02 + combo13
;
combo12_5 =combo12
* VX12 + combo13
;
combo12_8 =combo12
* VX22 + combo13
;
combo12_11=combo12
* VX32 + combo13
;
combo22_2 =combo22
* VX02 + combo23
;
combo22_5 =combo22
* VX12 + combo23
;
combo22_8 =combo22
* VX22 + combo23
;
combo22_11=combo22
* VX32 + combo23
;
for(t3=
0;t3
<3;t3++
){
wsin=sinc
[t3
];
wcos=cosc
[t3
];
SACASC=SACA
*wsin
;
SACACC=SACA
*wcos
;
SACACBSC=SACACB
*wsin
;
SACACBCC=SACACB
*wcos
;
rot0 = CACACB
*wcos+SASA
*wcos+SACACBSC-SACASC
;
rot3 = SACACBCC-SACACC+SASACB
*wsin+CACA
*wsin
;
rot6 = -CASB
*wcos-SASB
*wsin
;
combo00 = CP0
* rot0+ CP1
* rot3+ CP2
* rot6
;
combo10 = CP4
* rot0+ CP5
* rot3+ CP6
* rot6
;
combo20 = CP8
* rot0+ CP9
* rot3+ CP10
* rot6
;
rot1 = -CACACB
*wsin-SASA
*wsin+SACACBCC-SACACC
;
rot4 = -SACACBSC+SACASC+SASACB
*wcos+CACA
*wcos
;
rot7 = CASB
*wsin-SASB
*wcos
;
combo01 = CP0
* rot1+ CP1
* rot4+ CP2
* rot7
;
combo11 = CP4
* rot1+ CP5
* rot4+ CP6
* rot7
;
combo21 = CP8
* rot1+ CP9
* rot4+ CP10
* rot7
;
//
err =
0.0;
h = combo20
* VX00+ combo21
* VX01+ combo22_2
;
x = P2D00 -
(combo00
* VX00+ combo01
* VX01+ combo02_2
) / h
;
y = P2D01 -
(combo10
* VX00+ combo11
* VX01+ combo12_2
) / h
;
err += x
*x+y
*y
;
h = combo20
* VX10+ combo21
* VX11+ combo22_5
;
x = P2D10 -
(combo00
* VX10+ combo01
* VX11+ combo02_5
) / h
;
y = P2D11 -
(combo10
* VX10+ combo11
* VX11+ combo12_5
) / h
;
err += x
*x+y
*y
;
h = combo20
* VX20+ combo21
* VX21+ combo22_8
;
x = P2D20 -
(combo00
* VX20+ combo01
* VX21+ combo02_8
) / h
;
y = P2D21 -
(combo10
* VX20+ combo11
* VX21+ combo12_8
) / h
;
err += x
*x+y
*y
;
h = combo20
* VX30+ combo21
* VX31+ combo22_11
;
x = P2D30 -
(combo00
* VX30+ combo01
* VX31+ combo02_11
) / h
;
y = P2D31 -
(combo10
* VX30+ combo11
* VX31+ combo12_11
) / h
;
err += x
*x+y
*y
;
if( err
< minerr
) {
minerr = err
;
ma = a_factor
[t1
];
mb = b_factor
[t2
];
mc = c_factor
[t3
];
s1 = t1-
1;
s2 = t2-
1;
s3 = t3-
1;
}
}
}
}
if( s1 ==
0 && s2 ==
0 && s3 ==
0 ){
factor
*=
0.5;
}
a2 = ma
;
b2 = mb
;
c2 = mc
;
}
arGetRot
(ma,mb,mc,
this.
array);
/* printf("factor = %10.5f\n", factor*180.0/MD_PI); */
return minerr/
4;
}
}