topical media & game development

talk show tell print

student-ar-org-libspark-flartoolkit-core-transmat-rotmatrix-FLARRotMatrix.ax

student-ar-org-libspark-flartoolkit-core-transmat-rotmatrix-FLARRotMatrix.ax [swf] flex


  /* 
   * PROJECT: FLARToolKit
   * --------------------------------------------------------------------------------
   * This work is based on the NyARToolKit developed by
   *   R.Iizuka (nyatla)
   * http://nyatla.jp/nyatoolkit/
   *
   * The FLARToolKit is ActionScript 3.0 version ARToolkit class library.
   * Copyright (C)2008 Saqoosha
   *
   * This program is free software; you can redistribute it and/or
   * modify it under the terms of the GNU General Public License
   * as published by the Free Software Foundation; either version 2
   * of the License, or (at your option) any later version.
   * 
   * This program is distributed in the hope that it will be useful,
   * but WITHOUT ANY WARRANTY; without even the implied warranty of
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   * GNU General Public License for more details.
   * 
   * You should have received a copy of the GNU General Public License
   * along with this framework; if not, write to the Free Software
   * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   * 
   * For further information please contact.
   *        http://www.libspark.org/wiki/saqoosha/FLARToolKit
   *        <saq(at)saqoosha.net>
   * 
   */
  
  package org.libspark.flartoolkit.core.transmat.rotmatrix {
          import org.libspark.flartoolkit.core.param.FLARPerspectiveProjectionMatrix;
          import org.libspark.flartoolkit.core.transmat.FLARTransMatResult;
          import org.libspark.flartoolkit.core.types.FLARDoublePoint3d;
          import org.libspark.flartoolkit.core.types.matrix.FLARDoubleMatrix33;        
  
          
回転行列計算用の、3x3行列

  
          public class @ax-student-ar-org-libspark-flartoolkit-core-transmat-rotmatrix-FLARRotMatrix extends FLARDoubleMatrix33 {        
  
                  
インスタンスを準備します。
parameter: i_param

  
                  public function @ax-student-ar-org-libspark-flartoolkit-core-transmat-rotmatrix-FLARRotMatrix(i_matrix:FLARPerspectiveProjectionMatrix) {
                          this.__initRot_vec1 = new FLARRotVector(i_matrix);
                          this.__initRot_vec2 = new FLARRotVector(i_matrix);
                          return;
                  }
  
                  private var __initRot_vec1:FLARRotVector;
                  private var __initRot_vec2:FLARRotVector;
                  
                  
                  public function initRotByPrevResult(i_prev_result:FLARTransMatResult):void {
  
                          this.m00 = i_prev_result.m00;
                          this.m01 = i_prev_result.m01;
                          this.m02 = i_prev_result.m02;
  
                          this.m10 = i_prev_result.m10;
                          this.m11 = i_prev_result.m11;
                          this.m12 = i_prev_result.m12;
  
                          this.m20 = i_prev_result.m20;
                          this.m21 = i_prev_result.m21;
                          this.m22 = i_prev_result.m22;
                          return;
                  }        
  
                  

parameter: i_linear FLARLinear[]
parameter: i_sqvertex FLARDoublePoint2d[]

  
                  public function initRotBySquare( i_linear:Array,  i_sqvertex:Array):void {
                          const vec1:FLARRotVector = this.__initRot_vec1;
                          const vec2:FLARRotVector = 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]);
  
                          //回転の最適化?
                          FLARRotVector.checkRotation(vec1, vec2);
  
                          this.m00 = vec1.v1;
                          this.m10 = vec1.v2;
                          this.m20 = vec1.v3;
                          this.m01 = vec2.v1;
                          this.m11 = vec2.v2;
                          this.m21 = vec2.v3;
                  
                          //最後の軸を計算
                          const w02:Number = vec1.v2 * vec2.v3 - vec1.v3 * vec2.v2;
                          const w12:Number = vec1.v3 * vec2.v1 - vec1.v1 * vec2.v3;
                          const w22:Number = vec1.v1 * vec2.v2 - vec1.v2 * vec2.v1;
                          const w:Number = Math.sqrt(w02 * w02 + w12 * w12 + w22 * w22);
                          this.m02 = w02 / w;
                          this.m12 = w12 / w;
                          this.m22 = w22 / w;
                          return;
                  }
  
                  
                  
                  
int arGetAngle( double rot[3][3], double *wa, double *wb, double *wc ) Optimize:2008.04.20:STEP[481→433] 3x3変換行列から、回転角を復元して返します。
parameter: o_angle @return

  
                  public function getAngle(o_angle:FLARDoublePoint3d):void {
                          var a:Number,b:Number,c:Number;
                          var sina:Number, cosa:Number, sinb:Number, cosb:Number, sinc:Number, cosc:Number;
                  
                          if (this.m22 > 1.0) {
                                  // <Optimize/>if( rot[2][2] > 1.0 ) {
                                  this.m22 = 1.0;// <Optimize/>rot[2][2] = 1.0;
                          } else if (this.m22 < -1.0) {
                                  // <Optimize/>}else if( rot[2][2] < -1.0 ) {
                                  this.m22 = -1.0;// <Optimize/>rot[2][2] = -1.0;
                          }
                          cosb = this.m22;
                          // <Optimize/>cosb = rot[2][2];
                          b = Math.acos(cosb);
                          sinb = Math.sin(b);
                          const rot02:Number = this.m02;
                          const rot12:Number = this.m12;
                          if (b >= 0.000001 || b <= -0.000001) {
                                  cosa = rot02 / sinb;
                                  // <Optimize/>cosa = rot[0][2] / sinb;
                                  sina = rot12 / 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]);
                                  const tmp:Number = (rot02 * rot02 + rot12 * rot12);
                                  sinc = (this.m21 * rot02 - this.m20 * rot12) / tmp;
                                  cosc = -(rot02 * this.m20 + rot12 * this.m21) / 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 = this.m00;
                                  //cosc = rot[0];// <Optimize/>cosc = rot[0][0];
                                  sinc = this.m01;
                                  //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_angle.x = a;
                          // wa.value=a;//*wa = a;
                          o_angle.y = b;
                          // wb.value=b;//*wb = b;
                          o_angle.z = c;
                          // wc.value=c;//*wc = c;
                          return;
                  }
  
                  
回転角から回転行列を計算してセットします。
parameter: i_x
parameter: i_y
parameter: i_z

  
                  public function setAngle(i_x:Number, i_y:Number, i_z:Number):void {
                          const sina:Number = Math.sin(i_x);
                          const cosa:Number = Math.cos(i_x);
                          const sinb:Number = Math.sin(i_y);
                          const cosb:Number = Math.cos(i_y);
                          const sinc:Number = Math.sin(i_z);
                          const cosc:Number = Math.cos(i_z);
                          // Optimize
                          const CACA:Number = cosa * cosa;
                          const SASA:Number = sina * sina;
                          const SACA:Number = sina * cosa;
                          const SASB:Number = sina * sinb;
                          const CASB:Number = cosa * sinb;
                          const SACACB:Number = SACA * cosb;
  
                          this.m00 = CACA * cosb * cosc + SASA * cosc + SACACB * sinc - SACA * sinc;
                          this.m01 = -CACA * cosb * sinc - SASA * sinc + SACACB * cosc - SACA * cosc;
                          this.m02 = CASB;
                          this.m10 = SACACB * cosc - SACA * cosc + SASA * cosb * sinc + CACA * sinc;
                          this.m11 = -SACACB * sinc + SACA * sinc + SASA * cosb * cosc + CACA * cosc;
                          this.m12 = SASB;
                          this.m20 = -CASB * cosc - SASB * sinc;
                          this.m21 = CASB * sinc - SASB * cosc;
                          this.m22 = cosb;
                          return;
                  }
  
                  
i_in_pointを変換行列で座標変換する。
parameter: i_in_point
parameter: i_out_point

  
                  public function getPoint3d(i_in_point:FLARDoublePoint3d, i_out_point:FLARDoublePoint3d):void {
                          const x:Number = i_in_point.x;
                          const y:Number = i_in_point.y;
                          const z:Number = i_in_point.z;
                          i_out_point.x = this.m00 * x + this.m01 * y + this.m02 * z;
                          i_out_point.y = this.m10 * x + this.m11 * y + this.m12 * z;
                          i_out_point.z = this.m20 * x + this.m21 * y + this.m22 * z;
                          return;
                  }
  
                  
複数の頂点を一括して変換する
parameter: i_in_point FLARDoublePoint3d[]
parameter: i_out_point FLARDoublePoint3d[]
parameter: i_number_of_vertex

  
                  public function getPoint3dBatch(i_in_point:Array, i_out_point:Array, i_number_of_vertex:int):void {
                          for(var i:int = i_number_of_vertex - 1; i >= 0; i--) {
                                  var out_ptr:FLARDoublePoint3d = i_out_point[i];
                                  var in_ptr:FLARDoublePoint3d = i_in_point[i];
                                  var x:Number = in_ptr.x;
                                  var y:Number = in_ptr.y;
                                  var z:Number = in_ptr.z;
                                  out_ptr.x = this.m00 * x + this.m01 * y + this.m02 * z;
                                  out_ptr.y = this.m10 * x + this.m11 * y + this.m12 * z;
                                  out_ptr.z = this.m20 * x + this.m21 * y + this.m22 * z;
                          }
                          return;
                  }        
          }
  }


(C) Æliens 04/09/2009

You may not copy or print any of this material without explicit permission of the author or the publisher. In case of other copyright issues, contact the author.