#include <iostream>
#include <cmath> //sqrt
#include <vector> //std::vector
//You can use double instead of float if you want it to be more accurate
//but for these I don't think they really need to be more than a few
//digits
struct Point //this will be a basic point without operators
{
float x , y;
};
struct BoundingBox
{
float top , left , width , height;
};
class Shape
{
public:
virtual ~Shape(){}
virtual float area( void ) const = 0;
virtual float perimeter( void ) const = 0; //circumference for circles but oh well
protected:
Point _origin;
BoundingBox bounds;
};
//if you have a square derive from rectangle
//you might want to use virtual publics or consider
//composition instead of inheritance hierarchy
class Square : public Shape
{
public:
Square( const float width , const Point origin );
float area( void ) const;
float perimeter( void ) const;
private:
float width;
};
Square::Square( const float width , const Point origin ) : width( width )
{
_origin = origin;
bounds.left = origin.x - width / 2.0f;
bounds.top = origin.y - width / 2.0f;
bounds.width = width;
bounds.height = width;
}
float Square::area( void ) const
{
return width * width;
}
float Square::perimeter( void ) const
{
const int sides = 4;
return sides * width;
}
class Circle : public Shape
{
public:
Circle( const float radius , const Point origin );
float area( void ) const;
float perimeter( void ) const; //yeah its circum but in my example its perim
private:
float radius;
};
Circle::Circle( const float radius , const Point origin ) : radius( radius )
{
_origin = origin;
bounds.left = origin.x - radius;
bounds.top = origin.y + radius;
bounds.width = radius * 2; //radius * 2 = diameter
bounds.height = bounds.width; //height and width are same in a circle
}
float Circle::area( void ) const
{
const float pi = 3.14159f;
return pi * radius * radius;
}
float Circle::perimeter( void ) const
{
const float pi = 3.14159;
return 2 * pi * radius;
}
//mine is a Equilateral Triangle
class Triangle : public Shape
{
public:
Triangle( const float length , const Point origin );
float area( void ) const;
float perimeter( void ) const;
private:
float length;
};
Triangle::Triangle( const float length , const Point origin ) : length( length )
{
_origin = origin;
bounds.left = origin.x - length / 2.0f;
bounds.top = origin.y - length / 2.0f;
bounds.width = length;
bounds.height = sqrt( length * length - length / 2.0f * length / 2.0f );
}
float Triangle::area( void ) const
{
return length * bounds.height / 2.0f;
}
float Triangle::perimeter( void ) const
{
const int sides = 3;
return sides * length;
}
int main()
{
Point origin{ 10 , 5 }; //center of shape is at 10 , 5
std::vector<Shape *> shapes; //smart pointer would be better
shapes.push_back( new Triangle(10,origin) );
shapes.push_back( new Circle(5,origin) );
shapes.push_back( new Square(10,origin) );
for( const auto &it : shapes )
{
//triangle , circle , square
std::cout << "Area: " << it->area() << " Perimeter: " << it->perimeter() << std::endl;
delete it;
}
return 0;
}