0
/* 
 * 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*)
4

1 回答 1

0

您的函数声明甚至不会编译,具有默认值的参数不能在没有默认值的参数的前面:

Cross(string shapename = "Cross", bool containsWS, int vertices = 12, Point ordinates[])
Rectangle(string shapename = "Rectangle", bool containsWS, int vertices = 4, Point ordinates[]):ShapeTwoD(shapename, containsWS){}
Square(string shapename = "Square", bool containsWS, int vertices = 4, Point ordinates[]):ShapeTwoD(shapename, containsWS){}

您可以使所有参数都具有所有默认值或更改顺序,例如下面是有效的函数声明:

 Cross(bool containsWS, Point ordinates[], string shapename = "Cross", int vertices = 12)
于 2012-11-04T01:40:29.400 回答