Пример #1
0
 /*! This method returns true if and only if the matrix is
  * (approximately) equal to the identity matrix. The precision used
  * by this function is 1e-6. */
 bool matrix3x3::isUnitMatrix(void) const
 {
   return ( isDiagonal()
         && IsApprox( ele[0][0], 1.0, 1e-6 )
         && IsApprox( ele[1][1], 1.0, 1e-6 )
         && IsApprox( ele[2][2], 1.0, 1e-6 ) );
 }
Пример #2
0
  OBUnitCell::LatticeType OBUnitCell::GetLatticeType() const
  {
    if (_lattice != Undefined)
      return _lattice;
    else if (_spaceGroup != NULL)
      return GetLatticeType(_spaceGroup->GetId());

    double a = GetA();
    double b = GetB();
    double c = GetC();
    double alpha = GetAlpha();
    double beta  = GetBeta();
    double gamma = GetGamma();

    unsigned int rightAngles = 0;
    if (IsApprox(alpha, 90.0, 1.0e-3)) rightAngles++;
    if (IsApprox(beta,  90.0, 1.0e-3)) rightAngles++;
    if (IsApprox(gamma, 90.0, 1.0e-3)) rightAngles++;

    // recast cache member "_lattice" as mutable
    OBUnitCell::LatticeType *lattice =
      const_cast<OBUnitCell::LatticeType*>(&_lattice);

    switch (rightAngles)
      {
      case 3:
        if (IsApprox(a, b, 1.0e-4) && IsApprox(b, c, 1.0e-4))
          *lattice = Cubic;
        else if (IsApprox(a, b, 1.0e-4) || IsApprox(b, c, 1.0e-4))
          *lattice = Tetragonal;
        else
          *lattice = Orthorhombic;
        break;
      case 2:
        if ( (IsApprox(alpha, 120.0, 1.0e-3)
              || IsApprox(beta, 120.0, 1.0e-3)
              || IsApprox(gamma, 120.0f, 1.0e-3))
             && (IsApprox(a, b, 1.0e-4) || IsApprox(b, c, 1.0e-4)) )
          *lattice = Hexagonal;
        else
          *lattice = Monoclinic;
        break;
      default:
        if (IsApprox(a, b, 1.0e-4) && IsApprox(b, c, 1.0e-4))
          *lattice = Rhombohedral;
        else
          *lattice = Triclinic;
      }

    return *lattice;
  }
Пример #3
0
    int GeodesicArcIntercept(const LLPoint &pt1, double crs1,
                             const LLPoint &center, double radius,
                             LLPoint &intPtC1, LLPoint &intPtC2, double dTol)
    {
        double dCrsFromPt, dDistFromPt;
        const LLPoint perpPt = PerpIntercept(pt1, crs1, center, dCrsFromPt, dDistFromPt, dTol);

        InverseResult result;
        DistVincenty(perpPt, center, result);

        if (result.distance > radius)
            return 0;

        if (fabs(result.distance - radius) < dTol)
        {
            intPtC1 = perpPt;
            return 1;
        }

        const double perpDist = result.distance;
        DistVincenty(perpPt, pt1, result);

        if (IsApprox(cos(perpDist / kSphereRadius), 0.0, 1e-8))
            return 0;

        double crs = result.azimuth;
        double dist = kSphereRadius * acos(cos(radius / kSphereRadius) / cos(perpDist / kSphereRadius));
        LLPoint pt = DestVincenty(perpPt, crs, dist);

        const int nIntersects = 2;
        for (int i = 0; i < nIntersects; i++)
        {
            DistVincenty(center, pt, result);
            const double rcrs = result.reverseAzimuth;
            const double dErr = radius - result.distance;

            double distarray[2], errarray[2];
            distarray[0] = dist;
            errarray[0] = dErr;

            DistVincenty(pt, perpPt, result);
            const double bcrs = result.azimuth;

            DistVincenty(center, pt, result);
            const double dAngle = fabs(SignAzimuthDifference(result.azimuth, result.reverseAzimuth));
            const double B = fabs(SignAzimuthDifference(bcrs, rcrs) + M_PI - dAngle);
            const double A = acos(sin(B) * cos(fabs(dErr) / kSphereRadius));
            double c;
            if (fabs(sin(A)) < dTol)
                c = dErr;
            else if (fabs(A) < dTol)
                c = dErr / cos(B);
            else
                c = kSphereRadius * asin(sin(dErr / kSphereRadius) / sin(A));

            dist = dErr > 0 ? dist + c : dist - c;
            pt = DestVincenty(perpPt, crs, dist);
            DistVincenty(center, pt, result);
            distarray[1] = dist;
            errarray[1] = radius - result.distance;

            while (fabs(dErr) > dTol)
            {
                FindLinearRoot(distarray, errarray, dist);
                if (std::isnan(dist))
                    break;

                pt = DestVincenty(perpPt, crs, dist);
                DistVincenty(center, pt, result);
                distarray[0] = distarray[1];
                errarray[0] = errarray[1];
                distarray[1] = dist;
                errarray[1] = radius - result.distance;
                break;
            }

            if (i == 0)
                intPtC1 = pt;
            else if (i == 1)
                intPtC2 = pt;
            else
                break;

            crs += M_PI;
            pt = DestVincenty(perpPt, crs, dist);
            DistVincenty(center, pt, result);
            errarray[0] = radius - result.distance;
        }

        return nIntersects;
    }
Пример #4
0
 /*! \return False if there are indices i,j such that
   fabs(*this[i][j]-*this[j][i]) > 1e-6. Otherwise, it returns
   true. */
 bool matrix3x3::isSymmetric(void) const
 {
   return( IsApprox( ele[0][1], ele[1][0], 1e-6 )
        && IsApprox( ele[0][2], ele[2][0], 1e-6 )
        && IsApprox( ele[1][2], ele[2][1], 1e-6 ) );
 }