views:

212

answers:

2

I've implemented a 3D strange attractor explorer which gives float XYZ outputs in the range 0-100, I now want to implement a colouring function for it based upon the displacement between two successive outputs.

I'm not sure of the data structure to use to store the colour values for each point, using a 3D array I'm limited to rounding to the nearest int which gives a very coarse colour scheme.

I'm vaguely aware of octtrees, are they suitable in this siutation?

EDIT: A little more explanation:

to generate the points i'm repeatedly running this:

(a,b,c,d are random floats in the range -3 to 3)

x = x2;
y = y2;
z = z2;

x2 = sin(a * y) - z * cos(b * x);
y2 = z2 * sin(c * x) - cos(d * y);
z2 = sin(x);

parr[i][0]=x;
parr[i][1]=y;
parr[i][2]=z;

which generates new positions for each axis each run, to colour the render I need to take the distance between two successive results, if I just do this with a distance calculation between each run then the colours fade back and forth in equilibrium so I need to take running average for each point and store it, using a 3dimenrsionl array is too coarse a colouring and I'm looking for advice on how to store the values at much smaller increments.

+1  A: 

I'd probably think bout some kind of 3-d binary search tree.

template <class KEY, class VALUE>
class BinaryTree
{
    // some implementation, probably available in libraries
public:
    VALUE* Find(const KEY& key) const
    {
        // real implementation is needed here
     return NULL; 
    }

};

// this tree nodes wil actually hold color
class BinaryTree1 : public BinaryTree<double, int>
{
};

class BinaryTree2 : public BinaryTree<double, BinaryTree1>
{
};

class BinaryTree3 : public BinaryTree<double, BinaryTree2>
{
};

And you function to retreive the color from this tree would look like that

bool    GetColor(const BinaryTree3& tree, double dX, double dY, double& dZ, int& color)
{
    BinaryTree2* pYTree = tree.Find(dX);
    if( NULL == pYTree )
     return false;

    BinaryTree1* pZTree = pYTree->Find(dY);
    if( NULL == pZTree )
     return false;

    int* pCol = pZTree->Find(dZ);
    if( NULL == pCol )
     return false;

    color = *pCol;
    return true;
}

Af course you will need to write the function that would add color to this tree, provided 3 coordinates X, Y and Z. std::map appears to be a good candidate for base class.

BostonLogan
+2  A: 

Maybe you could drop the 2-dim array off and use an 1-dim array of

struct ColoredPoint {

   int   x;
   int   y;
   int   z;

   float color;
};

so that the code would look like

 ...
 parr[i].x     = x;
 parr[i].y     = y;
 parr[i].z     = z;
 parr[i].color = some_computed_color;

(you may also wish to encapsulate the fields and use class ColoredPoint with access methods)

And given (x,y,z) how will you find color? Linear search?
BostonLogan
From the initial post "...I now want to implement a colouring function for it based upon the displacement between two successive outputs..."it's not clear if the access to the color value by (x,y,z) is required at all.
access for rendering based on depth into the screen is required so I'm going for the 3-d binary search tree rather than an array of structs.
Baxter
"..access for rendering based on depth into the screen is required"Thanks for the clarification. Using 3 trees seems excessive to me in terms both performance and space. You will have to perform a few dereference operations (costly for modern CPUs unless accessed memory is in the L1/L2 cache) and undertake the space overhead of 2 (unnecessary) trees.Given that (x,y,z) is search key, you may simply use 1 tree and lexicograpical order on triples (node1.x,node1.y,node1.z) <= (node2.x,node2.y,node3.z)to sort/rebalance/search in the tree
actually, space overhead depends on your data (whether they are sparse or not)