1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136
|
#include <iostream>
#include <cmath>
using namespace std;
const double SMALL = 1.0e-10;
const double PI = 4.0 * atan( 1.0 );
//======================================================================
bool nearZero( double x )
{
return abs( x ) < SMALL;
}
//======================================================================
// Rotate position vector by theta radians
void rotate( double x, double y, double theta, double &xp, double &yp )
{
double c = cos( theta );
double s = sin( theta );
xp = c * x - s * y;
yp = s * x + c * y;
}
//======================================================================
// Coefficients in orthonormal axes rotated by theta radians (equivalent to rotating coordinates by -theta )
void rotateCoefficients( double A, double B, double C, double D, double E, double F, double theta,
double &AP, double &BP, double &CP, double &DP, double &EP, double &FP )
{
double c = cos( theta ), csq = c * c;
double s = sin( theta ), ssq = s * s;
double sc = s * c;
AP = csq * A + sc * B + ssq * C;
BP = ( csq - ssq ) * B + 2 * sc * ( C - A );
CP = ssq * A - sc * B + csq * C;
DP = c * D + s * E;
EP = c * E - s * D;
FP = F;
}
//======================================================================
int main()
{
double A, B, C, D, E, F;
cout << "Conic section Ax^2 + Bxy + Cy^2 + Dx + Ey + F = 0\n";
cout << "Input A, B, C, D, E, F: "; cin >> A >> B >> C >> D >> E >> F;
double theta;
double rhs, xc, yc;
// Determine angle by which to rotate axes if B != 0
if ( nearZero( B ) )
{
theta = 0.0;
}
else if ( nearZero( A - C ) )
{
theta = PI / 4;
}
else
{
theta = 0.5 * atan( B / ( A - C ) );
}
// Get coefficients in rotated axes
if ( !nearZero( B ) ) rotateCoefficients( A, B, C, D, E, F, theta, A, B, C, D, E, F );
// cout << A << ' ' << B << ' ' << C << ' ' << D << ' ' << E << ' ' << F << '\n';
cout << "Axes rotation: " << theta * 180.0 / PI << " degrees\n";
// Pick off cases
if ( nearZero( A ) && nearZero( C ) )
{
cout << "Not a conic section\n";
}
else if ( nearZero( A ) || nearZero( C ) )
{
if ( nearZero( A ) ) rhs = 0.25 * E * E / ( C * C ) - F / C;
else rhs = 0.25 * D * D / ( A * A ) - F / A;
if ( rhs <= 0.0 )
{
cout << "Not a conic section\n";
}
else
{
cout << "Parabola\n";
}
}
else if ( A * C < 0 )
{
rhs = 0.25 * D * D / A + 0.25 * E * E / C - F;
{
if ( nearZero( rhs ) )
{
cout << "Line pair\n";
}
else
{
cout << "Hyperbola\n";
}
}
}
else
{
rhs = 0.25 * D * D / A + 0.25 * E * E / C - F;
{
if ( rhs <= 0 )
{
cout << "Not a conic section\n";
}
else
{
xc = -0.5 * D / A;
yc = -0.5 * E / C;
rotate( xc, yc, theta, xc, yc );
if ( nearZero( A - C ) )
{
cout << "Circle:\n";
cout << " centre: " << xc << ", " << yc << '\n';
cout << " radius: " << sqrt( rhs / A ) << '\n';
}
else
{
cout << "Ellipse:\n";
cout << " centre: " << xc << ", " << yc << '\n';
cout << " semi-axes: " << sqrt( rhs / A ) << " and " << sqrt( rhs / C ) << '\n';
}
}
}
}
}
|