Thread: Multidimential(3) vectors

  1. #1
    Password:
    Join Date
    Dec 2009
    Location
    NC
    Posts
    587

    Multidimential(3) vectors

    How do I define a 3 dimension vector?

    Code:
    #ifndef FIELD_H_INCLUDED
    #define FIELD_H_INCLUDED
    
    #include <memory>
    #include <vector>
    #include "object.h"
    
    class field{
        public:
            int length, width, height;
            vector<shared_ptr<object> > location; // 3 dim vector ???
    };
    
    #endif // FIELD_H_INCLUDED

  2. #2
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    vector< vector< vector< shared_ptr< object > > > >
    Code:
    #include <cmath>
    #include <complex>
    bool euler_flip(bool value)
    {
        return std::pow
        (
            std::complex<float>(std::exp(1.0)), 
            std::complex<float>(0, 1) 
            * std::complex<float>(std::atan(1.0)
            *(1 << (value + 2)))
        ).real() < 0;
    }

  3. #3
    Password:
    Join Date
    Dec 2009
    Location
    NC
    Posts
    587
    Yeah... I did it like this instead:
    Code:
    #ifndef FIELD_H_INCLUDED
    #define FIELD_H_INCLUDED
    
    #include "object.h"
    
    class field{
    	public:
    		int length, width, height;
    		object ****location;
    
    		field(int l = 1, int w = 1, int h = 1);
    		field(const field&);
    
    		~field();
    };
    
    #endif // FIELD_H_INCLUDED
    Code:
    #include "field.h"
    
    field::field(int l, int w, int h) : length(l), width(w), height(h)
    {
    	int i, j, k;
    	location = new object*** [length];
    	for(i = 0;i < length;i++)
    	{
    		location[i] = new object** [width];
    		for(j = 0;j < width;j++)
    		{
    			location[i][j] = new object* [height];
    			for(k = 0;k < height;k++)
    				location[i][j][k] = 0;
    		}
    	}
    }
    
    field::field(const field& f) : length(f.length), width(f.width), height(f.height)
    {
    	int i, j, k;
    	location = new object*** [length];
    	for(i = 0;i < length;i++)
    	{
    		location[i] = new object** [width];
    		for(j = 0;j < width;j++)
    		{
    			location[i][j] = new object* [height];
    			for(k = 0;k < height;k++)
    				location[i][j][k] = f.location[i][j][k];
    		}
    	}
    }
    
    field::~field()
    {
    	int i, j, k;
    	for(i = 0;i < length;i++)
    	{
    		for(j = 0;j < width;j++)
    		{
    			for(k = 0;k < height;k++)
    				if(location[i][j][k] != 0)
    					delete[] location[i][j][k];
    			delete[] location[i][j];
    		}
    		delete[] location[i];
    	}
    	delete[] location;
    }
    I realized I don't need vectors anyway. I won't have any reason to resize after defining and allocating it, so I guess I don't need all the extra bloat.

    Thanks for the example though.

  4. #4
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Then I suggest std::array. Or even better, there should be some boost containers that simplify this (boost::multi_array).
    Last edited by Elysia; 07-21-2010 at 02:20 PM.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  5. #5
    Password:
    Join Date
    Dec 2009
    Location
    NC
    Posts
    587
    Simplify?! How much simpler could it get? I know it's like O(h * w * l) I think, but I can live with that since it only gets called once per field, field being a very long lasting class. It doesn't get created/destroyed often.

  6. #6
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    How about:
    Code:
    boost::multi_array<double, 3> A(boost::extents[3][4][2]);
    Done.
    Last edited by Elysia; 07-21-2010 at 02:25 PM.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  7. #7
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    One approach that may be feasible is to have a single std::vector<std::shared_ptr<object>> that holds length * width * height elements. Then, you simulate the 3D array by having a std::vector<std::shared_ptr<object>*> that holds length * width elements. Each of these pointers point to shared_ptrs from the earlier vector, at intervals of height units. Finally, you define a std::vector<std::shared_ptr<object>**>, say named location, with length elements. Each of these pointers point to the pointers to shared_ptrs from the previous vector, at intervals of width units. Now, if I did not mess up in my description , you should be able to access the original shared_ptrs by writing location[x][y][z]. You would have effectively only required three allocations rather than the many that you have now.

    I believe that Boost.MultiArray uses an approach similiar to this, but of course it requires Boost.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  8. #8
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    I would not allocate a fixed-size 3-dimensional array like that. There's no need to width*height+1 calls to new when it can be done with just 3, and then the freeing can be done with just 3 calls to delete and no loops. Using vectors you could have an item vector, a row vector, and a column vector. The row vector contains pointers into the column vector which contains pointers into the item vector.
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

  9. #9
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    .....or you can jam the data in a structure and use one linear array of those structures to represent all the data in a much simpler fashion.

  10. #10
    Password:
    Join Date
    Dec 2009
    Location
    NC
    Posts
    587
    It has to be 3 dimensional because it is used to represent space.

  11. #11
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    Ok....and?

    Code:
    struct Vector3
    {
       float x;
       float y;
       float z;
    
       Vector3() : x(0.0f),y(0.0f),z(0.0f) 
       {
       }
    
       Vector3(float x,float y,float z) : x(x),y(y),z(z)
       {
       }
    };
    There is no need to represent 'space' as an array since that makes 'space' into a finite grid. Rather use Vector3 to represent any point in 3 space.

    Code:
    std::vector<Vector3> space;
    
    Vector3 vec;
    for (unsigned int i = 0;i < 10; ++i)
    {
        vec.x = GetRandomFloatRange(-5000.0f,5000.0f);
        vec.y = GetRandomFloatRange(-5000.0f,5000.0f);
        vec.z = GetRandomFloatRange(-5000.0f,5000.0f);
        space.push_back(vec);
    };
    
    float GetRandomFloatRange(float min,float max)
    {
       unsigned int temp = rand() % 1000;
       float coef = temp / 1000.0f;
    
       return min + coef * (max - min);
    }
    All 3D games work in 3 space or 4 space (x,y,z,w) and they do not require huge multi-dimensional arrays. I avoid multi-dimensional arrays and multi-dimensional vectors at all costs. They can be quite confusing past 2 dimensions and the memory required plus the minor issue of speed when accessing multi-dimensional arrays keeps me far away from them.

    This code could be used to represent a starfield centered around the origin. If you move the points along a vector through local space and wrap them at the edges and then transform this 'system' to world space you can simulate a starfield around a player or object. Just because you have 3 coordinates or 3 components of a vector representing 3 space that does not mean you need a 3 dimensional array to represent it in memory. An array does not represent 'space' but it represents space broken up into finite grid cells.
    Last edited by VirtualAce; 07-22-2010 at 09:21 PM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Using/ Searching through Multiple Vectors
    By bengreenwood in forum C++ Programming
    Replies: 10
    Last Post: 08-03-2009, 08:35 AM
  2. Vectors
    By naseerhaider in forum C++ Programming
    Replies: 11
    Last Post: 05-09-2008, 08:21 AM
  3. How can i made vectors measuring program in DevC++
    By flame82 in forum C Programming
    Replies: 1
    Last Post: 05-07-2008, 02:05 PM
  4. How properly get data out of vectors of templates?
    By 6tr6tr in forum C++ Programming
    Replies: 4
    Last Post: 04-15-2008, 10:35 AM
  5. How to use Vector's in C++ !?!
    By IndioDoido in forum C++ Programming
    Replies: 3
    Last Post: 10-14-2007, 11:13 AM