So, I have been working on some code with a group of people/organisations etc. and I've hit a small bump in the road that I thought someone on here may be able to help me with :)
I have developed some code that draws 3D towers to represent the amount energy particular objects have, thus creating a sort of graph. I am currently using a very basic linear scaling algorithm but I wish to use a logarithmic method of scaling.

Currently my algorithm does the following:
NB: I only scale in x, y as z is the height and represents a completely different thing.

1: Calculates the centre point of the object
2: Calculates the distance between the centre and each corner
3: Divides this by the data collections maximum/highest energy
4: Multiplies this by the current objects energy
5: Adds this final value to the centre point

e.g.

corners[i].x = centre[0] + ( ( ( corners[i].x - centre[0] ) / max ) * energy );
corners[i].y = centre[1] + ( ( ( corners[i].y - centre[1] ) / max ) * energy );

In effect this scales the objects in proportion to the maximum recorded energy for a given data collection (a sort of percentage).
I wish to use a logarithmic scaling method to do the same thing but I am not sure how I would do this.
I am not all that great when it comes to Maths but particularly when it comes to logarithmic scaling in C++.....I would appreciate if someone could give me a hand with this. In particular coding examples in C++ would be very useful

Thanks in advance

I usually tackle these problems by looking at the boundaries. In your case, you have the basic scaling factor is "energy / max" which is at most 1 and at least 0. So in any logarithmic scale (I would assume you want base 10, but that doesn't really matter), these bounds translate to at most 0 (log(1)) and at least -infinity (log(0)). So you have a bit of a problem, you see. You will have to do a bit more work to get anything sensible out of that.

So, say you have base 10, the desired output, normally, is that if the energy of one object is ten times that of another, it should be one unit bigger. Really the only way I can think of is to set some minimum value of energy. Say the minimum for "energy / max" is 10^-10, which, in log10, is -10. Then a scale function like this might work:

//this checks the lower-bound, if greater then use log10 + 10 (offset), if lesser then use 0.
double logScaleFactor = (energy > 1E-10 * max ? log10(energy / max) + 10 : 0);
..
corners[i].x = centre[0] + ( corners[i].x - centre[0] ) * logScaleFactor; //now, the scale factor will be between 0 and 10.
corners[i].y = centre[1] + ( corners[i].y - centre[1] ) * logScaleFactor;

Thank you very much for your help and advice. It has been extremely useful to me! :)

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.