File indexing completed on 2026-09-28 09:20:51
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #ifndef _MathPoly_Quadratic_HeaderFile
0015 #define _MathPoly_Quadratic_HeaderFile
0016
0017 #include <MathUtils_Types.hxx>
0018 #include <MathUtils_Core.hxx>
0019
0020 #include <cmath>
0021
0022
0023 namespace MathPoly
0024 {
0025 using namespace MathUtils;
0026
0027
0028
0029
0030
0031
0032 #ifdef _MSC_VER
0033 #pragma warning(push)
0034 #pragma warning(disable : 4723)
0035 #endif
0036 inline MathUtils::PolyResult Linear(double theA, double theB)
0037 {
0038 MathUtils::PolyResult aResult;
0039
0040 if (MathUtils::IsZero(theA))
0041 {
0042 if (MathUtils::IsZero(theB))
0043 {
0044 aResult.Status = MathUtils::Status::InfiniteSolutions;
0045 }
0046 else
0047 {
0048 aResult.Status = MathUtils::Status::NoSolution;
0049 }
0050 }
0051 else
0052 {
0053 aResult.Status = MathUtils::Status::OK;
0054 aResult.NbRoots = 1;
0055 aResult.Roots[0] = -theB / theA;
0056 }
0057
0058 return aResult;
0059 }
0060 #ifdef _MSC_VER
0061 #pragma warning(pop)
0062 #endif
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078 inline MathUtils::PolyResult Quadratic(double theA, double theB, double theC)
0079 {
0080 MathUtils::PolyResult aResult;
0081
0082
0083 if (MathUtils::IsZero(theA))
0084 {
0085 return Linear(theB, theC);
0086 }
0087
0088
0089 const double aScale = std::max({std::abs(theA), std::abs(theB), std::abs(theC)});
0090 if (aScale < MathUtils::THE_ZERO_TOL)
0091 {
0092 aResult.Status = MathUtils::Status::InfiniteSolutions;
0093 return aResult;
0094 }
0095
0096 const double aA = theA / aScale;
0097 const double aB = theB / aScale;
0098 const double aC = theC / aScale;
0099
0100
0101 const double aDisc = aB * aB - 4.0 * aA * aC;
0102
0103
0104 const double aDiscTol = MathUtils::THE_ZERO_TOL * (aB * aB + std::abs(4.0 * aA * aC));
0105
0106 if (aDisc < -aDiscTol)
0107 {
0108
0109 aResult.Status = MathUtils::Status::OK;
0110 aResult.NbRoots = 0;
0111 return aResult;
0112 }
0113
0114 if (std::abs(aDisc) <= aDiscTol)
0115 {
0116
0117 aResult.Status = MathUtils::Status::OK;
0118 aResult.NbRoots = 1;
0119 aResult.Roots[0] = -aB / (2.0 * aA);
0120 return aResult;
0121 }
0122
0123
0124
0125 const double aSqrtDisc = std::sqrt(aDisc);
0126
0127
0128 const double aQ = -0.5 * (aB + MathUtils::SignTransfer(aSqrtDisc, aB));
0129
0130 aResult.Status = MathUtils::Status::OK;
0131 aResult.NbRoots = 2;
0132 aResult.Roots[0] = aQ / aA;
0133 aResult.Roots[1] = aC / aQ;
0134
0135
0136 if (aResult.Roots[0] > aResult.Roots[1])
0137 {
0138 std::swap(aResult.Roots[0], aResult.Roots[1]);
0139 }
0140
0141 return aResult;
0142 }
0143
0144 }
0145
0146 #endif