/*! 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 ) ); }
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; }
int GeodesicArcIntercept(const LLPoint &pt1, double crs1, const LLPoint ¢er, 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; }
/*! \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 ) ); }