/*
* File: ShapeTwoD.h
* Author: Administrator
*
* Created on October 30, 2012, 12:05 AM
*/
#ifndef SHAPETWOD_H
#define SHAPETWOD_H
#include <string>
#include <math.h>
using namespace std;
struct Point {
int x, y;
};
class ShapeTwoD {
public:
ShapeTwoD(string shapename, bool containsWS);
string getName();
bool getContainsWarpSpace();
string toString();
virtual double computeArea();
virtual bool isPointInShape(Point P, Point* V, int n);
virtual bool isPointOnShape(Point A, Point B, Point C, int slope, int intercept, int left, int top, int right, int bottom, int dx, int dy);
void setName(string shapename);
void setContainsWarpSpace(bool containsWS);
private:
string name;
bool containsWarpSpace;
};
class Cross : public ShapeTwoD {
public:
Cross(string shapename = "Cross", bool containsWS, int vertices = 12, Point ordinates[]):ShapeTwoD(shapename, containsWS){}
int getVert();
void setVert(int vertices);
Point getOrd();
void setOrd(Point ordinates[]);
virtual double computeArea(Point A[], int vertices);
private:
int vert;
Point ord[];
};
class Rectangle : public ShapeTwoD {
public:
Rectangle(string shapename = "Rectangle", bool containsWS, int vertices = 4, Point ordinates[]):ShapeTwoD(shapename, containsWS){}
int getVert();
void setVert(int vertices);
Point getOrd();
void setOrd(Point ordinates[]);
virtual double computeArea(Point A, Point B);
private:
int vert;
Point ord[];
};
class Square : public ShapeTwoD {
public:
Square(string shapename = "Square", bool containsWS, int vertices = 4, Point ordinates[]):ShapeTwoD(shapename, containsWS){}
int getVert();
void setVert(int vertices);
Point getOrd();
void setOrd(Point ordinates[]);
virtual double computeArea(Point A, Point B);
private:
int vert;
Point ord[];
};
#endif /* SHAPETWOD_H */
/*
* File: ShapeTwoD.cpp
* Author: Administrator
*
* Created on October 30, 2012, 12:05 AM
*/
#include "ShapeTwoD.h"
#include <sstream>
ShapeTwoD::ShapeTwoD(string shapename, bool containsWS) {
name = shapename;
containsWarpSpace = containsWS;
}
string ShapeTwoD::getName() {
return name;
}
void ShapeTwoD::setName(string shapename) {
name = shapename;
};
bool ShapeTwoD::getContainsWarpSpace() {
return containsWarpSpace;
}
void ShapeTwoD::setContainsWarpSpace(bool containsWS) {
containsWarpSpace = containsWS;
}
string cvtBool(bool b) {
stringstream ss;
ss << b;
return ss.str();
}
string ShapeTwoD::toString() {
return "Name:\t" + name + "\nSpecial Type:\t" + cvtBool(containsWarpSpace) + "\n";
}
// Formulas gotten from http://www.mathopenref.com/coordpolygonarea.html
// http://softsurfer.com/Archive/algorithm_0103/algorithm_0103.htm
int pointsInShape;
int pointsOnShape;
double ShapeTwoD::computeArea() {
// Based on Pick's Thorem
double area = pointsInShape + (pointsOnShape / 2) - 1;
return area;
}
float isLeft(Point P0, Point P1, Point P2) {
return ((P1.x - P0.x) * (P2.y - P0.y) - (P2.x - P0.x) * (P1.y - P0.y));
}
bool ShapeTwoD::isPointInShape(Point P, Point* V, int n) {
// Input: P = a point,
// V[] = vertex points of a polygon V[n+1] with V[n]=V[0]
int wn = 0; // the winding number counter
// loop through all edges of the polygon
for (int i = 0; i < n; i++) { // edge from V[i] to V[i+1]
if (V[i].y <= P.y) { // start y <= P.y
if (V[i + 1].y > P.y) // an upward crossing
if (isLeft(V[i], V[i + 1], P) > 0) // P left of edge
++wn; // have a valid up intersect
} else { // start y > P.y (no test needed)
if (V[i + 1].y <= P.y) // a downward crossing
if (isLeft(V[i], V[i + 1], P) < 0) // P right of edge
--wn; // have a valid down intersect
}
}
pointsInShape += wn;
return true;
}
bool ShapeTwoD::isPointOnShape(Point A, Point B, Point C, int slope, int intercept, int left, int top, int right, int bottom, int dx, int dy) {
// Linear equation
dx = B.x - A.x;
dy = B.y - A.y;
slope = dy / dx;
intercept = y1 - slope * A.x;
if (A.x < B.x) {
left = A.x;
right = B.x;
} else {
left = B.x;
right = A.x;
}
if (A.y < B.y) {
top = A.y;
bottom = B.y;
} else {
top = B.y;
bottom = A.y;
}
if (slope * C.x + intercept > (C.y - 0.01) && slope * C.x + intercept < (C.y + 0.01)) {
if (C.x >= left && C.x <= right && C.y >= top && C.y <= bottom) {
pointsOnShape++;
return true;
}
}
}
Cross::Cross(string shapename, bool containsWS, int vertices = 12, Point ordinates[]):ShapeTwoD(shapename, containsWS) {
vert = vertices;
ord[] = ordinates[];
}
int Cross::getVert() {
return vert;
}
void Cross::setVert(int vertices) {
vert = vertices;
}
Point Cross::getOrd() {
return ord[];
}
void Cross::setOrd(Point ordinates[]) {
ord[] = ordinates[];
}
double Cross::computeArea(Point A[], int vertices) {
/* If you know the coordinates of the vertices of a polygon, this algorithm can be used to find the area.
* Parameters
* X, Y Arrays of the x and y coordinates of the vertices, traced in a clockwise direction, starting at any vertex. If you trace them counterclockwise, the result will be correct but have a negative sign.
* numPoints The number of vertices
* Returns the area of the polygon
*/
double area = 0;
int j = vertices - 1; // The last vertex is the 'previous' one to the first
for (int i = 0; i < vertices; i++) {
area = (area + (A[j].x + A[i].x) * (A[j].y - A[i].y))/2;
j = i;
}
return area;
}
Rectangle::Rectangle(string shapename, bool containsWS, int vertices = 4, Point ordinates[]):ShapeTwoD(shapename, containsWS) {
vert = vertices;
ord[] = ordinates[];
}
int Rectangle::getVert() {
return vert;
}
void Rectangle::setVert(int vertices) {
vert = vertices;
}
void Rectangle::getOrd() {
return ord[];
}
void Rectangle::setOrd(Point ordinates[]) {
ord[] = ordinates[];
}
double Rectangle::computeArea(Point A, Point B, Point C) {
double length = sqrt(pow((A.x - B.x), 2) + pow((A.y - B.y), 2));
double width = sqrt(pow((B.x - C.x), 2) + pow((B.y - C.y), 2));
double area = length * width;
return area;
}
Square::Square(string shapename, bool containsWS, int vertices, Point ordinates[]):ShapeTwoD(shapename, containsWS) {
vert = vertices;
ord[] = ordinates[];
}
int Square::getVert() {
return vert;
}
void Square::setVert(int vertices) {
vert = vertices;
}
void Square::getOrd() {
return ord[];
}
void Square::setOrd(Point ordinates[]) {
ord[] = ordinates[];
}
double Square::computeArea(Point A, Point B) {
double length = sqrt(pow((A.x - B.x), 2) + pow((A.y - B.y), 2));
double area = pow(length, 2);
return area;
}
/*
* File: Assn2.cpp
* Author: Administrator
*
* Created on October 29, 2012, 11:58 PM
*/
#include "ShapeTwoD.h"
#include <iostream>
#include <math.h>
#include <string>
#include <vector>
using namespace std;
// Global declarations
void menu(), option1(), option2(), option3(), option4();
int choice, vert;
string shape, special;
double area;
bool containsWS;
vector<ShapeTwoD> stdv;
int main() {
cout << "Welcome to Assn2 program!\n\n";
// When user enters 5 as input, the program quits
while (choice != 5) {
menu();
/* switch evaluates expression and checks if it is equivalent to constant1,
* if it is, it executes group of statements 1 until it finds the break statement.
* When it finds this break statement the program jumps to the end of the switch selective structure.
* If expression was not equal to constant1 it will be checked against constant2.
* If it is equal to this, it will execute group of statements 2 until a break keyword is found,
* and then will jump to the end of the switch selective structure.
*/
switch (choice) {
case 1:
option1();
break;
case 2:
option2();
break;
case 3:
option3();
break;
case 4:
option4();
break;
}
}
}
void menu() {
cout << "1) Input sensor data\n";
cout << "2) Compute area (for all records)\n";
cout << "3) Print shapes report\n";
cout << "4) Sort shape data\n";
cout << "5) Quit\n\n";
cout << "Please enter your choice: ";
cin >> choice;
cout << "\n";
}
void option1() {
cout << "[ Input sensor data ]\n";
cout << "Please enter name of Shape (Cross, Rectangle or Square): ";
cin >> shape;
cout << "Please enter Special type (NS or WS): ";
cin >> special;
if (special == "WS") {
containsWS = true;
}
else {
containsWS = false;
}
if (shape == "Cross") {
vert = 12;
for (int v = 0; v < vert; v++) {
Point ordinates[v];
cout << "Please enter x-ordinate of pt. " << (v+1) << ":";
cin >> ordinates[v].x;
cout << "Please enter y-ordinate of pt. " << (v+1) << ":";
cin >> ordinates[v].y;
Cross cross(shape, containsWS, vert, ordinates[v]);
stdv.push_back(cross);
}
}
if (shape == "Rectangle") {
vert = 4;
for (int v = 0; v < vert; v++) {
Point ordinates[v];
cout << "Please enter x-ordinate of pt. " << (v+1) << ":";
cin >> ordinates[v].x;
cout << "Please enter y-ordinate of pt. " << (v+1) << ":";
cin >> ordinates[v].y;
Rectangle rectangle(shape, containsWS, vert, ordinates[v]);
stdv.push_back(rectangle);
}
}
else {
shape = "Square";
vert = 4;
for (int v = 0; v < vert; v++) {
Point ordinates[v];
cout << "Please enter x-ordinate of pt. " << (v+1) << ":";
cin >> ordinates[v].x;
cout << "Please enter y-ordinate of pt. " << (v+1) << ":";
cin >> ordinates[v].y;
Square square(shape, containsWS, vert, ordinates[v]);
stdv.push_back(square);
}
}
cout << "Record successfully stored. Going back to main menu";
}
void option2() {
if (stdv.size() != 0) {
for (int count = 0; count < stdv.size(); count++) {
area = stdv.at(count).computeArea();
//Debugging purpose
cout << (count+1) << ")" << stdv.at(count).getName() << "\t" << area;
}
cout << "Computation completed! (" << stdv.size() << " records were updated)\n\n";
}
}
在这里,我试图将 struct Point 的数组插入到我的类构造函数(Cross、Rectangle、Square)中。但它给我带来了一些我并没有真正理解的错误。
- Assn2.cpp:113: 错误: 没有匹配函数调用'Cross::Cross(std::string&, bool&, int&, Point&)'
- ShapeTwoD.h:41:注意:候选者是:Cross::Cross(const Cross&)
- ShapeTwoD.h:43: 注意: Cross::Cross(std::string, bool, int, Point*)
- Assn2.cpp:136: 错误: 没有匹配函数调用 `Rectangle::Rectangle(std::string&, bool&, int&, Point&)
- ShapeTwoD.h:56:注意:候选者是:Rectangle::Rectangle(const
Rectangle&) - ShapeTwoD.h:58: 注意: Rectangle::Rectangle(std::string, bool, int, Point*)