diff options
| author | Fuwn <[email protected]> | 2022-05-28 02:06:34 -0700 |
|---|---|---|
| committer | Fuwn <[email protected]> | 2022-05-28 02:06:34 -0700 |
| commit | 58c5ef034f006cea749affed1031f4e929cb3d3c (patch) | |
| tree | 9e036d39acfd4bc532d4246432a043f997427741 | |
| download | ellipse-58c5ef034f006cea749affed1031f4e929cb3d3c.tar.xz ellipse-58c5ef034f006cea749affed1031f4e929cb3d3c.zip | |
feat: initial commit
| -rw-r--r-- | .gitignore | 15 | ||||
| -rw-r--r-- | build.ninja | 26 | ||||
| -rw-r--r-- | ellipse/ellipse.cc | 103 | ||||
| -rw-r--r-- | ellipse/ellipse.hh | 33 | ||||
| -rw-r--r-- | ellipse/test.cc | 43 |
5 files changed, 220 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..adf120e --- /dev/null +++ b/.gitignore @@ -0,0 +1,15 @@ +# Visual Studio Code +.vscode + +# Artifacts +out + +# Ninja +.ninja_* + +# CLion +.idea + +# CMake +cmake-* +CMakeLists.txt diff --git a/build.ninja b/build.ninja new file mode 100644 index 0000000..4eac415 --- /dev/null +++ b/build.ninja @@ -0,0 +1,26 @@ +cc = clang++ +cxxflags = -Ofast -std=c++20 -Weverything -Wno-c++98-compat +out_dir = out +name = ellipse +src_dir = $name +out_ext = .exe + +rule clang_format + command = clang-format -i $src_dir/*.cc $src_dir/*.hh + +rule compile + command = $cc $cxxflags -c $in -o $out + +rule link + command = $cc $in -o $out + +build _format: clang_format + +build format: phony _format + +build $out_dir/$name.o: compile $src_dir/$name.cc +build $out_dir/test.o: compile $src_dir/test.cc + +build $out_dir/$name$out_ext: link $out_dir/$name.o $out_dir/test.o | format + +default $out_dir/$name$out_ext diff --git a/ellipse/ellipse.cc b/ellipse/ellipse.cc new file mode 100644 index 0000000..eb13b69 --- /dev/null +++ b/ellipse/ellipse.cc @@ -0,0 +1,103 @@ +#include <functional> +#include <iomanip> +#include <iostream> +#include <numbers> + +#include "ellipse.hh" + +// Enable this if for some reason your compiler doesn't support C++20. +// #define NO_CXX_20 + +void ellipse::set_axis(double _major, double _minor) { + this->major = _major; + this->minor = _minor; +} + +void ellipse::compute() { this->calculate(); } + +void ellipse::calculate() { + // Check if the ellipse is a horizontal or vertical ellipse: useful for + // obtaining correct results for the eccentricity calculation regardless of + // directional shift. + bool horizontal = 2 * this->major > 2 * this->minor; + // Define a Pi +#ifdef NO_CXX_20 + constexpr double pi = 3.14159265358979323846; +#else + double pi = std::numbers::pi; +#endif + + // Calculate the area of the ellipse, easy enough. + this->area = pi * this->major * this->minor; + + // Calculate the ellipse's eccentricity while accounting for the ellipse's + // directional shift via its transverse axis. + this->eccentricity = + std::sqrt(std::pow(horizontal ? this->major : this->minor, 2) - + std::pow(horizontal ? this->minor : this->major, 2)) / + (horizontal ? this->major : this->minor); + + // Crappy approximation + // this->circumference = + // 2 * pi * + // std::sqrt((std::pow(this->major, 2) + std::pow(this->minor, 2)) / 2); + + // A closer approximation, but still not 100% accurate for insanely large + // axis. + this->circumference = + pi * std::abs((3 * (this->major + this->minor)) - + std::sqrt(((3 * this->major) + this->minor) * + (this->major + (3 * this->minor)))); + + // Similar to the previous approximation, but more complicated and yields + // negligible fruits relative to its cognitive complexity. + // { + // double h = std::pow(this->major - this->minor, 2) / + // std::pow(this->major + this->minor, 2); + // + // this->circumference = pi * (this->major + this->minor) * + // ((1 + ((3 * h)) / (10 + std::sqrt(4 - (3 * h))))); + // } + + // I was going to attempt to get some kind of infinite series calculations + // involved, but it was just too boring... and probably out of the scope of + // this project anyway. + // std::function<double(double)> factorial; + // + // factorial = [&factorial](double n) -> double { + // if (n > 1) { + // return n * factorial(n - 1); + // } else { + // return 1; + // } + // }; + // + // { + // double i = std::numeric_limits<double>::infinity(); + // + // this->circumference = 2 * this->major * pi * + // (1 - (std::pow(factorial(2 * i), 2) / + // std::pow(std::pow(2, i) * factorial(i), + // 4)) + // * + // ((std::pow(this->eccentricity, 2 * i) / + // ((2 * i) - 1)))); + // } +} + +// double ellipse::get_major() { return this->major; } + +// double ellipse::get_minor() { return this->minor; } + +double ellipse::get_area() const { return this->area; } + +double ellipse::get_circumference() const { return this->circumference; } + +double ellipse::get_eccentricity() const { return this->eccentricity; } + +void ellipse::get_ellipse_description() const { + std::cout << std::fixed << std::setprecision(3) << "major: " << this->major + << "\nminor: " << this->minor << "\narea: " << this->area + << "\ncircumference: " << this->circumference + << "\neccentricity: " << this->eccentricity << std::endl; +} diff --git a/ellipse/ellipse.hh b/ellipse/ellipse.hh new file mode 100644 index 0000000..9296954 --- /dev/null +++ b/ellipse/ellipse.hh @@ -0,0 +1,33 @@ +#ifndef ELLIPSE_HH +#define ELLIPSE_HH + +class ellipse { +private: + double major; // a + double minor; // b + double area; + double circumference; // perimeter + double eccentricity; + +public: + // Lone constructor + ellipse() : major(0), minor(0), area(0), circumference(0), eccentricity(0) {} + + // Lone setter + void set_axis(double, double); + + // Getters + // double get_major(); + // double get_minor(); + [[nodiscard]] double get_area() const; + [[nodiscard]] double get_circumference() const; + [[nodiscard]] double get_eccentricity() const; + + void compute(); + void get_ellipse_description() const; + +private: + void calculate(); +}; + +#endif // ELLIPSE_HH diff --git a/ellipse/test.cc b/ellipse/test.cc new file mode 100644 index 0000000..89c5207 --- /dev/null +++ b/ellipse/test.cc @@ -0,0 +1,43 @@ +#include <iostream> + +#include "ellipse.hh" + +int main() { + // Create one ellipse object immediately and ... + ellipse e; + + // call the get_ellipse_description function. + e.get_ellipse_description(); + + for (;;) { + double major; + double minor; + + std::cout << "major: "; + std::cin >> major; + + if (major < 0) { + break; + } + + std::cout << "minor: "; + std::cin >> minor; + + if (minor < 0) { + break; + } + + // if (major < 0 || minor < 0) { + // break; + // } + + e.set_axis(major, minor); + e.compute(); + + std::cout << "area: " << e.get_area() << std::endl; + std::cout << "circumference: " << e.get_circumference() << std::endl; + std::cout << "eccentricity: " << e.get_eccentricity() << std::endl; + } + + return 0; +} |