#include <sstream>
#include <cmath>
#include <fstream>
#include <iostream> // for tests only
#include <string>
class Shape {
public:
struct Point {
double x;
double y;
};
virtual bool save(const std::string& path) const = 0;
virtual ~Shape() {}
protected:
virtual std::string info() const = 0;
};
bool Shape::save(const std::string& path) const {
std::ofstream file(path);
if (!file.good()) return false;
file << info() << std::endl;
return true;
}
double distance(const Shape::Point p1, const Shape::Point p2) {
return sqrt(pow(p2.x - p1.x, 2) + pow(p2.y - p1.y, 2));
}
class Triangle : public Shape {
public:
Triangle(const Point p1, const Point p2, const Point p3) {
m_p1 = p1;
m_p2 = p2;
m_p3 = p3;
}
virtual bool save(const std::string& path) const override {
return Shape::save(path);
}
protected:
virtual std::string info() const override {
std::stringstream ss;
ss << "Triangle" << std::endl;
ss << points() << std::endl;
ss << circ() << std::endl;
ss << area() << std::endl;
return ss.str();
}
private:
double area() const {
const double a = distance(m_p1, m_p2);
const double b = distance(m_p2, m_p3);
const double c = distance(m_p3, m_p1);
const double p = (a + b + c) / 2.0;
return sqrt(p * (p - a) * (p - b) * (p - c));
}
double circ() const {
return distance(m_p1, m_p2) + distance(m_p2, m_p3) + distance(m_p3, m_p1);
}
std::string points() const {
std::stringstream ss;
ss << m_p1.x << " " << m_p1.y << std::endl;
ss << m_p2.x << " " << m_p2.y << std::endl;
ss << m_p3.x << " " << m_p3.y;
return ss.str();
}
private:
Point m_p1;
Point m_p2;
Point m_p3;
};
class Circle : public Shape {
public:
Circle(Point p, const double r) {
m_p = p;
m_r = r;
}
virtual bool save(const std::string& path) const override {
return Shape::save(path);
}
protected:
virtual std::string info() const override {
std::stringstream ss;
ss << "Circle" << std::endl;
ss << m_p.x << " " << m_p.y << std::endl;
ss << m_r << std::endl;
ss << M_PI * 2.0 * m_r << std::endl; // circ
ss << M_PI * m_r * m_r << std::endl; // area
return ss.str();
}
private:
Point m_p;
double m_r;
};
void f(Shape** shapes, const int size, const std::string& base_path) {
for (int i = 0; i < size; ++i) {
shapes[i]->save(base_path + std::to_string(i));
}
}
/* -------------------------------------------------------------------------- */
// testing
int main() {
Shape::Point p1;
p1.x = 10;
p1.y = 10;
Shape::Point p2;
p2.x = 15;
p2.y = 10;
Shape::Point p3;
p3.x = 12.5;
p3.y = 15;
Shape::Point p4;
p4.x = 10;
p4.y = 20;
const int size = 3;
Shape** shapes = new Shape*[size];
shapes[0] = new Triangle(p1, p2, p3);
shapes[1] = new Triangle(p1, p2, p4);
shapes[2] = new Circle(p3, 10);
f(shapes, size, "shape");
delete[] shapes;
return 0;
}