Sign in to follow this  

[C++] sort by value in struct?

This topic is 3565 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I have an array of structs like this struct pixel{ float phi; float theta; float red; float green; float blue; }pixeldata[1500*1500]; What I do here is, I read in a 1500*1500 pixels image, and I compute 2 things, theta and phi and I take the color values and put thos in a struct per pixel. Now I want to print these values ordered by theta. So for Phi equals X print all Theta values from small to big or whatever I need. Now how would I do that ?

Share this post


Link to post
Share on other sites
You say "...for Phi equals X..." what does that mean? You only want to iterate over the elements that have the phi value equal to x?

And then, once you have all the elements of the array that have phi == x, you want to sort those elements so the element with the lowest theta is at the front, and the highest is at the end, and then print those values of theta out?

Share this post


Link to post
Share on other sites

bool comp(const pixel & lhs, const pixel & rhs) {
if (lhs.phi < rhs.phi) return true;
if (lhs.phi > rhs.phi) return false;
return lhs.theta < rhs.theta;
}

void foo(void) {
std::sort(pixeldata, pixeldata + 1500 * 1500, comp);
}

Share this post


Link to post
Share on other sites
You want to print potentially 1500 * 1500 numbers and try to make sense of them? I wish you all the best. ;-)

The easiest way is just to sort your list by theta (Both C and C++ have standard library functions to do this if you don't want to write them yourself), and then iterate through the whole list, only printing those values of theta where phi == x (if I have your meaning right).

If you need something faster, assuming you have a wide range of phi values:
Sort by phi first, then find all the ranges in the list with equal phi and sort those subsectiosn by theta. Keep a map (std::map perhaps) of where your subsections begin/end so you can easily find a subsection based on its phi value.
Psuedo code:

struct PhiRange { float val; int minIndex, maxIndex; }

sortByPhi(pixeldata)
for each pixel p in pixeldata
if new phi
phiMap[phi] = PhiRange(phi, thisIndex, thisIndex);
else
phiMap[phi].maxIndex++;
for each PhiRange pr in phiMap
sortByTheta(pixeldata, pr.minIndex, pr.maxIndex);

printAllOfPhi(phi)
for i from phiMap[phi].minIndex to phiMap[phi].maxIndex
print pixeldata[i].theta

You'll need to take special precautions since you're dealing with floats (you don't want to do exact comparisons with floats or map based on them).

Anyway, hope that helps/makes sense.

Cheers,
--Brian

Share this post


Link to post
Share on other sites

static void print_pixel(pixel const & pxl)
{
if(pxl.phi == 0.0f) std::cout << pxl.theta << std::endl;
}

int main()
{
pixel * begin(pixeldata),
* end(pixeldata + sizeof(pixeldata) / sizeof(pixeldata[0]));

std::sort(begin, end, boost::bind(&pixel::theta, _1));
std::for_each(begin, end, print_pixel);
return 0;
}


Was what i ended up with very quickly.. dunno if i misunderstood the question.

Share this post


Link to post
Share on other sites
Bah apparently it's not as seasy as I thought

since I read in one of those light probes (resolution 1500*1500) from paul debevec. And then I compute theta and phi like this

for (int i = 0; i<1500*1500; i++){
const Imf::Rgba &p = _rawPixels[i];
float red = p.r;
pixeldata[i].red = p.r;
pixeldata[i].green = p.g;
pixeldata[i].blue = p.b;
float tmp = i/1500;
float Yvalue = floorf(tmp);
float Xvalue = i % 1500;
u = (Xvalue - 750)/750;
v = (Yvalue - 750)/750;

float theta=atan2(v,u);
float phi=PI*sqrt(u*u+v*v);

pixeldata[i].phi = phi;
pixeldata[i].theta = theta;
}

problem is that the theta values are not exactly alike apparently >_<

Share this post


Link to post
Share on other sites
Quote:
Original post by Zarathustra

problem is that the theta values are not exactly alike apparently >_<

Have you tried using an epsilon when comparing for equality? Something like:
bool epsilonEquals(const float left, const float right, const float epsilon)
{
return abs(left-right) < epsilon;
}

Also see What Every Computer Scientist Should Know About Floating-Point Arithmetic.

Share this post


Link to post
Share on other sites

This topic is 3565 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this