Comment + unique_ptr issue + correct horse battery staple

This commit is contained in:
Tyler Beckman 2024-11-18 00:18:28 -07:00
parent 99f1a4863a
commit 764f468028
Signed by: Ty
GPG key ID: 2813440C772555A4
19 changed files with 222 additions and 220 deletions

View file

@ -1,11 +1,11 @@
#include "Coordinate.h" #include "Coordinate.h"
Coordinate::Coordinate() { Coordinate::Coordinate() {
x = 0; x = 0;
y = 0; y = 0;
} }
Coordinate::Coordinate(const double X, const double Y) { Coordinate::Coordinate(const double X, const double Y) {
x = X; x = X;
y = Y; y = Y;
} }

View file

@ -1,12 +1,12 @@
#ifndef COORDINATE_H #ifndef COORDINATE_H
#define COORDINATE_H #define COORDINATE_H
class Coordinate { class Coordinate {
public: public:
Coordinate(); Coordinate();
Coordinate(const double X, const double Y); Coordinate(const double X, const double Y);
double x; double x;
double y; double y;
}; };
#endif // COORDINATE_H #endif // COORDINATE_H

View file

@ -3,12 +3,12 @@
#include "GeometryUtils.h" #include "GeometryUtils.h"
bool EquilateralTriangle::validate() { bool EquilateralTriangle::validate() {
double sideOne = calculate_distance(mVertices[0], mVertices[1]); double sideOne = calculate_distance(mVertices[0], mVertices[1]);
double sideTwo = calculate_distance(mVertices[1], mVertices[2]); double sideTwo = calculate_distance(mVertices[1], mVertices[2]);
double sideThree = calculate_distance(mVertices[2], mVertices[0]); double sideThree = calculate_distance(mVertices[2], mVertices[0]);
// Equilateral triangles must (a) Be a triangle and (b) Have three equal // Equilateral triangles must (a) Be a triangle and (b) Have three equal
// sides // sides
return lengths_make_triangle(sideOne, sideTwo, sideThree) && return lengths_make_triangle(sideOne, sideTwo, sideThree) &&
(double_eq(sideOne, sideTwo) && double_eq(sideTwo, sideThree)); (double_eq(sideOne, sideTwo) && double_eq(sideTwo, sideThree));
} }

View file

@ -2,8 +2,8 @@
#define EQUILATERAL_TRIANGLE_H #define EQUILATERAL_TRIANGLE_H
#include "Triangle.h" #include "Triangle.h"
class EquilateralTriangle : public ATriangle { class EquilateralTriangle : public ATriangle {
public: public:
bool validate() override; bool validate() override;
}; };
#endif // EQUILATERAL_TRIANGLE_H #endif // EQUILATERAL_TRIANGLE_H

View file

@ -5,29 +5,29 @@
const double EPSILON = 1e-7; const double EPSILON = 1e-7;
bool double_eq(double first, double second) { bool double_eq(double first, double second) {
if (std::abs(first - second) <= EPSILON) { if (std::abs(first - second) <= EPSILON) {
return true; return true;
} else { } else {
return false; return false;
} }
} }
double calculate_distance(Coordinate &firstPoint, Coordinate &secondPoint) { double calculate_distance(Coordinate& firstPoint, Coordinate& secondPoint) {
return std::sqrt(std::pow(secondPoint.x - firstPoint.x, 2) + return std::sqrt(std::pow(secondPoint.x - firstPoint.x, 2) +
std::pow(secondPoint.y - firstPoint.y, 2)); std::pow(secondPoint.y - firstPoint.y, 2));
} }
bool lengths_make_triangle(double sideOne, double sideTwo, double sideThree) { bool lengths_make_triangle(double sideOne, double sideTwo, double sideThree) {
// Not a triangle if one of the side lengths is 0 // Not a triangle if one of the side lengths is 0
if (sideOne <= 0 || sideTwo <= 0 || sideThree <= 0) { if (sideOne <= 0 || sideTwo <= 0 || sideThree <= 0) {
return false; return false;
} }
// Not a triangle if the sum of any two side lengths >= the third length // Not a triangle if the sum of any two side lengths >= the third length
if (sideOne + sideTwo <= sideThree || sideTwo + sideThree <= sideOne || if (sideOne + sideTwo <= sideThree || sideTwo + sideThree <= sideOne ||
sideThree + sideOne <= sideTwo) { sideThree + sideOne <= sideTwo) {
return false; return false;
} }
return true; return true;
} }

View file

@ -22,7 +22,7 @@ bool double_eq(double first, double second);
* @param secondPoint The second coordinate point to compare the first to * @param secondPoint The second coordinate point to compare the first to
* @return double The pythagorean distance between the two points * @return double The pythagorean distance between the two points
*/ */
double calculate_distance(Coordinate &firstPoint, Coordinate &secondPoint); double calculate_distance(Coordinate& firstPoint, Coordinate& secondPoint);
/** /**
* @brief Returns true if all of the side lengths in the specified array make a * @brief Returns true if all of the side lengths in the specified array make a

View file

@ -3,13 +3,13 @@
#include "GeometryUtils.h" #include "GeometryUtils.h"
bool IsoscelesTriangle::validate() { bool IsoscelesTriangle::validate() {
double sideOne = calculate_distance(mVertices[0], mVertices[1]); double sideOne = calculate_distance(mVertices[0], mVertices[1]);
double sideTwo = calculate_distance(mVertices[1], mVertices[2]); double sideTwo = calculate_distance(mVertices[1], mVertices[2]);
double sideThree = calculate_distance(mVertices[2], mVertices[0]); double sideThree = calculate_distance(mVertices[2], mVertices[0]);
// Isosceles triangles must (a) Be a triangle and (b) Have two sides that // Isosceles triangles must (a) Be a triangle and (b) Have two sides that
// equal each other // equal each other
return lengths_make_triangle(sideOne, sideTwo, sideThree) && return lengths_make_triangle(sideOne, sideTwo, sideThree) &&
(double_eq(sideOne, sideTwo) || double_eq(sideTwo, sideThree) || (double_eq(sideOne, sideTwo) || double_eq(sideTwo, sideThree) ||
double_eq(sideThree, sideOne)); double_eq(sideThree, sideOne));
} }

View file

@ -2,8 +2,8 @@
#define ISOSCELES_TRIANGLE_H #define ISOSCELES_TRIANGLE_H
#include "Triangle.h" #include "Triangle.h"
class IsoscelesTriangle : public ATriangle { class IsoscelesTriangle : public ATriangle {
public: public:
bool validate() override; bool validate() override;
}; };
#endif // ISOSCELES_TRIANGLE_H #endif // ISOSCELES_TRIANGLE_H

View file

@ -6,25 +6,25 @@
#include <SFML/Graphics/RenderTarget.hpp> #include <SFML/Graphics/RenderTarget.hpp>
APolygon::APolygon() { APolygon::APolygon() {
_color = sf::Color::White; _color = sf::Color::White;
mNumVertices = 0; mNumVertices = 0;
mVertices = nullptr; mVertices = nullptr;
} }
APolygon::~APolygon() { delete[] mVertices; } APolygon::~APolygon() { delete[] mVertices; }
void APolygon::setColor(const sf::Color COLOR) { _color = COLOR; } void APolygon::setColor(const sf::Color COLOR) { _color = COLOR; }
void APolygon::draw(sf::RenderTarget &window) { void APolygon::draw(sf::RenderTarget& window) {
sf::ConvexShape shape(mNumVertices); sf::ConvexShape shape(mNumVertices);
for (int i = 0; i < mNumVertices; i++) { for (int i = 0; i < mNumVertices; i++) {
shape.setPoint(i, sf::Vector2f(mVertices[i].x, mVertices[i].y)); shape.setPoint(i, sf::Vector2f(mVertices[i].x, mVertices[i].y));
} }
shape.setFillColor(_color); shape.setFillColor(_color);
window.draw(shape); window.draw(shape);
} }
void APolygon::setCoordinate(const int IDX, const Coordinate COORD) { void APolygon::setCoordinate(const int IDX, const Coordinate COORD) {
mVertices[IDX] = COORD; mVertices[IDX] = COORD;
} }

View file

@ -5,50 +5,50 @@
#include <SFML/Graphics.hpp> #include <SFML/Graphics.hpp>
class APolygon { class APolygon {
public: public:
/** /**
* @brief Construct a new Polygon object, with a white color and 0 vertices * @brief Construct a new Polygon object, with a white color and 0 vertices
*/ */
APolygon(); APolygon();
/** /**
* @brief Destroy the APolygon object * @brief Destroy the APolygon object
*/ */
virtual ~APolygon(); virtual ~APolygon();
/** /**
* @brief Sets the color of this polygon * @brief Sets the color of this polygon
* *
* @param COLOR The color to change the polygon to * @param COLOR The color to change the polygon to
*/ */
void setColor(const sf::Color COLOR); void setColor(const sf::Color COLOR);
/** /**
* @brief Draws this polygon to a SFML render target * @brief Draws this polygon to a SFML render target
* *
* @param window The render target to draw the polygon on * @param window The render target to draw the polygon on
*/ */
void draw(sf::RenderTarget &window); void draw(sf::RenderTarget& window);
/** /**
* @brief Sets the coordinate point at a specific vertex of this polygon * @brief Sets the coordinate point at a specific vertex of this polygon
* *
* @param IDX The index of the vertex to change * @param IDX The index of the vertex to change
* @param COORD The coordinate location to set the vertex to * @param COORD The coordinate location to set the vertex to
*/ */
void setCoordinate(const int IDX, const Coordinate COORD); void setCoordinate(const int IDX, const Coordinate COORD);
/** /**
* @brief Returns if the created polygon is valid or not * @brief Returns if the created polygon is valid or not
* *
* @return true All of the vertices of the polygon line up with the current * @return true All of the vertices of the polygon line up with the current
* polygon type * polygon type
* @return false The vertices are invalid for the current polygon type * @return false The vertices are invalid for the current polygon type
*/ */
virtual bool validate() = 0; virtual bool validate() = 0;
protected: protected:
short mNumVertices; short mNumVertices;
Coordinate *mVertices; Coordinate* mVertices;
private: private:
sf::Color _color; sf::Color _color;
}; };
#endif // POLYGON_H #endif // POLYGON_H

View file

@ -3,6 +3,6 @@
#include "Coordinate.h" #include "Coordinate.h"
AQuadrilateral::AQuadrilateral() { AQuadrilateral::AQuadrilateral() {
mNumVertices = 4; mNumVertices = 4;
mVertices = new Coordinate[4]; mVertices = new Coordinate[4];
} }

View file

@ -2,8 +2,8 @@
#define QUADRILATERAL_H #define QUADRILATERAL_H
#include "Polygon.h" #include "Polygon.h"
class AQuadrilateral : public APolygon { class AQuadrilateral : public APolygon {
public: public:
AQuadrilateral(); AQuadrilateral();
}; };
#endif // QUADRILATERAL_H #endif // QUADRILATERAL_H

View file

@ -4,25 +4,25 @@
#include "IsoscelesTriangle.h" #include "IsoscelesTriangle.h"
bool Rhombus::validate() { bool Rhombus::validate() {
double sideOne = calculate_distance(mVertices[0], mVertices[1]); double sideOne = calculate_distance(mVertices[0], mVertices[1]);
double sideTwo = calculate_distance(mVertices[1], mVertices[2]); double sideTwo = calculate_distance(mVertices[1], mVertices[2]);
double sideThree = calculate_distance(mVertices[2], mVertices[3]); double sideThree = calculate_distance(mVertices[2], mVertices[3]);
double sideFour = calculate_distance(mVertices[3], mVertices[0]); double sideFour = calculate_distance(mVertices[3], mVertices[0]);
IsoscelesTriangle firstTriangle; IsoscelesTriangle firstTriangle;
firstTriangle.setCoordinate(0, mVertices[0]); firstTriangle.setCoordinate(0, mVertices[0]);
firstTriangle.setCoordinate(1, mVertices[1]); firstTriangle.setCoordinate(1, mVertices[1]);
firstTriangle.setCoordinate(2, mVertices[2]); firstTriangle.setCoordinate(2, mVertices[2]);
IsoscelesTriangle secondTriangle; IsoscelesTriangle secondTriangle;
secondTriangle.setCoordinate(0, mVertices[0]); secondTriangle.setCoordinate(0, mVertices[0]);
secondTriangle.setCoordinate(1, mVertices[2]); secondTriangle.setCoordinate(1, mVertices[2]);
secondTriangle.setCoordinate(2, mVertices[3]); secondTriangle.setCoordinate(2, mVertices[3]);
// A valid rhombus must (a) Have vertices (0, 1, 2) make a valid isosceles // A valid rhombus must (a) Have vertices (0, 1, 2) make a valid isosceles
// triangle, (b) Have vertices (0, 2, 3) make a valid isosceles triangle, // triangle, (b) Have vertices (0, 2, 3) make a valid isosceles triangle,
// and (c) Have all sides of equal length // and (c) Have all sides of equal length
return firstTriangle.validate() && secondTriangle.validate() && return firstTriangle.validate() && secondTriangle.validate() &&
(double_eq(sideOne, sideTwo) && double_eq(sideTwo, sideThree) && (double_eq(sideOne, sideTwo) && double_eq(sideTwo, sideThree) &&
double_eq(sideThree, sideFour)); double_eq(sideThree, sideFour));
} }

View file

@ -2,8 +2,8 @@
#define RHOMBUS_H #define RHOMBUS_H
#include "Quadrilateral.h" #include "Quadrilateral.h"
class Rhombus : public AQuadrilateral { class Rhombus : public AQuadrilateral {
public: public:
bool validate() override; bool validate() override;
}; };
#endif // RHOMBUS_H #endif // RHOMBUS_H

View file

@ -3,13 +3,13 @@
#include "GeometryUtils.h" #include "GeometryUtils.h"
bool ScaleneTriangle::validate() { bool ScaleneTriangle::validate() {
double sideOne = calculate_distance(mVertices[0], mVertices[1]); double sideOne = calculate_distance(mVertices[0], mVertices[1]);
double sideTwo = calculate_distance(mVertices[1], mVertices[2]); double sideTwo = calculate_distance(mVertices[1], mVertices[2]);
double sideThree = calculate_distance(mVertices[2], mVertices[0]); double sideThree = calculate_distance(mVertices[2], mVertices[0]);
// Scalene triangles must (a) Be a triangle and (b) Have no sides that equal // Scalene triangles must (a) Be a triangle and (b) Have no sides that equal
// each other // each other
return lengths_make_triangle(sideOne, sideTwo, sideThree) && return lengths_make_triangle(sideOne, sideTwo, sideThree) &&
(!double_eq(sideOne, sideTwo) && !double_eq(sideTwo, sideThree) && (!double_eq(sideOne, sideTwo) && !double_eq(sideTwo, sideThree) &&
!double_eq(sideThree, sideOne)); !double_eq(sideThree, sideOne));
} }

View file

@ -2,8 +2,8 @@
#define SCALENE_TRIANGLE_H #define SCALENE_TRIANGLE_H
#include "Triangle.h" #include "Triangle.h"
class ScaleneTriangle : public ATriangle { class ScaleneTriangle : public ATriangle {
public: public:
bool validate() override; bool validate() override;
}; };
#endif // SCALENE_TRIANGLE_H #endif // SCALENE_TRIANGLE_H

View file

@ -1,6 +1,6 @@
#include "Triangle.h" #include "Triangle.h"
ATriangle::ATriangle() { ATriangle::ATriangle() {
mNumVertices = 3; mNumVertices = 3;
mVertices = new Coordinate[3]; mVertices = new Coordinate[3];
} }

View file

@ -2,8 +2,8 @@
#define TRIANGLE_H #define TRIANGLE_H
#include "Polygon.h" #include "Polygon.h"
class ATriangle : public APolygon { class ATriangle : public APolygon {
public: public:
ATriangle(); ATriangle();
}; };
#endif // TRIANGLE_H #endif // TRIANGLE_H

168
main.cpp
View file

@ -1,8 +1,10 @@
/** /**
* @author Tyler Beckman (tyler_beckman@mines.edu) * @author Tyler Beckman (tyler_beckman@mines.edu)
* @brief A program template for CSCI200 * @brief A program to read polygon points and colors from a data file and
* display them utilizing the SFML library, validating all shapes at each point
* during processing.
* @version 1 * @version 1
* @date 2024-09-21 * @date 2024-11-11
*/ */
#include "Coordinate.h" #include "Coordinate.h"
@ -21,98 +23,98 @@
#include <SFML/Graphics/Color.hpp> #include <SFML/Graphics/Color.hpp>
int main(void) { int main(void) {
// Start file parsing logic // Start file parsing logic
std::cout << "Please enter file path to read polygons from: "; std::cout << "Please enter file path to read polygons from: ";
std::string filePath; std::string filePath;
std::cin >> filePath; std::cin >> filePath;
std::ifstream file(filePath); std::ifstream file(filePath);
if (file.fail()) { if (file.fail()) {
std::cout << "Failed to open specified file path " << filePath std::cout << "Failed to open specified file path " << filePath
<< ", does it exist?" << std::endl; << ", does it exist?" << std::endl;
return 1; return 1;
} }
std::vector<std::unique_ptr<APolygon>> polygonList; std::vector<std::unique_ptr<APolygon>> polygonList;
std::unique_ptr<APolygon> currentPolygon; std::unique_ptr<APolygon> currentPolygon;
char type; char type;
double x1, y1, x2, y2, x3, y3, x4 = -1, y4 = -1; double x1, y1, x2, y2, x3, y3, x4 = -1, y4 = -1;
int r, g, b; int r, g, b;
while (true) { while (true) {
file >> type >> x1 >> y1 >> x2 >> y2 >> x3 >> y3; file >> type >> x1 >> y1 >> x2 >> y2 >> x3 >> y3;
if (type == 'R') { if (type == 'R') {
file >> x4 >> y4; file >> x4 >> y4;
} }
file >> r >> g >> b; file >> r >> g >> b;
if (file.fail()) { if (file.fail()) {
break; break;
} }
switch (type) { switch (type) {
case 'S': case 'S':
currentPolygon = std::make_unique<ScaleneTriangle>(); currentPolygon = std::make_unique<ScaleneTriangle>();
break; break;
case 'I': case 'I':
currentPolygon = std::make_unique<IsoscelesTriangle>(); currentPolygon = std::make_unique<IsoscelesTriangle>();
break; break;
case 'E': case 'E':
currentPolygon = std::make_unique<EquilateralTriangle>(); currentPolygon = std::make_unique<EquilateralTriangle>();
break; break;
case 'R': case 'R':
currentPolygon = std::make_unique<Rhombus>(); currentPolygon = std::make_unique<Rhombus>();
break; break;
default: default:
std::cout << "polygon is invalid - \"" << type << " " << x1 std::cout << "polygon is invalid - \"" << type << " " << x1 << " " << y1
<< " " << y1 << " " << x2 << " " << y2 << " " << x3 << " " << x2 << " " << y2 << " " << x3 << " " << y3 << " "
<< " " << y3 << " " << x4 << " " << y4 << " " << r << x4 << " " << y4 << " " << r << " " << g << " " << b << "\""
<< " " << g << " " << b << "\"" << std::endl; << std::endl;
continue; continue;
} }
currentPolygon->setCoordinate(0, Coordinate(x1, y1)); currentPolygon->setCoordinate(0, Coordinate(x1, y1));
currentPolygon->setCoordinate(1, Coordinate(x2, y2)); currentPolygon->setCoordinate(1, Coordinate(x2, y2));
currentPolygon->setCoordinate(2, Coordinate(x3, y3)); currentPolygon->setCoordinate(2, Coordinate(x3, y3));
if (type == 'R') { if (type == 'R') {
currentPolygon->setCoordinate(3, Coordinate(x4, y4)); currentPolygon->setCoordinate(3, Coordinate(x4, y4));
} }
currentPolygon->setColor(sf::Color(r, g, b)); currentPolygon->setColor(sf::Color(r, g, b));
if (!currentPolygon->validate()) { if (!currentPolygon->validate()) {
std::cout << "polygon is invalid - \"" << type << " " << x1 << " " std::cout << "polygon is invalid - \"" << type << " " << x1 << " " << y1
<< y1 << " " << x2 << " " << y2 << " " << x3 << " " << y3; << " " << x2 << " " << y2 << " " << x3 << " " << y3;
if (x4 != -1) { if (x4 != -1) {
std::cout << " " << x4 << " " << y4; std::cout << " " << x4 << " " << y4;
} }
std::cout << " " << r << " " << g << " " << b << "\"" << std::endl; std::cout << " " << r << " " << g << " " << b << "\"" << std::endl;
} else { } else {
polygonList.push_back(currentPolygon); polygonList.push_back(std::move(currentPolygon));
} }
}; };
// Start SFML Rendering logic // Start SFML Rendering logic
sf::RenderWindow window( sf::RenderWindow window(
sf::VideoMode(640, 640), ":3", sf::VideoMode(640, 640), "correct horse battery staple",
sf::Style::Titlebar | sf::Style::Close // Disable window resize sf::Style::Titlebar | sf::Style::Close // Disable window resize
); );
window.setVerticalSyncEnabled(true); window.setVerticalSyncEnabled(true);
sf::Event event; sf::Event event;
while (window.isOpen()) { while (window.isOpen()) {
window.clear(); window.clear();
for (size_t i = 0; i < polygonList.size(); i++) { for (size_t i = 0; i < polygonList.size(); i++) {
polygonList.at(i)->draw(window); polygonList.at(i)->draw(window);
} }
window.display(); window.display();
while (window.pollEvent(event)) { while (window.pollEvent(event)) {
if (event.type == sf::Event::Closed) { if (event.type == sf::Event::Closed) {
window.close(); window.close();
} }
} }
} }
} }