[C++] sort by value in struct?

Started by
7 comments, last by OrangyTang 16 years, 1 month ago
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 ?
Advertisement
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?
Well, if Phi eg. takes the values a, b and c I want to be able to print a list of all theta values (sorted) for phi equal to a. And then the same for phi equal to b etc.
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);}
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.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
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.
Thanks for all the suggestions, I'll try them tomorrow since it's 4 at night here atm :)

And no I'm not planning to make sense out of 2250000+ numbers :p they should be input for something else
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;
float red = p.r;
pixeldata.red = p.r;
pixeldata.green = p.g;
pixeldata.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.phi = phi;
pixeldata.theta = theta;
}

problem is that the theta values are not exactly alike apparently >_<
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.

This topic is closed to new replies.

Advertisement