summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFuwn <[email protected]>2022-05-28 02:06:34 -0700
committerFuwn <[email protected]>2022-05-28 02:06:34 -0700
commit58c5ef034f006cea749affed1031f4e929cb3d3c (patch)
tree9e036d39acfd4bc532d4246432a043f997427741
downloadellipse-58c5ef034f006cea749affed1031f4e929cb3d3c.tar.xz
ellipse-58c5ef034f006cea749affed1031f4e929cb3d3c.zip
feat: initial commit
-rw-r--r--.gitignore15
-rw-r--r--build.ninja26
-rw-r--r--ellipse/ellipse.cc103
-rw-r--r--ellipse/ellipse.hh33
-rw-r--r--ellipse/test.cc43
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;
+}