2015-04-10 10 views
0

Я пытаюсь добавить шаг, рулон и рыскание объекта к матрице3d, затем получить qu quaternions и slerp вращение ... но в результате это действительно shaky, это первый раз, когда я занимаюсь кватернионами, и я новичок в 3d-программировании, к этому моменту я предполагаю правильное использование кватернионов (чтобы избежать блокировки карданных) есть ли способ не «добавлять» просто «назначать», новые значения вращения?Quaternion slerp from matrix3d ​​добавляет шаг поворота, рулон, рыскание AS3

pitch=(obj.pitch); 
yaw=(obj.yaw); 
roll=(obj.roll); 

mtrx:Matrix3D=new Matrix3D(); 
mtrx=setV[a].transform.clone(); 

mtrx.appendRotation(pitch,Vector3D.Y_AXIS); 
mtrx.appendRotation(roll,Vector3D.X_AXIS); 
mtrx.appendRotation(yaw,Vector3D.Z_AXIS); 

quat1:Quaternion=new Quaternion; 
quat1.fromMatrix(mtrx); 
quat2:Quaternion=new Quaternion; 
quat2.fromMatrix(setV[a].transform); 

quat2.slerp(quat2,quat1,0.1); 

mtrx2:Matrix3D=new Matrix3D();    
quat1.toMatrix3D(mtrx2); 

setV[a].transform=mtrx.clone(); 
+0

Что вы подразумеваете под «действительно шаткой»? Как часто вы обновляете подачу/рыскание/рулон? – Fygo

+0

Вращение похоже на блокировку карданного вала, что происходит даже с кватернионами, я обновляю вал качания в каждом кадре. Спасибо за ответ. – zkr

+0

Это не происходит из-за кватернионов (вы не можете получить блокировку карданного шарнира с кватернионами), это, вероятно, потому, что вы конвертируете рыскание/шаг/рулон в квартет, и, очевидно, это может произойти с рысканием/шагом/броском, поэтому я предполагаю, что преобразование будет иметь нет выгоды. (возьмите это с солью, я не очень хорош в 3D-материалах). Что именно возвращает вам рыскание/шаг/рулон? Некоторое устройство? Разве он не поддерживает x/y/z/w для кватернионов? Кроме того, если вы обновляете его на каждом фрейме, нет смысла снимать его imho. Вам лучше попытаться сгладить значения (удалить всплески), иначе он будет дрожать. – Fygo

ответ

0

Проверьте этот класс, я сделал его для IMU Brick, поэтому, если у вас есть аналогичное устройство, оно может сработать для вас. Я получал значения из javascript, но в вашем случае это может быть другим. Вам также может потребоваться настроить relX, rely ... и т. Д. (Наблюдайте, как, например, мне пришлось изменить quaternionArray [0] как отрицательный и т. Д.).

package com.company.product.imu { 

    import flash.external.ExternalInterface; 
    import flash.geom.Matrix3D; 

    public final class Brick { 

     private static var _relX:Number; 
     private static var _relY:Number; 
     private static var _relZ:Number; 
     private static var _relW:Number; 

     public function Brick() { 
      super(); 
      throw new Error("Brick is a static class."); 
     } 

     public static function saveOrientation():void { 
      var quaternionString:String; 
      if(ExternalInterface.available) { 
       try { 
        quaternionString = ExternalInterface.call("getQuaternionString"); 
       } 
       catch(e:SecurityError) {} 
      } 
      var quaternionArray:Array = quaternionString.split(","); 
      _relX = -quaternionArray[0]; 
      _relY = -quaternionArray[1]; 
      _relZ = quaternionArray[2]; 
      _relW = quaternionArray[3]; 
     } 

     public static function getTransformationMatrix():Matrix3D { 
      var quaternionString:String; 
      if(isNaN(_relX)) { 
       saveOrientation(); 
      } 
      if(ExternalInterface.available) { 
       try { 
        quaternionString = ExternalInterface.call("getQuaternionString"); 
       } 
       catch(e:SecurityError) {} 
      } 
      var quaternionArray:Array = quaternionString.split(","); 
      var x:Number = -quaternionArray[0]; 
      var y:Number = -quaternionArray[1]; 
      var z:Number = quaternionArray[2]; 
      var w:Number = -quaternionArray[3]; 

      var wn:Number = w * _relW - x * _relX - y * _relY - z * _relZ; 
      var xn:Number = w * _relX + x * _relW + y * _relZ - z * _relY; 
      var yn:Number = w * _relY - x * _relZ + y * _relW + z * _relX; 
      var zn:Number = w * _relZ + x * _relY - y * _relX + z * _relW; 

      x = xn; 
      y = yn; 
      z = zn; 
      w = wn; 

      var xx:Number = x * x; 
      var yy:Number = y * y; 
      var zz:Number = z * z; 
      var xy:Number = x * y; 
      var xz:Number = x * z; 
      var yz:Number = y * z; 
      var wx:Number = w * x; 
      var wy:Number = w * y; 
      var wz:Number = w * z; 

      var matrix:Matrix3D = new Matrix3D(); 
      var matrixData:Vector.<Number> = new <Number>[1 - 2 * (yy + zz), 2 * (xy - wz), 2 * (xz + wy), 0.0, 
                  2 * (xy + wz), 1 - 2 * (xx + zz), 2 * (yz - wx), 0.0, 
                  2 * (xz - wy), 2 * (yz + wx), 1 - 2 * (xx + yy), 0.0, 
                  0.0, 0.0, 0.0, 1]; 
      matrix.rawData = matrixData; 
      return matrix; 
     } 
    } 
} 

Тогда, в каком-то другом классе (мой основной, в данном случае) я просто позвонить:

private function onEnterFrame(e:Event):void { 
    if(_drill.isLoaded) { 
     _drill.transform = Brick.getTransformationMatrix(); 
     //other things to perform 
    } 
    _view.render(); 
} 

Также обратите внимание, что ошибка JS не ловя имеет смысла в моем случае, потому что я был уверен, что это никогда не потерпит неудачу. Конечно, если это может упасть для вас, вам придется с этим справиться (мой код на самом деле бросил бы ошибку в этом случае).

+0

Спасибо, я тщательно проверю документ, чтобы попытаться понять кватернионы. быстрый вопрос, если устройство предоставляет 4 значения для каждой из 3-х осей, я должен вычислить все 3 оси для вращения с кватернионами? я действительно потерялся здесь. – zkr

+0

@zkr Устройство должно предоставить вам 4 значения (x, y, z, w), из которых вы можете вычислить матрицу преобразования, а также шаг, рулон, рыскание. Точная математика вне меня, но я уверен, что страница в Википедии объясняет это. ;) – Fygo

+0

Я очень ценю помощь, я нашел это http://mousman.com/agal/?p=467, я буду продолжать исследования, чтобы понять, как используются кватернионы, но это было очень полезно для указателей, которые вы сделали. Спасибо за ваше время. – zkr