Problem of Apollonius: Difference between revisions
Content added Content deleted
(New post.) |
|||
Line 758: | Line 758: | ||
} |
} |
||
</syntaxhighlight> |
</syntaxhighlight> |
||
=={{header|C++}}== |
|||
<syntaxhighlight lang="c++"> |
|||
#include <cmath> |
|||
#include <iostream> |
|||
#include <stdexcept> |
|||
struct Circle { |
|||
double x; |
|||
double y; |
|||
double radius; |
|||
void display() { |
|||
std::cout << "centre(" << x << ", " << y << ")" << ", radius = " << radius << std::endl; |
|||
} |
|||
}; |
|||
double square(const double& value) { |
|||
return value * value; |
|||
} |
|||
/** |
|||
* The parameters s1, s2, s3 indicate whether the result circle is |
|||
* internally tangent to the corresponding argument circle (-1), or |
|||
* externally tangent to the corresponding argument circle (+1). |
|||
*/ |
|||
Circle solve_apollonius(const Circle& circle1, const Circle& circle2, const Circle& circle3, |
|||
const double& s1, const double& s2, const double& s3) { |
|||
if ( abs(s1) != 1 || abs(s2) != 1 || abs(s3) != 1 ) { |
|||
throw std::invalid_argument("Parameters s1, s2, s3 must be +1 or -1"); |
|||
} |
|||
const double v11 = 2 * circle2.x - 2 * circle1.x; |
|||
const double v12 = 2 * circle2.y - 2 * circle1.y; |
|||
const double v13 = square(circle1.x) - square(circle2.x) + square(circle1.y) - square(circle2.y) |
|||
- square(circle1.radius) + square(circle2.radius); |
|||
const double v14 = 2 * s2 * circle2.radius - 2 * s1 * circle1.radius; |
|||
const double v21 = 2 * circle3.x - 2 * circle2.x; |
|||
const double v22 = 2 * circle3.y - 2 * circle2.y; |
|||
const double v23 = square(circle2.x) - square(circle3.x) + square(circle2.y) - square(circle3.y) |
|||
- square(circle2.radius) + square(circle3.radius); |
|||
const double v24 = 2 * s3 * circle3.radius - 2 * s2 * circle2.radius; |
|||
const double w12 = v12 / v11; |
|||
const double w13 = v13 / v11; |
|||
const double w14 = v14 / v11; |
|||
const double w22 = v22 / v21 - w12; |
|||
const double w23 = v23 / v21 - w13; |
|||
const double w24 = v24 / v21 - w14; |
|||
const double p = -w23 / w22; |
|||
const double q = w24 / w22; |
|||
const double m = -w12 * p - w13; |
|||
const double n = w14 - w12 * q; |
|||
const double a = square(n) + square(q) - 1; |
|||
const double b = 2 * m * n - 2 * n * circle1.x + 2 * p * q - 2 * q * circle1.y + 2 * s1 * circle1.radius; |
|||
const double c = square(circle1.x) + square(m) - 2 * m * circle1.x + square(p) |
|||
+ square(circle1.y) - 2 * p * circle1.y - square(circle1.radius); |
|||
const double discriminant = b * b - 4 * a * c; |
|||
const double root = ( -b - sqrt(discriminant) ) / ( 2 * a ); |
|||
const double centre_x = m + n * root; |
|||
const double centre_y = p + q * root; |
|||
return Circle(centre_x, centre_y, root); |
|||
} |
|||
int main() { |
|||
Circle circle1(0.0, 0.0, 1.0); |
|||
Circle circle2(4.0, 0.0, 1.0); |
|||
Circle circle3(2.0, 4.0, 2.0); |
|||
std::cout << "The three initial circles are:" << std::endl; |
|||
std::cout << " Circle 1: "; circle1.display(); |
|||
std::cout << " Circle 2: "; circle2.display(); |
|||
std::cout << " Circle 3: "; circle3.display(); |
|||
std::cout << std::endl; |
|||
std::cout << "The internal circle is: "; solve_apollonius(circle1, circle2, circle3, -1.0, -1.0, -1.0).display(); |
|||
std::cout << "The external circle is: "; solve_apollonius(circle1, circle2, circle3, 1.0, 1.0, 1.0).display(); |
|||
} |
|||
</syntaxhighlight> |
|||
{{ out }} |
|||
<pre> |
|||
The three initial circles are: |
|||
Circle 1: centre(0, 0), radius = 1 |
|||
Circle 2: centre(4, 0), radius = 1 |
|||
Circle 3: centre(2, 4), radius = 2 |
|||
The internal circle is: centre(2, 0.833333), radius = 1.16667 |
|||
The external circle is: centre(2, 2.1), radius = 3.9 |
|||
</pre> |
|||
=={{header|CoffeeScript}}== |
=={{header|CoffeeScript}}== |