0

I'm newbie with C++. I'm using netbeans IDE. I have created class Point (Point.h and Point.cpp) and another c++ file geo.cpp where I have put the methods to use after. I have also created a header file where I geo.h where I have put the declaration of the methods implemented in geo.cpp. My code is the following:

Point.h

#include <math.h>
#include <iostream>
using namespace std;

#ifndef POINT_H
#define POINT_H

class Point {
protected:
    double x;
    double y;
    double z;
    // color RGB
    double r;
    double g;
    double b;
public:
    // Constructors
    Point();
    //  Point(const Point& orig);
    Point(ostream &strm);
    Point(double x, double y, double z);
    Point(double *tab);
    Point(const Point& orig);
    virtual ~Point();

    //getters

    double getX() const {
        return this->x;
    }

    double getY() const {
        return this->y;
    }

    double getZ() const {
        return this->z;
    }

    double getR() const {
        return this->r;
    }

    double getG() const {
        return this->g;
    }

    double getB() const {
        return this->b;
    }

    //setters

    void setX(double x) {
        this->x = x;
    }

    void setY(double y) {
        this->y = y;
    }

    void setZ(double z) {
        this->z = z;
    }

    void setR(double r) {
        this->r = r;
    }

    void setG(double g) {
        this->g = g;
    }

    void setB(double b) {
        this->b = b;
    }

    void setColor(double r, double g, double b) {
        this->r = r;
        this->g = g;
        this->b = b;
    }

    /**
     * Print the point
     * @param strm
     */
    void print(ostream &strm);

    //Other methods

    double dist2D(Point &other);

    double dist3D(Point &other);

    Point swap(Point p);

    Point operator-(const Point &other) const;

};

#endif  /* POINT_H */

Point.cpp

#include <iostream>
#include <math.h>
#include <ostream>
using namespace std;

#include "Point.h"

Point::Point(const Point& orig) {
}

Point::Point(ostream &strm) {
    strm << "Type the abscissa: ", cin >> this->x;
    strm << "Type the ordinate: ", cin >> this->y;
    strm << "Type the applicate: ", cin >> this->z;
}

Point::Point(double x, double y, double z) : x(x), y(y), z(z) {
    // The default point color is blue
    this->r = 0;
    this->g = 0;
    this->b = 255;
}

Point::Point(double *tab) : x(tab[0]), y(tab[1]), z(tab[2]) {
    // The default point color is blue
    r = 0;
    g = 0;
    b = 255;
}

Point::~Point() {

}

//Other methods

double Point::dist2D(Point &other) {
    double xd = x - other.x;
    double yd = y - other.y;
    return sqrt(xd * xd + yd * yd);
}

double Point::dist3D(Point &other) {
    double xd = x - other.x;
    double yd = y - other.y;
    double zd = z - other.z;
    return sqrt(xd * xd + yd * yd + zd * zd);
}

Point Point::swap(Point p) {
    Point aux(x, y, z);
    x = p.x;
    y = p.y;
    z = p.z;
    return aux;
}

Point Point::operator-(const Point &other) const {
    return Point(other.getX() - this->x, other.getY() - this->y, other.getZ() - this->z);
}

void Point::print(ostream &strm) {
    strm << "Point(" << this->x << "," << y << "," << z << ")\n";
}

geo.h

#include <vector>
#include <stack>

using namespace std;
#include "Point.h"

#ifndef GEO_H
#define GEO_H

double myRand(double min, double max);

void PCEngine(char *theFileName, int pointsNBR);

void getFarthestPoints(vector<Point> v, Point &p1, Point &p2);

vector<Point> getCloudPoint(char *fileName);

void loadPointCloud(char *fileName, Point p[]);

int getLineNbr(char *fileName);

double myRand(double min, double max);

Point nextToTop(stack<Point> &S);

int orientation(Point p, Point q, Point r);

int compare(const void *vp1, const void *vp2);

vector<Point> convexHull(Point Points[], int n);

#endif  /* GEO_H */

geo.cpp

#include <cstdlib>
#include <string>
#include <vector>
#include <stack>
#include <fstream>
#include <sstream>

using namespace std;

#include "geo.h"
#include "Point.h"

Point p0 = NULL;

double myRand(double min, double max) {
    return (double) (min + ((float) rand() / RAND_MAX * (max - min + 1.0)));
}

int getLineNbr(char *fileName) {
    string line;
    int nbr = 0;
    ifstream file(fileName);
    if (file.is_open()) {
        while (getline(file, line)) {
            ++nbr;
        }
        file.close();
    } else {
        cout << "Unable to open " << fileName << '\n';
        exit(0);
    }
    return 0;
}

void loadPointCloud(char *fileName, Point Points[]) {
    string line;
    string token;
    double tab[3];
    ifstream file(fileName);
    if (file.is_open()) {
        int lineNbr = -1;
        while (getline(file, line)) {
            ++lineNbr;
            int cpt = 0;
            stringstream stream(line);
            while (getline(stream, token, ',')) {
                tab[cpt] = ::atof(token.c_str());
                ++cpt;
            }
            Point p(tab[0], tab[1], tab[2]);
            p.setColor(myRand(0, 255), myRand(0, 255), myRand(0, 255));
            Points[lineNbr] = p;
        }
        file.close();
    } else {
        cout << "Unable to open " << fileName << '\n';
        exit(0);
    }
}

vector<Point> getCloudPoint(char *fileName) {
    string line;
    string token;
    vector<Point> v;
    double tab[3];
//    double x;
//    double y;
//    double z;
    ifstream file(fileName);
    if (file.is_open()) {
        while (getline(file, line)) {
            int cpt = 0;
            stringstream stream(line);
            while (getline(stream, token, ',')) {
                tab[cpt] = ::atof(token.c_str());
                cpt++;
            }
            Point p(tab[0], tab[1], tab[2]);
            p.setColor(myRand(0, 255), myRand(0, 255), myRand(0, 255));
            v.push_back(p);
        }
        file.close();
    } else {
        cout << "Unable to open " << fileName << '\n';
        exit(0);
    }

    return v;
}

/**
 * This is an Engine to generate the points
 *  and to save their in the "file".csv
 * 
 * @param theFileName
 * @param pointsNBR points number
 */
void PCEngine(char *theFileName, int pointsNBR) {
        cout << "PCEngine : Ok!\n";
    ofstream file(theFileName);
    if (file.is_open()) {
        cout << "Ok!\n";
        for (int i = 0; i < pointsNBR; i++) {
            file << myRand(-1, 1) << "," << myRand(-1, 1) << "," << myRand(-1, 1) << "\n";
        }
        file.close();
    } else {
        cout << "Unable to open file\n";
    }
}

void getFarthestPoints(vector<Point> v, Point &p1, Point &p2) {
    if (v.size() < 2) {
        cout << "The number of points is very small.\n";
        exit(0);
    } else {
        int indexP1 = -1;
        int indexP2 = -1;
        double maxDist = 0;
        double dist = 0;
        for (int i = 0; i < v.size() - 1; ++i) {
            for (int j = i + 1; j < v.size(); ++j) {
                dist = v[i].dist3D(v[j]);
                if (maxDist < dist) {
                    maxDist = dist;
                    indexP1 = i;
                    indexP2 = j;
                }
            }
        }
        p1 = v[indexP1];
        p1.print(cout);
        p2 = v[indexP2];
        p2.print(cout);
    }
}

/** An utility function to find next to top in a stack */
Point nextToTop(stack<Point> &S) {
    Point p = S.top();
    S.pop();
    Point res = S.top();
    S.push(p);
    return res;
}

int orientation(Point p, Point q, Point r) {
    int val = (q.getY() - p.getY()) * (r.getX() - q.getX()) -
            (q.getX() - p.getX()) * (r.getY() - q.getY());

    if (val == 0) return 0;
    // colinear
    return (val > 0) ? 1 : 2; // clock or counterclock wise
}

// A function used by library function qsort() to sort an array of
// Points with respect to the first Point

int compare(const void *vp1, const void *vp2) {
    Point *p1 = (Point *) vp1;
    Point *p2 = (Point *) vp2;

    // Find orientation
    int o = orientation(p0, *p1, *p2);
    if (o == 0) {
        //the distance square between p0 and p1
        double distSquare1 = p0.dist2D(*p1) * p0.dist2D(*p1);
        //the distance square between p0 and p2
        double distSquare2 = p0.dist2D(*p2) * p0.dist2D(*p2);
        return (distSquare2 >= distSquare1) ? -1 : 1;
    }

    return (o == 2) ? -1 : 1;
}

vector<Point> convexHull(Point Points[], int n) {
    vector<Point> v;
    // Find the bottommost Point
    int ymin = Points[0].getY();
    int min = 0;
    for (int i = 1; i < n; i++) {
        int y = Points[i].getY();

        // Pick the bottom-most or chose the left most Point in case of tie
        if ((y < ymin) || (ymin == y && Points[i].getX() < Points[min].getX()))
            ymin = Points[i].getY(), min = i;

    }
    // Place the bottom-most Point at first position
    Points[min] = Points[0].swap(Points[min]);

    // Sort n-1 Points with respect to the first Point. A Point p1 comes
    // before p2 in sorted ouput if p2 has larger polar angle (in 
    // counterclockwise direction) than p1
    p0 = Points[0];
    qsort(&Points[1], n - 1, sizeof (Point), compare);

    // Create an empty stack and push first three Points to it.
    stack<Point> S;
    S.push(Points[0]);
    S.push(Points[1]);
    S.push(Points[2]);

    // Process remaining n-3 Points
    for (int i = 3; i < n; i++) {
        // Keep removing top while the angle formed by Points next-to-top, 
        // top, and Points[i] makes a non-left turn
        while (orientation(nextToTop(S), S.top(), Points[i]) != 2)
            S.pop();
        S.push(Points[i]);

    }

    // Now stack has the output Points, print contents of stack
    while (!S.empty()) {
        Point p = S.top();
        cout << "(" << p.getX() << ", " << p.getY() << ")" << endl;
        v.push_back(Point(p.getX(), p.getY(), 0));
        S.pop();
    }
    return v;
}

main.cpp

#include <cstdlib>
#include <iostream>
#include <string>

using namespace std;

#include "Point.h"
#include "geo.cpp"

int main(int argc, char** argv) {
    cout << "main\n";
    char *theFileName = "file.csv";
    PCEngine(theFileName, 100);
    return 0;
}

When I run the project I have found the following error:

main.cpp: In function ‘int main(int, char**)’:
main.cpp:20:29: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]
mkdir -p dist/Debug/GNU-Linux-x86
g++     -o dist/Debug/GNU-Linux-x86/dgilog build/Debug/GNU-Linux-x86/Plan.o build/Debug/GNU-Linux-x86/Point.o build/Debug/GNU-Linux-x86/Straight.o build/Debug/GNU-Linux-x86/Vect.o build/Debug/GNU-Linux-x86/geo.o build/Debug/GNU-Linux-x86/main.o 
/usr/bin/ld: error: build/Debug/GNU-Linux-x86/main.o: multiple definition of 'p0'
/usr/bin/ld: build/Debug/GNU-Linux-x86/geo.o: previous definition here
/usr/bin/ld: error: build/Debug/GNU-Linux-x86/main.o: multiple definition of 'myRand(double, double)'
/usr/bin/ld: build/Debug/GNU-Linux-x86/geo.o: previous definition here
/usr/bin/ld: error: build/Debug/GNU-Linux-x86/main.o: multiple definition of 'getLineNbr(char*)'
/usr/bin/ld: build/Debug/GNU-Linux-x86/geo.o: previous definition here
/usr/bin/ld: error: build/Debug/GNU-Linux-x86/main.o: multiple definition of 'loadPointCloud(char*, Point*)'
/usr/bin/ld: build/Debug/GNU-Linux-x86/geo.o: previous definition here
/usr/bin/ld: error: build/Debug/GNU-Linux-x86/main.o: multiple definition of 'getCloudPoint(char*)'
/usr/bin/ld: build/Debug/GNU-Linux-x86/geo.o: previous definition here
/usr/bin/ld: error: build/Debug/GNU-Linux-x86/main.o: multiple definition of 'PCEngine(char*, int)'
/usr/bin/ld: build/Debug/GNU-Linux-x86/geo.o: previous definition here
/usr/bin/ld: error: build/Debug/GNU-Linux-x86/main.o: multiple definition of 'getFarthestPoints(std::vector<Point, std::allocator<Point> >, Point&, Point&)'
/usr/bin/ld: build/Debug/GNU-Linux-x86/geo.o: previous definition here
/usr/bin/ld: error: build/Debug/GNU-Linux-x86/main.o: multiple definition of 'nextToTop(std::stack<Point, std::deque<Point, std::allocator<Point> > >&)'
/usr/bin/ld: build/Debug/GNU-Linux-x86/geo.o: previous definition here
/usr/bin/ld: error: build/Debug/GNU-Linux-x86/main.o: multiple definition of 'orientation(Point, Point, Point)'
/usr/bin/ld: build/Debug/GNU-Linux-x86/geo.o: previous definition here
/usr/bin/ld: error: build/Debug/GNU-Linux-x86/main.o: multiple definition of 'compare(void const*, void const*)'
/usr/bin/ld: build/Debug/GNU-Linux-x86/geo.o: previous definition here
/usr/bin/ld: error: build/Debug/GNU-Linux-x86/main.o: multiple definition of 'convexHull(Point*, int)'
/usr/bin/ld: build/Debug/GNU-Linux-x86/geo.o: previous definition here
collect2: ld returned 1 exit status
make[2]: *** [dist/Debug/GNU-Linux-x86/dgilog] Error 1
make[2]: Leaving directory `/home/abouabdillehmsk/NetBeansProjects/DGILOG'
make[1]: *** [.build-conf] Error 2
make[1]: Leaving directory `/home/abouabdillehmsk/NetBeansProjects/DGILOG'
make: *** [.build-impl] Error 2

I have replace the include

#include "geo.cpp"

by #include "geo.h"

The compiler didn't give me any error, but when I check my output file file.csv, it's still empty.

Knowing that all is well before creating the files: geo.h and geo.cpp

Thanks in advance.

5
  • Stick with the line you were using before (g++ -o dist/Debug/GNU-Linux-x86/dgilog build/Debug/GNU-Linux-x86/Plan.o build/Debug/GNU-Linux-x86/Point.o ...) . If you only include some of your files then obviously you will have undefined references. Commented Mar 14, 2014 at 8:23
  • 1
    To fix the "deprecated conversion" warning, in the line char *theFileName = "file.csv";, change it to char theFilename[] = ...; Commented Mar 14, 2014 at 8:24
  • 1
    When I remove using namespace std I have found this error geo.h:21:24: error: ‘vector’ was not declared in this scope. Is it mandatory to add std:: to each vector declaration like this: std::vector? @MattMcNabb Commented Mar 14, 2014 at 8:34
  • 1
    @Dinosaur Yes. If you're using a STL type and you don't have using namespace std; in your code, you'll need to put std:: at the start of that type. For example, std::map, std::vector, std::string, std::cout, std::endl. Commented Mar 14, 2014 at 8:45
  • Yes I corrected It. But there is the same problem. I haven't any error in compilation, but when running project the output file file.csv is still empty : (. Commented Mar 14, 2014 at 8:49

2 Answers 2

3
  1. In main.cpp you included a .cpp file instead of the header file. Never include an implementation file.
  2. Never use using namespace in a header file. Prefer namespace { } if you want to use a namespace.
  3. The multiple inclusion protection have to be done before any includes.
#ifndef POINT_H
#define POINT_H

#include <math.h>
#include <iostream>

//code 

#endif
Sign up to request clarification or add additional context in comments.

2 Comments

When I remove using namespace std I have found this error geo.h:21:24: error: ‘vector’ was not declared in this scope. Is it mandatory to add std:: to each vector declaration like this: std::vector?
Yes, you have to adapt it by adding std:: in front of the class or functions which are part of the std namespace
1

Please remove intermediate errors that you have already solved.

You need to include geo.cpp in your compile command:

g++ main.cpp geo.cpp -o main.out

Tips for c++ improvements:

  • Never use "using ..." in header files.
  • Have the include guards at the very top of the header files.

6 Comments

... and remove #include "geo.cpp" from the source of main.cpp
Yes I did. But there is the same problem. I haven't any error in compilation, but when running project the output file file.csv is still empty : (.
@WhozCraig The compilation has success but I have found this error Segmentation fault (core dumped)
@Dinosaur unrelated issue. That means you're code is broken, but at least now it links. Now you get to debug =P
@Dinosaur I'd start by ensuring your comparator for your quicksort establishes a real strict weak ordering, because I can see right now it doesn't. Second, you have multiple places in where you implicitly convert double to int, which just seems wrong, but hey its not my code. Best of luck.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.