I'm taking data from a plot of a 2D line drawing and trying to plot it on a piece of paper of a given size. (The paper size can change) To make the line drawings fit on the paper, I need to scale it. Unfortunately, some of the legs on this plot are very short, and some are extremely long, so a simply linear scale results in areas too small to see with a single line often taking up half the paper. I'm trying to use logarithmic scaling to compensate for this, so the entire drawing is on the piece of paper and the longest lengths are attenuated more than the shortest lengths. I just can't seem to wrap my head around the math here. If I can understand the math, I can translate that into the C++ code I need.
I've looked here: Convert Linear scale to Logarithmic
And here: https://math.stackexchange.com/questions/970094/convert-a-linear-scale-to-a-logarithmic-scale
The basics:
I need to convert linear x,y values into logarithmic values ranging from 1-paperWidth and from 1-paperHeight.
My x and y values will always be positive and will range from x-min to x-max, and y-min to y-max.
Can someone dumb down this math for me?
I would REALLY appreciate it!
Let you have range xmin..xmax
and want to map it logaritmically onto canvas coordinates X0..X1
. Equation is:
X = a + b * ln (x)
You can use decimal logarithm log10
if you want (this change just scales b
coefficient)
Substitute start and end points:
X0 = a + b * ln(xmin)
X1 = a + b * ln(xmax)
To find a
and b
parameters, you need to solve equation system above. Subtract the first equation from the second one
X1 - X0 = b *(ln(xmax) - ln(xmin)) = b * ln(xmax / xmin)
so
b = (X1 - X0) / ln(xmax / xmin)
Now put this b value in the first equation to get a
a = X0 - b * ln(xmin)
Example:
xmin = 0.01
xmax = 100
X0 = 20
X1 = 800
b = (X1 - X0) / ln(xmax / xmin) = 780/9.21 = 84.7
a = 20 - 84.7 * (-4.6)= 410
So transformation is:
X = 410 + 84.7 * ln(x)
Check for some intermediate points (should be evenly spaced in logaritmic space):
x = 0.01 => X = 20
x = 0.1 => X = 215
x = 1 => X = 410 (OK, this is (20+800)/2)
x = 10 => X = 605
x = 100 => X = 800
Concerning question in comments:
Logarithmic function y=ln(x)
transforms range x1..x2
(length x2-x1
) into range of length ln(x2)-ln(x1)
.
But if we want to have specific result range length (for example, canvas size for drawing), we should introduce scale coefficient b
.
If we want that result range starts from specific value (for example, canvas coordinates start from 0), we should introduce shift coefficient a
.
So we make linear transformation of result into needed range.