예제 #1
0
void quatMult(Quaternion *q1, Quaternion *q2, Quaternion *result) {

    Quaternion a, b;

    if(q1 == NULL || q2 == NULL || result == NULL) { return; }

    quatCopy(&a, q1); // Make copies so result can be operand
    quatCopy(&b, q2);

    result->w = a.w*b.w - a.x*b.x - a.y*b.y - a.z*b.z;
    result->x = a.w*b.x + b.w*a.x + a.y*b.z - a.z*b.y;
    result->y = a.w*b.y + b.w*a.y - a.x*b.z + a.z*b.x;
    result->z = a.w*b.z + b.w*a.z + a.x*b.y - a.y*b.x;

}
예제 #2
0
//*****************************************************************************
//
// * The distance between two quaternion
//============================================================================
double SJCQuaterniond::
distance(SJCQuaterniond& quat ) 
//============================================================================
{
  SJCQuaterniond quatCopy( quat );
  
  double dotProd = 
    w_ * quat.w() + x_ * quat.x() + y_ * quat.y() + z_ * quat.z();
   
  // If the antipode is closer, use it instead.
  if( dotProd < 0 ) {
    quatCopy.set(quatCopy.w() * -1, quatCopy.x() * -1, 
		 quatCopy.y() * -1, quatCopy.z() * -1);
  }
  
  // Represent this Quaternion as an offset from the given Quaternion.
  quatCopy.inverse();
  quatCopy *= *this;

  double angle = SJCACos(quatCopy.w()) * 2;
  
  if( angle > M_PI ) {
    angle -= M_2PI;
  }
  
  return( fabs(angle) );
}
예제 #3
0
파일: slew.c 프로젝트: Humhu/ibird-lib
// qtarget = qcurr*qdisp
// qcurr'*qtarget = qdisp
void slewProcess(Quaternion *input, Quaternion *output) {

    Quaternion conjugate, displacement;
    bams32_t input_angle, limited_angle;
    float sin_input, sin_limited, scale;

    if(!is_ready || !is_running || max_angular_displacement == 0) {
        quatCopy(output, input);
        return;
    }

    // Calculate displacement
    quatConj(&prev_ref, &conjugate);
    quatMult(&conjugate, input, &displacement);

    // Calculate displacement magnitude
    input_angle = bams16ToBams32(bams16Acos(displacement.w)*2);
    if(input_angle == 0) { // Check for no displacement case
        quatCopy(output, input);
        return;
    }
    sin_input = bams32Sin(input_angle/2);

    // Apply displacement limits
    if(input_angle > max_angular_displacement) {
        limited_angle = max_angular_displacement;
    } else if(input_angle < -max_angular_displacement) {
        limited_angle = -max_angular_displacement;
    } else {
        limited_angle = input_angle;
    }

    sin_limited = bams32SinFine(limited_angle/2);
    scale = sin_limited/sin_input;

    displacement.w = bams32CosFine(limited_angle/2);
    displacement.x = displacement.x*scale;
    displacement.y = displacement.y*scale;
    displacement.z = displacement.z*scale;

    // Apply limited displacement
    quatMult(&prev_ref, &displacement, output);
    quatNormalize(output);
    quatCopy(&prev_ref, output);

}