Exemple #1
0
VerdictVector vectorRotate(const double angle,
                           const VerdictVector &normalAxis,
                           const VerdictVector &referenceAxis)
{
    // A new coordinate system is created with the xy plane corresponding
    // to the plane normal to the normal axis, and the x axis corresponding to
    // the projection of the reference axis onto the normal plane.  The normal
    // plane is the tangent plane at the root point.  A unit vector is
    // constructed along the local x axis and then rotated by the given
    // ccw angle to form the new point.  The new point, then is a unit
    // distance from the global origin in the tangent plane.

    double x, y;

    // project a unit distance from root along reference axis

    VerdictVector yAxis = normalAxis * referenceAxis;
    VerdictVector xAxis = yAxis * normalAxis;
    yAxis.normalize();
    xAxis.normalize();

    x = cos(angle);
    y = sin(angle);

    xAxis *= x;
    yAxis *= y;
    return VerdictVector(xAxis + yAxis);
}
/*! 
  moves and rotates the quad such that it enables us to 
  use components of ef's
*/
void localize_quad_for_ef( VerdictVector node_pos[4])
{

  VerdictVector centroid(node_pos[0]);
  centroid += node_pos[1];
  centroid += node_pos[2];
  centroid += node_pos[3];
  
  centroid /= 4.0;

  node_pos[0] -= centroid;
  node_pos[1] -= centroid;
  node_pos[2] -= centroid;
  node_pos[3] -= centroid;

  VerdictVector rotate = node_pos[1] + node_pos[2] - node_pos[3] - node_pos[0];
  rotate.normalize();

  double cosine = rotate.x();
  double   sine = rotate.y();
 
  double xnew;
 
  for (int i=0; i < 4; i++) 
  {
    xnew =  cosine * node_pos[i].x() +   sine * node_pos[i].y();
    node_pos[i].y( -sine * node_pos[i].x() + cosine * node_pos[i].y() );
    node_pos[i].x(xnew);
  }
}
Exemple #3
0
double VerdictVector::vector_angle(const VerdictVector &vector1,
                                   const VerdictVector &vector2) const
{
    // This routine does not assume that any of the input vectors are of unit
    // length. This routine does not normalize the input vectors.
    // Special cases:
    //     If the normal vector is zero length:
    //         If a new one can be computed from vectors 1 & 2:
    //             the normal is replaced with the vector cross product
    //         else the two vectors are colinear and zero or 2PI is returned.
    //     If the normal is colinear with either (or both) vectors
    //         a new one is computed with the cross products
    //         (and checked again).

    // Check for zero length normal vector
    VerdictVector normal = *this;
    double normal_lensq = normal.length_squared();
    double len_tol = 0.0000001;
    if( normal_lensq <= len_tol )
    {
        // null normal - make it the normal to the plane defined by vector1
        // and vector2. If still null, the vectors are colinear so check
        // for zero or 180 angle.
        normal = vector1 * vector2;
        normal_lensq = normal.length_squared();
        if( normal_lensq <= len_tol )
        {
            double cosine = vector1 % vector2;
            if( cosine > 0.0 ) return 0.0;
            else               return VERDICT_PI;
        }
    }

    //Trap for normal vector colinear to one of the other vectors. If so,
    //use a normal defined by the two vectors.
    double dot_tol = 0.985;
    double dot = vector1 % normal;
    if( dot * dot >= vector1.length_squared() * normal_lensq * dot_tol )
    {
        normal = vector1 * vector2;
        normal_lensq = normal.length_squared();

        //Still problems if all three vectors were colinear
        if( normal_lensq <= len_tol )
        {
            double cosine = vector1 % vector2;
            if( cosine >= 0.0 ) return 0.0;
            else                return VERDICT_PI;
        }
    }
    else
    {
        //The normal and vector1 are not colinear, now check for vector2
        dot = vector2 % normal;
        if( dot * dot >= vector2.length_squared() * normal_lensq * dot_tol )
        {
            normal = vector1 * vector2;
        }
    }

    // Assume a plane such that the normal vector is the plane's normal.
    // Create yAxis perpendicular to both the normal and vector1. yAxis is
    // now in the plane. Create xAxis as the perpendicular to both yAxis and
    // the normal. xAxis is in the plane and is the projection of vector1
    // into the plane.

    normal.normalize();
    VerdictVector yAxis = normal;
    yAxis *= vector1;
    double yv = vector2 % yAxis;
    //  yAxis memory slot will now be used for xAxis
    yAxis *= normal;
    double xv = vector2 % yAxis;


    //  assert(x != 0.0 || y != 0.0);
    if( xv == 0.0 && yv == 0.0 )
    {
        return 0.0;
    }
    double angle = atan2( yv, xv );

    if (angle < 0.0)
    {
        angle += TWO_VERDICT_PI;
    }
    return angle;
}