13 Replies - 763 Views - Last Post: 06 September 2013 - 07:08 AM Rate Topic: -----

#1 xnewix  Icon User is offline

  • D.I.C Head
  • member icon

Reputation: 2
  • View blog
  • Posts: 204
  • Joined: 23-May 09

STL vectors and lists. unable to store class objects correctly

Posted 01 September 2013 - 05:22 AM

okay my problem is that something like this...

	        temppoint = new Point3d;	
		temppoint->setPoint(x,y,z);
		point3d.push_back(*temppoint);		
		delete temppoint;


...works correctly at line 114. (the output can be viewed by uncommiting the section of code at line 147.)
however a similar use of this doesn't work in the function at line 79, specificly at line 102. The function is called at line 135.

Unfortunatly, for me, the code doesn't output any data as the vector has a .size() of 0.

What I am trying to do is subdivide an iscohedron so it becomes more spherical looking. N.B the terminolagly of normals is wrong here, rather i was hoping to split each tiangle into four then copy the new vertices from the function to the point3d list.

here is the code.

#include <iostream>
#include <fstream>
#include <cmath>
#include <string.h>
#include <vector>
#include <list>

#define M_PI 3.14159265359

class Point3d {
private:
	double x,y,z;
public:
	void setPoint(double nx, double ny, double nz) {
		x=nx;
		y=ny;
		z=nz;
	}
	double getx() { return x; }
	double gety() { return y; }
	double getz() { return z; }
};
class Triangle3d {
private:
	int v1,v2,v3;
public:
	void setVertices(int nv1, int nv2, int nv3) {
		v1=nv1;
		v2=nv2;
		v3=nv3;
	}
	int getv1() { return v1; }
	int getv2() { return v2; }
	int getv3() { return v3; }
};

class Sphere3d {
private:
public:
	std::list<Point3d> point3d;
	Point3d *temppoint;

	std::list<Point3d> newtemppoint3d;
	Point3d *newtemppoint;
	Point3d *tempnormals;

	std::vector<Triangle3d> triangle3d;
	Triangle3d *temptriangle;	

	//
	Point3d *retpoint3d;
	Triangle3d *tempMidpoint; // not used yet??

	void addPoint(double x,double y, double z) {
		temppoint = new Point3d;	
		temppoint->setPoint(x,y,z);
		point3d.push_back(*temppoint);		
		delete temppoint;
	}    
	void getPoint(int index, std::list<Point3d> newpoint3d) {
		retpoint3d = new Point3d;
		std::list<Point3d>::iterator it = newpoint3d.begin();
		std::advance(it, index);
		
		retpoint3d->setPoint(it->getx(),it->gety(),it->getz());		
	}	
	
	void addTriangle(int xindex,int yindex, int zindex) {
		temptriangle = new Triangle3d;	
		temptriangle->setVertices(xindex,yindex,zindex);
		triangle3d.push_back(*temptriangle);		
		delete temptriangle;
	}    
	void getTriangleVertexRefs(int index) {
		std::cout << triangle3d[index].getv1() << ",";
		std::cout << triangle3d[index].getv2() << ",";
		std::cout << triangle3d[index].getv3() << std::endl;
	}
	void normalizePoint(int index, std::list<Point3d> newpoint3d, std::vector<Point3d> tempnormals_point3d) {
		// this formular is incorrect for its implementation.
		
		getPoint(index,newpoint3d); double v1 = retpoint3d->getx(); 
		getPoint(index,newpoint3d); double v2 = retpoint3d->gety(); 
		getPoint(index,newpoint3d); double v3 = retpoint3d->getz(); 

		double d  = sqrt((v1*v1)+(v2*v2)+(v3*v3));
		v1 /=d;
		v2 /=d;
		v3 /=d;

		// variables are set as intended.
		std::cout << "v1" << v1 << "v2" << v2 << "v3" << v3 << std::endl;

		/*
		Point3d *tempnormals = new Point3d;
		tempnormals->setPoint(v1,v2,v3);	
		tempnormals_point3d.push_back(*tempnormals); 
		//delete tempnormals;
        */

		// this doesn't seam to work, dispite simillar methods at void addPoint(x,y,z);
        tempnormals = new Point3d;
        tempnormals->setPoint(v1,v2,v3);
        tempnormals_point3d.push_back(*tempnormals); 

	}
};

void sphere() {
	Sphere3d sphere3d;

	double r= (1.0+sqrt(5.0))/2.0;

	sphere3d.addPoint(-1.0, r,0.0);
	sphere3d.addPoint( 1.0, r,0.0);
	sphere3d.addPoint(-1.0,-r,0.0);
	sphere3d.addPoint( 1.0,-r,0.0);
    
	sphere3d.addPoint(0.0,-1.0, r);
	sphere3d.addPoint(0.0, 1.0, r);
	sphere3d.addPoint(0.0,-1.0,-r);
	sphere3d.addPoint(0.0, 1.0,-r);

	sphere3d.addPoint( r,0.0,-1.0);
	sphere3d.addPoint( r,0.0, 1.0);
	sphere3d.addPoint(-r,0.0,-1.0);
	sphere3d.addPoint(-r,0.0, 1.0);

	// all vectors <Point3d> should be std::lists
	std::vector<Point3d> normalpoints; // std::list
	std::cout << sphere3d.point3d.size();

	for(int i=0; i<sphere3d.point3d.size(); i++) {
		std::cout << i << ", ";
		sphere3d.normalizePoint(i,sphere3d.point3d,normalpoints);
	}

	// Outputs as 0.
	std::cout << "normal size: " << normalpoints.size();

	// display coordinates, does not seam to work as normalpoints.size() is 0.
	std::vector<Point3d>::iterator it_norm; // std::list
	for(it_norm=normalpoints.begin(); it_norm!=normalpoints.end(); it_norm++) {
		std::cout << it_norm->getx() << "..." << it_norm->gety() << "..." << it_norm->getz() << std::endl;
	}

        /*
	std::list<Point3d>::iterator it;
	for(it=sphere3d.point3d.begin(); it!=sphere3d.point3d.end(); it++) {
		std::cout << it->getx() << " " << it->gety() << " " << it->getz() << std::endl;
	}
	*/

}
int num;

int main () {
	sphere();
	std::cin >> num;
};

This post has been edited by xnewix: 01 September 2013 - 05:27 AM


Is This A Good Question/Topic? 0
  • +

Replies To: STL vectors and lists. unable to store class objects correctly

#2 CTphpnwb  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 2927
  • View blog
  • Posts: 10,114
  • Joined: 08-August 08

Re: STL vectors and lists. unable to store class objects correctly

Posted 01 September 2013 - 07:31 AM

Point3d is not a vector, so why do you think you can push_back to it?
Was This Post Helpful? 0
  • +
  • -

#3 xnewix  Icon User is offline

  • D.I.C Head
  • member icon

Reputation: 2
  • View blog
  • Posts: 204
  • Joined: 23-May 09

Re: STL vectors and lists. unable to store class objects correctly

Posted 01 September 2013 - 07:37 AM

View PostCTphpnwb, on 01 September 2013 - 08:31 AM, said:

Point3d is not a vector, so why do you think you can push_back to it?


Point3d is a class yes, but point3d is a list , see line 40
std::list<Point3d> point3d;
unless i'm mistaking what your trying to say here?

Sorry if my naming conventions have caused confusion?
Was This Post Helpful? 0
  • +
  • -

#4 baavgai  Icon User is offline

  • Dreaming Coder
  • member icon

Reputation: 5800
  • View blog
  • Posts: 12,635
  • Joined: 16-October 07

Re: STL vectors and lists. unable to store class objects correctly

Posted 01 September 2013 - 07:46 AM

That's kind of nasty.
void addPoint(double x,double y, double z) {
	temppoint = new Point3d;	
	temppoint->setPoint(x,y,z);
	point3d.push_back(*temppoint);		
	delete temppoint;
}    



Also, why doesn't Point3d have a constructor? Indeed, why doesn't anything have a constructor? An object without a constructor should be a red flag.

Instead:
class Point3d {
private:
	double x,y,z;
public:
	Point3d(double nx, double ny, double nz)  : x(nx), y(ny), z(nz) { }
	double getx() { return x; }
	double gety() { return y; }
	double getz() { return z; }
};
// ...
void addPoint(double x,double y, double z) {
	point3d.push_back(Point3d(x,y,z));
}



Now:
std::cout << "normal size: " << normalpoints.size();



Show where you actually add data to this vector.
Was This Post Helpful? 3
  • +
  • -

#5 xnewix  Icon User is offline

  • D.I.C Head
  • member icon

Reputation: 2
  • View blog
  • Posts: 204
  • Joined: 23-May 09

Re: STL vectors and lists. unable to store class objects correctly

Posted 01 September 2013 - 08:51 AM

Quote

That's kind of nasty.


Okay, granted. Had a quick fiddle with things given the above, the function below addPoint : ln 60 would look something like this...

	void getPoint(int index, std::list<Point3d> newpoint3d) {
		std::list<Point3d>::iterator it = newpoint3d.begin();
		std::advance(it, index);		
		retpoint3d = Point3d(it->getx(),it->gety(),it->getz());		
	}

... and you suggest a simillar thing for the Triangle3d class. Right?

Quote

Show where you actually add data to this vector.


The data should be added at ln 135, the function normalizePoint is at ln 79.

129	    // all vectors <Point3d> should be std::lists
130	    std::vector<Point3d> normalpoints; // std::list
131	    std::cout << sphere3d.point3d.size();
132	 
133	    for(int i=0; i<sphere3d.point3d.size(); i++) {
134	        std::cout << i << ", ";
135 ->>>>>      sphere3d.normalizePoint(i,sphere3d.point3d,normalpoints);
136	    }


inside normalizePoint at ln 104 is where i attempted to push_back to the vector. the vector im adding to is outside the class at ln 130

101	        // this doesn't seam to work, dispite simillar methods at void addPoint(x,y,z);
102	        tempnormals = new Point3d;
103	        tempnormals->setPoint(v1,v2,v3);
104	        tempnormals_point3d.push_back(*tempnormals); 

This post has been edited by xnewix: 01 September 2013 - 08:52 AM

Was This Post Helpful? 0
  • +
  • -

#6 vividexstance  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 656
  • Posts: 2,246
  • Joined: 31-December 10

Re: STL vectors and lists. unable to store class objects correctly

Posted 01 September 2013 - 10:23 AM

It doesn't seem like you need to dynamically allocate the class objects, unless you're attempting to use polymorphism. If you're not trying to use that, why not let the computer handle the lifetime of the objects for you?
Was This Post Helpful? 0
  • +
  • -

#7 baavgai  Icon User is offline

  • Dreaming Coder
  • member icon

Reputation: 5800
  • View blog
  • Posts: 12,635
  • Joined: 16-October 07

Re: STL vectors and lists. unable to store class objects correctly

Posted 01 September 2013 - 11:27 AM

Consider:
#include <iostream>
#include <vector>

void add1(std::vector<int> v, int value) {
	std::cout << "add1(" << value << ')' << std::endl;
	v.push_back(value);
}

void add2(std::vector<int> &v, int value) {
	std::cout << "add2(" << value << ')' << std::endl;
	v.push_back(value);
}

int main () {
	std::vector<int> v;
	for(int i=0; i<6; i++) { 
		if (i%2) { add1(v, i); } else { add2(v, i); }
	}
	for(std::vector<int>::const_iterator it = v.begin(); it != v.end(); ++it) {
		std::cout << *it << ' ';
	}
	std::cout << std::endl;
	return 0;
};



Results:
add2(0)
add1(1)
add2(2)
add1(3)
add2(4)
add1(5)
0 2 4 



See the difference?
Was This Post Helpful? 0
  • +
  • -

#8 xnewix  Icon User is offline

  • D.I.C Head
  • member icon

Reputation: 2
  • View blog
  • Posts: 204
  • Joined: 23-May 09

Re: STL vectors and lists. unable to store class objects correctly

Posted 01 September 2013 - 01:09 PM

no way! an & thanks :)/>/> I thought it was something to do with that. It worked fine when I put normalpoints back into the sphere class too.
now that it kinda works, i've completly forgotten why i wanted 3 arguments for that function. heck it doesn't really do anything usseful.

anyway, it's probably hidious in places, but here's what I came up with ...

#include <iostream>
#include <fstream>
#include <cmath>
#include <string.h>
#include <vector>
#include <list>

#define M_PI 3.14159265359

class Point3d {
private:
	double x,y,z;
public:
	Point3d(double nx,double ny,double nz) : x(nx),y(ny),z(nz) { }
	Point3d()   {}
	~Point3d()  {}

	double getx() { return x; }
	double gety() { return y; }
	double getz() { return z; }
};
class Triangle3d {
private:
	int v1,v2,v3;
public:
	Triangle3d(int nv1, int nv2, int nv3) : v1(nv1),v2(nv2),v3(nv3) { }
	Triangle3d()  {}
	~Triangle3d() {}
	
	int getv1() { return v1; }
	int getv2() { return v2; }
	int getv3() { return v3; }
};

class Sphere3d {
private:
public:
	Sphere3d()  {}
	~Sphere3d() {}

	std::list<Point3d> point3d;	
	//std::list<Point3d> normalpoints;
	std::list<Triangle3d> triangle3d;
	Point3d retpoint3d;
	Triangle3d rettriangle3d;

	void addPoint(double x,double y, double z) {
		point3d.push_back(Point3d(x,y,z));	
	}  
	void addTriangle(int xindex,int yindex, int zindex) {
		triangle3d.push_back(Triangle3d(xindex,yindex,zindex));	
	} 
	void getPoint(int index, std::list<Point3d> newpoint3d) {
		std::list<Point3d>::iterator it = newpoint3d.begin();
		std::advance(it, index);		
		retpoint3d = Point3d(it->getx(),it->gety(),it->getz());
	}   
	void getTriangleVertexRefs(int index, std::list<Triangle3d> newtriangle3d) {
		std::list<Triangle3d>::iterator it = newtriangle3d.begin();
		std::advance(it, index);		
		rettriangle3d = Triangle3d(it->getv1(),it->getv2(),it->getv3());		
	}
	void normalizePoint(int index, std::list<Point3d> newpoint3d, std::list<Point3d> &newnormalpoints) {
		
		getPoint(index,newpoint3d); double v1 = retpoint3d.getx(); 
		getPoint(index,newpoint3d); double v2 = retpoint3d.gety(); 
		getPoint(index,newpoint3d); double v3 = retpoint3d.getz(); 

		double d  = sqrt((v1*v1)+(v2*v2)+(v3*v3));
		v1 /=d;
		v2 /=d;
		v3 /=d;

		std::cout << " v1: " << v1 << " v2: " << v2 << " v3: " << v3 << std::endl;     
                newnormalpoints.push_back(Point3d(v1,v2,v3)); 
	}
};

void sphere() {
	Sphere3d sphere3d;

	double r= (1.0+sqrt(5.0))/2.0;

	sphere3d.addPoint(-1.0, r,0.0);
	sphere3d.addPoint( 1.0, r,0.0);
	sphere3d.addPoint(-1.0,-r,0.0);
	sphere3d.addPoint( 1.0,-r,0.0);
    
	sphere3d.addPoint(0.0,-1.0, r);
	sphere3d.addPoint(0.0, 1.0, r);
	sphere3d.addPoint(0.0,-1.0,-r);
	sphere3d.addPoint(0.0, 1.0,-r);

	sphere3d.addPoint( r,0.0,-1.0);
	sphere3d.addPoint( r,0.0, 1.0);
	sphere3d.addPoint(-r,0.0,-1.0);
	sphere3d.addPoint(-r,0.0, 1.0);

    std::cout << sphere3d.point3d.size() << std::endl;

	std::list<Point3d> normalpoints;
	for(int i=0; i<sphere3d.point3d.size(); i++) {
		std::cout << i << ", ";
		sphere3d.normalizePoint(i,sphere3d.point3d,normalpoints);
	}
	std::cout << "normal size: " << normalpoints.size() << std::endl;

	std::list<Point3d>::iterator it_norm; 
	for(it_norm=normalpoints.begin(); it_norm!=normalpoints.end(); it_norm++) {
		std::cout << it_norm->getx() << " " << it_norm->gety() << " " << it_norm->getz() << std::endl;
	}

	std::list<Point3d>::iterator it_point;
	for(it_point=sphere3d.point3d.begin(); it_point!=sphere3d.point3d.end(); it_point++) {
		std::cout << it_point->getx() << " " << it_point->gety() << " " << it_point->getz() << std::endl;
	}	

	sphere3d.addTriangle(0,11,5);
	sphere3d.addTriangle(0,5,1);
	sphere3d.addTriangle(0,1,7);
	sphere3d.addTriangle(0,7,10);
	sphere3d.addTriangle(0,10,11);

	sphere3d.addTriangle(1,5,9);
	sphere3d.addTriangle(5,11,4);
	sphere3d.addTriangle(11,10,2);
	sphere3d.addTriangle(10,7,6);
	sphere3d.addTriangle(7,1,8);

	sphere3d.addTriangle(3,9,4);
	sphere3d.addTriangle(3,4,2);
	sphere3d.addTriangle(3,2,6);
	sphere3d.addTriangle(3,6,8);
	sphere3d.addTriangle(3,8,9);

	sphere3d.addTriangle(4,9,5);
	sphere3d.addTriangle(2,4,11);
	sphere3d.addTriangle(6,2,10);
	sphere3d.addTriangle(8,6,7);
	sphere3d.addTriangle(9,8,1);

	std::list<Triangle3d>::iterator it_tri; 
	
	for(it_tri=sphere3d.triangle3d.begin(); it_tri!=sphere3d.triangle3d.end(); it_tri++) {
	    std::cout << it_tri->getv1() << " " << it_tri->getv2() << " " << it_tri->getv3() << std::endl;	
    }  	
}
int num;

int main () {
	sphere();
	std::cin >> num;
};

Was This Post Helpful? 0
  • +
  • -

#9 baavgai  Icon User is offline

  • Dreaming Coder
  • member icon

Reputation: 5800
  • View blog
  • Posts: 12,635
  • Joined: 16-October 07

Re: STL vectors and lists. unable to store class objects correctly

Posted 01 September 2013 - 02:42 PM

View Postxnewix, on 01 September 2013 - 04:09 PM, said:

now that it kinda works, i've completly forgotten why i wanted 3 arguments for that function. heck it doesn't really do anything usseful.


Good. When you see stuff like that, fix it. This is called refactoring. Programming is an organic process. As you change code, you often make other code irrelevant. Leave it long enough and you confuse yourself.

This is also why programmers run code after even minor changes. The more code you write, the more likely you are to introduce something unintended. The earlier you catch an error you introduced, the easier it is to fix.

Try making a ostream overload for your classes, so you can dump them out easier.

You'd probably also find something like distance a useful addition to Point3d. e.g.
class Point3d {
//..
	double distance(const Point3d &other) { /* your code here*/ }
};



There are probably other methods that would help in this class...
Was This Post Helpful? 0
  • +
  • -

#10 xnewix  Icon User is offline

  • D.I.C Head
  • member icon

Reputation: 2
  • View blog
  • Posts: 204
  • Joined: 23-May 09

Re: STL vectors and lists. unable to store class objects correctly

Posted 02 September 2013 - 08:38 AM

@ baavgai: yes they are starting to get a bit tedious now so i probably will change that soon...

-------

Okay, I ruled against starting a new topic for this, same project, different problem.

Basicaly i've been trying to subdivide an icosahedron. I've been following a few articals online such as http://coredumping.c...f-icosahedrons/ but they can be a bit obscure in places.

I'm able to turn 12 points into the neccecary 48 points for the first subdivision, but the TriangleVerRefs obviously no longer referance the correct points for each triangle, this is my problem.

The only difference in the code is this ..... ,which is in the Sphere class.

// Midpoint subdivides the origial 12 points into 48 points. 
	// Use to split each triangle into 4 new ones.
	// Don't know what the new TriangleVertRefs will be though.
	void midpoint(std::list<Point3d> newpoint3d, std::list<Point3d> &temppoints3d) {
		
		// use to store the three midpoints.
		Point3d point3d_1;
        Point3d point3d_2;
		Point3d point3d_3;

		for(int index=0; index<point3d.size(); index +=3) {

		// this could propably be seperated into a seperate function
		getPoint(index,  newpoint3d); double v1_x = retpoint3d.getx();
		getPoint(index,  newpoint3d); double v1_y = retpoint3d.gety();
		getPoint(index,  newpoint3d); double v1_z = retpoint3d.getz();

		getPoint(index+1,newpoint3d); double v2_x = retpoint3d.getx();
		getPoint(index+1,newpoint3d); double v2_y = retpoint3d.gety();
		getPoint(index+1,newpoint3d); double v2_z = retpoint3d.getz();

		getPoint(index+2,newpoint3d); double v3_x = retpoint3d.getx();
		getPoint(index+2,newpoint3d); double v3_y = retpoint3d.gety();
		getPoint(index+2,newpoint3d); double v3_z = retpoint3d.getz();

		// calculate the three midpoints 1+2,2+3,3+1 -> 4,5,6
		point3d_1 = Point3d((v1_x+v2_x)/2,(v1_y+v2_y)/2,(v1_z+v2_z)/2);
		point3d_2 = Point3d((v2_x+v3_x)/2,(v2_y+v3_y)/2,(v2_z+v3_z)/2);
		point3d_3 = Point3d((v3_x+v1_x)/2,(v3_y+v1_x)/2,(v3_z+v1_x)/2);

		//     3
		//   6 - 5  
		// 1 - 4 - 2

		// points for 4 triangles?
		// 6,1,4
		temppoints3d.push_back(Point3d(point3d_3.getx(),point3d_3.gety(),point3d_3.getz()));
        temppoints3d.push_back(Point3d(v1_x,v1_y,v1_z));
        temppoints3d.push_back(Point3d(point3d_1.getx(),point3d_1.gety(),point3d_1.getz()));
        // 4,2,5
		temppoints3d.push_back(Point3d(point3d_1.getx(),point3d_1.gety(),point3d_1.getz()));
        temppoints3d.push_back(Point3d(v2_x,v2_y,v2_z));
		temppoints3d.push_back(Point3d(point3d_2.getx(),point3d_2.gety(),point3d_2.getz()));
        // 5,3,6
		temppoints3d.push_back(Point3d(point3d_2.getx(),point3d_2.gety(),point3d_2.getz()));
		temppoints3d.push_back(Point3d(v3_x,v3_y,v3_z));
		temppoints3d.push_back(Point3d(point3d_3.getx(),point3d_3.gety(),point3d_3.getz()));
     	// 4,5,6
		temppoints3d.push_back(Point3d(point3d_1.getx(),point3d_1.gety(),point3d_1.getz()));
   		temppoints3d.push_back(Point3d(point3d_2.getx(),point3d_2.gety(),point3d_2.getz()));
       	temppoints3d.push_back(Point3d(point3d_3.getx(),point3d_3.gety(),point3d_3.getz()));
		
		// eww, replace old list.
		newpoint3d = temppoints3d;
		// increase index by +3 to get original 2nd point so can subdivide.
		}
		std::cout << "point3d.size()" << newpoint3d.size();
		point3d = newpoint3d;
	}


these no longer use the correct points. the subdivided sphere should have 80 triangles not 20 as each of the original triangles are split into 4 new triangless.


	sphere3d.addTriangle(0,11,5);
	sphere3d.addTriangle(0,5,1);
	sphere3d.addTriangle(0,1,7);
	sphere3d.addTriangle(0,7,10);
	sphere3d.addTriangle(0,10,11);

	sphere3d.addTriangle(1,5,9);
	sphere3d.addTriangle(5,11,4);
	sphere3d.addTriangle(11,10,2);
	sphere3d.addTriangle(10,7,6);
	sphere3d.addTriangle(7,1,8);

	sphere3d.addTriangle(3,9,4);
	sphere3d.addTriangle(3,4,2);
	sphere3d.addTriangle(3,2,6);
	sphere3d.addTriangle(3,6,8);
	sphere3d.addTriangle(3,8,9);

	sphere3d.addTriangle(4,9,5);
	sphere3d.addTriangle(2,4,11);
	sphere3d.addTriangle(6,2,10);
	sphere3d.addTriangle(8,6,7);
	sphere3d.addTriangle(9,8,1);

Was This Post Helpful? 0
  • +
  • -

#11 baavgai  Icon User is offline

  • Dreaming Coder
  • member icon

Reputation: 5800
  • View blog
  • Posts: 12,635
  • Joined: 16-October 07

Re: STL vectors and lists. unable to store class objects correctly

Posted 03 September 2013 - 01:24 PM

I figured I'd take a stab at this.

#include <iostream>
#include <cmath>
#include <vector>

struct Point {
	double x, y, z;
	Point(double nx, double ny, double nz) : x(nx), y(ny), z(nz) { }
	Point() { }
	Point midPoint(const Point &pt) const {
		return Point((x + pt.x) / 2.0,(y + pt.y) / 2.0,(z + pt.z) / 2.0);
	}
};

struct Triangle {
	int v[3];
	Triangle(int v0, int v1, int v2) { v[0] = v0; v[1] = v1; v[2] = v2; }
	Triangle() { }
};

class Sphere {
private:
	struct PointRef {
		Point pt;
		int idx[2];
		PointRef(const Point &v, int i0=-1, int i1=-1) : pt(v) { 
			if (i0<i1) { idx[0]=i0; idx[1]=i1; } else { idx[1]=i0; idx[0]=i1; }
		}
	};
	std::vector<PointRef> points;
	std::vector<Triangle> polys;

	void addPoint(double x, double y, double z) { 
		points.push_back(PointRef(Point(x, y, z)));
	}

	void addTriangle(int x, int y, int z) {
		polys.push_back(Triangle(x, y, z));
	}

	int getMidPoint(int p1, int p2) {
		// your code here, when the magic happens
		// check to see if you already have a mid point for these two 
		// ( that's why PointRef and not just point )
		// if you do, give that one back
		// if not, make a new one and return to the index
	}
public:
	Sphere() {
		double r = (1.0 + sqrt(5.0)) / 2.0;

		addPoint(-1.0, r, 0.0);
		addPoint(1.0, r, 0.0);
		addPoint(-1.0, -r, 0.0);
		addPoint(1.0, -r, 0.0);

		addPoint(0.0, -1.0, r);
		addPoint(0.0, 1.0, r);
		addPoint(0.0, -1.0, -r);
		addPoint(0.0, 1.0, -r);

		addPoint(r, 0.0, -1.0);
		addPoint(r, 0.0, 1.0);
		addPoint(-r, 0.0, -1.0);
		addPoint(-r, 0.0, 1.0);

		addTriangle(0, 11, 5);
		addTriangle(0, 5, 1);
		addTriangle(0, 1, 7);
		addTriangle(0, 7, 10);
		addTriangle(0, 10, 11);

		addTriangle(1, 5, 9);
		addTriangle(5, 11, 4);
		addTriangle(11, 10, 2);
		addTriangle(10, 7, 6);
		addTriangle(7, 1, 8);

		addTriangle(3, 9, 4);
		addTriangle(3, 4, 2);
		addTriangle(3, 2, 6);
		addTriangle(3, 6, 8);
		addTriangle(3, 8, 9);

		addTriangle(4, 9, 5);
		addTriangle(2, 4, 11);
		addTriangle(6, 2, 10);
		addTriangle(8, 6, 7);
		addTriangle(9, 8, 1);
	}
	
	int triCount() const { return polys.size(); }
	int pointCount() const { return points.size(); }
	
	void generate() {
		std::vector<Triangle> newPolys;
		for(std::vector<Triangle>::const_iterator it=polys.begin(); it!=polys.end(); ++it) {
			const int *v = it->v;
			int a = getMidPoint(v[0], v[1]);
			int b = getMidPoint(v[1], v[2]);
			int c = getMidPoint(v[2], v[0]);
			
			newPolys.push_back(Triangle(v[0], a, c));
			newPolys.push_back(Triangle(v[1], b, a));
			newPolys.push_back(Triangle(v[2], c, B)/>);
			newPolys.push_back(Triangle(a, b, c));
		}
		polys = newPolys;
	}
};

using namespace std;

int main() {
	Sphere sphere;
	cout << "points=" << sphere.pointCount() << " triangles=" << sphere.triCount() << endl;
	sphere.generate();
	cout << "points=" << sphere.pointCount() << " triangles=" << sphere.triCount() << endl;
	return 0;
}



Results:
points=12 triangles=20
points=72 triangles=80



I don't even know if that's right, but I think it is. Maybe it will give you another way to look at the problem. The link you gave is a pretty good example, though he chucks the idea of vertices early. The link below that seemed clearer to me.
Was This Post Helpful? 0
  • +
  • -

#12 xnewix  Icon User is offline

  • D.I.C Head
  • member icon

Reputation: 2
  • View blog
  • Posts: 204
  • Joined: 23-May 09

Re: STL vectors and lists. unable to store class objects correctly

Posted 04 September 2013 - 06:57 PM

At the moment im getting the same output.

72 points and 80 triangles.

though i'm getting some undesirable results when running through Opengl.
but apart from that and the redundant midpoints it looks like a sphere.

I'll posst an larger update with code tommorow,
Was This Post Helpful? 0
  • +
  • -

#13 xnewix  Icon User is offline

  • D.I.C Head
  • member icon

Reputation: 2
  • View blog
  • Posts: 204
  • Joined: 23-May 09

Re: STL vectors and lists. unable to store class objects correctly

Posted 05 September 2013 - 03:48 PM

this is taken from the opengl version, so there are a few redundant bits of code.

this works but doesn't store the new data.

all i can think of now is the way that the triangles are added. or it has something to do with the extra points.

the image shows the same sphere from different distances.
the solid sphere looks fine but looking closer in wiremesh mode there are incorrectly/extra? placed lines.

Posted Image


#include <iostream>
#include <fstream>
#include <cmath>
#include <vector>


class Point3d {
private:
	double x,y,z;
public:
	Point3d(double nx,double ny,double nz) : x(nx),y(ny),z(nz) { }
	Point3d()   {}
	~Point3d()  {}

	double getx() { return x; }
	double gety() { return y; }
	double getz() { return z; }
};

class Triangle3d {
private:
	int v1,v2,v3;
public:
	Triangle3d(int nv1, int nv2, int nv3) : v1(nv1),v2(nv2),v3(nv3) { }
	Triangle3d()  {}
	~Triangle3d() {}
	
	int getv1() { return v1; }
	int getv2() { return v2; }
	int getv3() { return v3; }
};

class Sphere3d {
private:
	double radius;
	double size;
	double depth; // subdivisions

	std::vector<Point3d>      point3d;	
	std::vector<Triangle3d>   triangle3d;
	std::vector<Triangle3d>   newtriangles3d;

public:
	Sphere3d(double nsize, double ndepth)  : size(nsize), depth(ndepth) {

		radius =(1.0+sqrt(5.0))/2.0;

		addPoint(-size, radius*size,0.0);
		addPoint( size, radius*size,0.0);
		addPoint(-size,-radius*size,0.0);
		addPoint( size,-radius*size,0.0);
    
		addPoint(0.0,-size, radius*size);
		addPoint(0.0, size, radius*size);
		addPoint(0.0,-size,-radius*size);
		addPoint(0.0, size,-radius*size);

		addPoint( radius*size,0.0,-size);
		addPoint( radius*size,0.0, size);
		addPoint(-radius*size,0.0,-size);
		addPoint(-radius*size,0.0, size);

		addTriangle(0,11,5);
		addTriangle(0,5,1);
		addTriangle(0,1,7);
		addTriangle(0,7,10);
		addTriangle(0,10,11);

		addTriangle(1,5,9);
		addTriangle(5,11,4);
		addTriangle(11,10,2);
		addTriangle(10,7,6);
		addTriangle(7,1,8);

		addTriangle(3,9,4);
		addTriangle(3,4,2);
		addTriangle(3,2,6);
		addTriangle(3,6,8);
		addTriangle(3,8,9);

		addTriangle(4,9,5);
		addTriangle(2,4,11);
		addTriangle(6,2,10);
		addTriangle(8,6,7);
		addTriangle(9,8,1);

		generate();	
	} 
	~Sphere3d() {}	
	
	void addPoint(double x,double y, double z) {
		point3d.push_back(Point3d(x,y,z));	
	}  
	void addTriangle(int xindex,int yindex, int zindex) {
		triangle3d.push_back(Triangle3d(xindex,yindex,zindex));	
	} 
	int getMidPoint(int p1, int p2) {		
		
		//N.B - Still need to Eliminate duplicates
		double nx = (point3d[p1].getx()+point3d[p2].getx())/2;
		double ny = (point3d[p1].gety()+point3d[p2].gety())/2;
		double nz = (point3d[p1].getz()+point3d[p2].getz())/2;

		double n = sqrt((nx*nx)+(ny*ny)+(nz*nz));
		nx /=n;	ny /=n;	nz /=n;

        nx *=sqrt(radius*radius+1.0)*size; 
		ny *=sqrt(radius*radius+1.0)*size; 
		nz *=sqrt(radius*radius+1.0)*size;

		point3d.push_back(Point3d(nx,ny,nz));
		return point3d.size()-1;
	}
	void subdivide(int v1,int v2,int v3,double depth) {
		
		if(depth == 0) {				
			return;
		}

		int v12 = getMidPoint(v1,v2);
		int v23 = getMidPoint(v2,v3);
		int v31 = getMidPoint(v3,v1);

		newtriangles3d.push_back(Triangle3d(v1,v12,v31));
		newtriangles3d.push_back(Triangle3d(v2,v23,v12));
		newtriangles3d.push_back(Triangle3d(v3,v31,v23));
		newtriangles3d.push_back(Triangle3d(v12,v23,v31));

		subdivide(v1,v12,v31,depth-1);	
                subdivide(v2,v23,v12,depth-1);
		subdivide(v3,v31,v23,depth-1);
		subdivide(v12,v23,v31,depth-1);	

	}
	void generate() {		
		for(int i=0; i<20; i++) {
			subdivide(triangle3d[i].getv1(),triangle3d[i].getv2(),triangle3d[i].getv3(),depth);			
		}
		if(depth != 0) {	
			triangle3d = newtriangles3d;
			newtriangles3d.clear();
		}		
		outputdata();
	}
	/*
	void draw() {
		for(int i=0; i<triangle3d.size(); i++) {
			glBegin(GL_TRIANGLES);

                glColor3f(0.5,0.5,0.5); 
				glNormal3f(point3d[triangle3d[i].getv1()].getx(),point3d[triangle3d[i].getv1()].gety(),point3d[triangle3d[i].getv1()].getz());
   			    glVertex3f(point3d[triangle3d[i].getv1()].getx(),point3d[triangle3d[i].getv1()].gety(),point3d[triangle3d[i].getv1()].getz());
		        
				glColor3f(0.5,0.5,0.5); 
				glNormal3f(point3d[triangle3d[i].getv2()].getx(),point3d[triangle3d[i].getv2()].gety(),point3d[triangle3d[i].getv2()].getz());
				glVertex3f(point3d[triangle3d[i].getv2()].getx(),point3d[triangle3d[i].getv2()].gety(),point3d[triangle3d[i].getv2()].getz());
				
				glColor3f(0.5,0.5,0.5); 
				glNormal3f(point3d[triangle3d[i].getv3()].getx(),point3d[triangle3d[i].getv3()].gety(),point3d[triangle3d[i].getv3()].getz());
		        glVertex3f(point3d[triangle3d[i].getv3()].getx(),point3d[triangle3d[i].getv3()].gety(),point3d[triangle3d[i].getv3()].getz());
		    
			glEnd();
		}
	}
	*/
	void outputdata() {
		std::ofstream datafile;
		datafile.open("data.txt");
		datafile << "New Triangles: " << newtriangles3d.size() << std::endl;
		for(std::size_t i=0; i<point3d.size(); i++) {
			datafile  << i << "  x: " << point3d[i].getx() << "  y: " << point3d[i].gety() << "  z: " << point3d[i].getz() << std::endl;
			//std::cout << i << "  x: " << point3d[i].getx() << "  y: " << point3d[i].gety() << "  z: " << point3d[i].getz() << std::endl;
		}	 
        for(std::size_t i=0; i<triangle3d.size(); i++) {
			datafile  << i << "  x: " << triangle3d[i].getv1() << "  y: " << triangle3d[i].getv2() << "  z: " << triangle3d[i].getv3() << std::endl;
			//std::cout << i << "  x: " << triangle3d[i].getv1() << "  y: " << triangle3d[i].getv2() << "  z: " << triangle3d[i].getv3() << std::endl;
		}	 
		datafile.close();
	}
	double displaydepth()  { return depth; }
	int pointcount()    { return point3d.size(); }
	int trianglecount() { return triangle3d.size(); }
};

int main() {
	Sphere3d sphere3d(10.0,1.0);
	std::cout << "subsdivisions:  " << sphere3d.displaydepth() << std::endl;
	std::cout << "points:         " << sphere3d.pointcount() << std::endl;
	std::cout << "triangles       " << sphere3d.trianglecount() << std::endl;

	int num=0; std::cin >> num;
	return 0;
}

This post has been edited by xnewix: 05 September 2013 - 03:52 PM

Was This Post Helpful? 0
  • +
  • -

#14 baavgai  Icon User is offline

  • Dreaming Coder
  • member icon

Reputation: 5800
  • View blog
  • Posts: 12,635
  • Joined: 16-October 07

Re: STL vectors and lists. unable to store class objects correctly

Posted 06 September 2013 - 07:08 AM

The size thing is a little weird. That's where you're hurting yourself, I think. Also, for rendering, since you aren't really using both vertex and connections, you could just use points.

I played with this, so this is what I came up with.

Version 1:
Spoiler



After that, I decided to use just a vector of Triangles, so version 2:
Spoiler


Thanks for the diversion. Hope this helps.
Was This Post Helpful? 1
  • +
  • -

Page 1 of 1