From Last Time …
In our last post we talked about how the locations of the marks found on standard scales of a slide rule could be determined. Below we will code this in a programming language to use the computer to draw scaled images of a few standard scales. The portions of code shown below were used to create the images of scales found in our previous post.
Review:
The main scales for computing are taken to be C/D scales which run from 1 to 10.
In the table below, all scales have the same physical length, L0.
For each scale, values of y are chosen to be marked. The table shows the minimum and maximum acceptable values of y for each scale. In terms of the variable x that appears on the C/D scales, other scales represent functions of x, denoted by f(x). The inverse of this function is denoted by g. Both f and its inverse g are shown in the table. The marks for y are made on each scale a distance d from the left end, according to the inverse function:
An Example:
Suppose we want to create an image with the following scales: D, A, CI, and S.
Let's draw the D scale from 1 to 10 with divisions of 1 and subdivisions of 0.5.
Let's draw the A scale from 1 to 100 with divisions of 1 and 10, subdivisions of 5.
Let's draw the CI scale from 1 to 10 with divisions of 1, subdivisions of 0.5.
Let's draw the S scale with marks from 10 deg. to 90 deg. with divisions of 10 deg. and subdivisions of 5 deg.
To draw the scales I am using the R programming language.1 It is open source, available on Windows, Linux, and Mac systems, and has all the plotting tools necessary. But I'm not “selling” this language as the best or the one to use; it is just familiar to me, is easy to produce plots in a document like this one, and is available to anyone. If you are already familiar with programming and making plots on a computer using one of the standard languages, then you probably are familiar with similar functions as those found below. (Don't hesitate to post a question or email me if you want to discuss further.)
So, in code, we could start by making lists like the following of our desired “y” values that we want to put on the scales, along with subdivisions for each scale:2
# D scale:
yD = c(1,2,3,4,5,6,7,8,9,10)
yDsub = c(1.5,2.5,3.5,4.5,5.5,6.5,7.5,8.5,9.5)
# A scale:
yA = c(1,2,3,4,5,6,7,8,9,10,20,30,40,50,60,70,80,90,100)
yAsub = c(1.5,2.5,3.5,4.5,5.5,6.5,7.5,8.5,9.5,
15,25,35,45,55,65,75,85,95)
# CI scale:
yCI = c(1,2,3,4,5,6,7,8,9,10)
yCIsub = c(1.5,2.5,3.5,4.5,5.5,6.5,7.5,8.5,9.5)
# S scale:
yS = c(5.74,10,20,30,40,50,60,70,90)
ySsub = c(15,25,35,45,55,65,80)
Next, we need to apply the necessary inverse functions to our “y” values to use in determining the correct locations for the primary marks and secondary marks. In R, we can do this directly as we can treat each of our lists above as a variable, and apply the appropriate inverse function to each list in the following way:
# inverse function of x is y
gD = yD
gDs = yDsub
# inverse function of x^2 is sqrt(y)
gA = sqrt(yA)
gAs = sqrt(yAsub)
# inverse function of 10/x is 10/y
gCI = 10/yCI
gCIs = 10/yCIsub
# inverse function of arcsin(x/10) is 10sin(y)
gS = 10*sin(yS /180*pi)
gSs = 10*sin(ySsub/180*pi)
Note that to use the sine function our variables yS
and ySsub
had to be converted from degrees to radians, as this is the unit used in the computer language for execution of its "sin(x)" function.
All of the above variables are actually lists. Because yA
is a list, then gA
will also be a list. If I print out the variables yA
and gA,
I get our original list for yA
and a new list, gA
, where each value in yA
has been evaluated using our inverse function.
yA:
> 1 2 3 4 5 6 7 8 9 10
20 30 40 50 60 70 80 90 100
gA:
> 1.000 1.414 1.732 2.000 2.236 2.449 2.646 2.828 3.000 3.162
4.472 5.477 6.325 7.071 7.746 8.367 8.944 9.487 10.000
The values of gA
, and similarly gAs
, can now be used to place our vertical marks for our A scale at distances L0 × log[ gA
] and L0 × log[ gAs
] along the scale.
With our lists of marks to make on the rule, and with the inverse function being evaluated at each of our marks, we can now make our set of scales. For instance, for the D scale, we want to make vertical linear marks for values yD
, which we will label, and other shorter linear marks for values yDsub
which will not be labeled. To do each scale in the same fashion I’ve written a function that I have called MakeScale
:
MakeScale = function(y, g, gs, name){
plot(0, 0, type="n", xlim=c(0,10), ylim=c(0,3), main=name,
xlab="", ylab="", xaxt="n", yaxt="n", bty="n")
L0 = 10
abline(h=1.5)
segments(L0*log10(g), 1.1,
L0*log10(g), 1.9, lwd=2, col="blue")
segments(L0*log10(gs), 1.3,
L0*log10(gs), 1.7, lwd=2, col="blue")
text( L0*log10(g), 2.7, y )
}
Our function initiates a plot, draws a horizontal line, draws vertical line segments at the major and minor y values, and then writes the y values just above the major marks. I haven’t tried hard to make it very pretty; just trying to illustrate the process. The input to MakeScale
consists of the following four items:
y
: a list of the y values for which to make a long vertical line. These values will be printed above each long line drawn. (example:yA
)g
: the values of the inverse function applied to the valuesy
. These give the locations for placing the long vertical lines. (example:gA
)gs
: a similar list of the locations at which to make a short vertical line. These will not be labled. (example:gAs
)name
: a title to be placed above the scale. (example: “A Scale”)
Within MakeScale
,
the
plot
function sets up plot limits, axis types, the main title, and so on.the
abline
function is drawing a horizontal line at y = y1:abline
(h=y1)the
segments
function draws a line segment between the points (x1,y1) and (x2,y2) on the plot:segments
( x1, y1, x2, y2, width, color)the text function places text centered at (x1,y1):
text
( x1, y1, text)
While you might wish to try this out using a different programming language, hopefully the code chunks provided will give enough flavor for how to proceed.
And now we can create the image containing the four scales:
# parameters to place 4 plots into one plotting region
par(mar=c(1,1,3,1)) # reduce margins to make space
par(mfcol=c(4,1)) # place 4 horizontal plots in 1 column
# then, make the scales
MakeScale(yD, gD, gDs, "D scale")
MakeScale(yA, gA, gAs, "A scale")
MakeScale(yCI,gCI, gCIs, "CI scale")
MakeScale(yS, gS, gSs, "S scale")
Here is the result:
Have you made or attempted to make or plot slide rule scales? If so, what programming languages/codes do you use to make such plots? Please share in the comments your experiences and some screen shots if you have them!
See https://www.r-project.org.
There are special functions that could make the creation of these lists easier, but I have written them out explicitly for clarity’s sake.
Nice clean code Mike - very easy to follow.
In the past I have used Excel scatter plots to generate scales. Similar to your approach I create two tables, one with the coordinates and labels at which I place large '+' shaped tick marks on a horizontal axis along with the labels, and a second with coordinates where I place smaller '+' marks and no labels. It has worked fine for some custom scales I needed for an article I wrote. I have another article which uses somewhat more complex scales and the Excel approach doesn't look as good. I will likely code up something in Python using your approach as a template. Very timely.
Very good information. I am not one for computer languages, or computers for that matter. I'm just old school.
The only computer language I ever began to learn was Fortran IV, which I never was any good at. 😀
I will have to take a look at R as it seems very straightforward.
As an aside, I have started to use AI for writing letters and small reports. I'm just beginning, but it looks promising.