A CURTA model II mechanical calculator is simulated in all its visible operations.
In the drawings above you see the machine in a front view at the left and a top view at the top right. For ease of understanding a synoptic view of the registers is added at the bottom right.
At the start all registers show zero, the crank is in the adding position (down), the counter inversion switch is up (counts positively) and the register clear handle is at the right.
(click the "Show Legends" button to show the names of the parts)
To operate the calculator:
A CURTA model II is used for this simulator: 11 input digits, 15 result digits, 8 counter digits and 8 shift positions. Parts shown are:
This simulator of the CURTA mechanical calculator is written in SVG and JavaScript. We don't try to do better than Jan Meyer's flash simulator from 2008.
The simulator only shows how to operate the machine. It does not show how the carry mechanism is implemented, how the clearing of registers works internally, how the ten's complement is computed. I.e. it lets you operate it but it does not tell you how it actually works.
There is no attempt at 3D visuals: the model is "flattened" on purpose because the number of digits is too high for them all to be visible at once from the front. The impact on operation is minimal. The most significant deviations from a real view are: (1) all sliders of the input digits are visible and the space between them is more than halved, (2) the counter inversion switch has been moved very close to the right of the first input slider whereas in reality it would be out of sight. The resulting image looks "flat" but still has the same silhouette as the real machine. The top view displays the machine as accurately as necessary.
The commas/thousands separators are not shown. On the real machine there are three in the bottom groove and six in the top cover groove. Their presence is not necessary for understanding how to operate the machine.
Parts shown are:
Thus, for the cap:
The SVG object hierarchy is:
register I of 11 input cursors I01 to I11
register R of 15 result digits R01 to R15
register C of 8 counter digits C01 to C08
crank or drum handle H
counting direction switch D
clearing handle E
cover: the painted cylinders covering the inner mechanism, usually painted grey, green or blue. Top part slides over bottom part. Bottom part has the input register.
Values:
register R shift position S
clearing handle position P
To work with whole numbers, the dimensions of the actual machine are expressed in tenths of a mm, thus what in reality would be 3.4mm would here be expressed as 34. Angles are in degrees and to avoid dealing with negative angles they may be greater than 360.
Objects are generated around 0,0 as their object centre, then transformed as needed.
There are 15+8+11 = 34 digit wheels. Each digit wheel on the cap is represented as a black background rectangle with a white digit. Since the digits need to change, each digit is a clone of one of ten digit glyphs.
Top circle: (in 0.1mm)
inner diameter: 510
digit width: 25, inter-digit space: 42 inter register space: 72
angle between digits: 15º
15x(14+7)=315, leaves 360-315=45, or 22.5º on each side between the registers.
Let 0º pass through the centre of the result register's first digit. Let angles increase clockwise (they do so in SVG anyway). Then:
This helps in deciding when to set a digit to 0 as the reset handle passes over it.
In the real machine there is something sophisticated going on: when the clearing handle turns clockwise, digits are cleard slightly ahead of the handle, if it turns counterclockwise they are cleard slightly after the handle passes over them. But this happens only at the start of the clearing operation, towards the end (before the handle reaches its resting position) digits closer to the handle and finally under the handle are cleard. This is very difficult to simulate, decide to do it under the handle so that we don't even have to simulate the rotation of the digit wheels.
The handle has two resting positions: one in each of the centres of the register separation spaces (which themselves are -22.5/2 = -11.25º away from a digit's centre). These positions are at 337.5º (resting position 1) and 232.5º (resting position 2). However:
The problem with clearing the result could also be solved by using two different values for resting position 1: 337.5 for the counter and -11.5 for the result. This solution is effectively used by comparing with cRegisterDivide1-360 in the result procedures.
To make it easier to decide when to clear a digit as the clearhandle passes over it, we move the clear handle in increments of 5º but because it starts at either -11.25º or 221.25º we begin by putting it at a whole multiple of 5º: -10 or 220º . Then, as its angle modulo 15 is zero, we clear the digit corresponding to its position.
Both resting positions are taken to be at positive angles. After clearing the handle has to be in the other resting position. This makes a more general mechanism so difficult that it is easier to use four unfortunately very similar routines rather than trying to fold them up into one.
All graphics are fairly simple SVG objects. There are no images, only vector graphics.
The operations are performed in JavaScript (arguably the programming language with the worst ever syntax). Because there are only three objects (the top view, the front view and the linear registers) I did not use an object oriented approach. Everything is done with a few global variables and event listener procedures.
Trick for those who want to play with the code: option-clicking (alt key) on the Show Legends button displays a grid of 100x100 units and a circle around the path of the clear handle. This aids in positioning elements.
Using stroke-dashoffset to simulate rotating the cap in front view works well but is of course a trick. It avoids having to clip.
All graphic objects that are referred to by id have their handle stored during the setup phase, so there should not be uses of document.getElementById after setup. During setup (i.e. inside the Setup() function) there are a few local references, used only to position graphic elements.
A few numbers remain in the code: they are small offsets to make things look slightly prettier and it was deemed not worth the trouble to define them as parameters: they would have needed very long names and are used only once and only during seetup. An example is the distance from the top cover of the CURTA name. These numbers are marked in the code with the word tweak.
At first the digits were taken from Helvetica, no font was found to be closer to the Curta's digits. A possible solution would be to use a path for each digit instead of a font glyph, and this was ultimately adopted. There is no noticeable increase of processing time.
SVG filters were used to show some 3D and lighting effects. These do introduce a noticeable delay when clearing registers because the clearing handle has to be redrawn with a different lighting at each position, and furthermore the two little buttons have to be separate with a separate filter. Finally, the filters do not turn with the objects, it is impossible to make them rotate, they do not work in Firefox and there is no way to modify their attributes satisfactorily. In the end I abandoned them infavour of simple flat fills.
The real machine in front (side) view is a cylinder. On the model II not all input digits are then visible and the counter inversion switch is most of the time out of view. I rolled the cylinder out flat, but then the cap's 15 digit positions become very wide and the counter switch is far away to the right. To cope with that I took a few liberties: only show 11 positions of the cap at a time and put the counter switch adjacent to the first input slider.
Making the interslot step 1.8mm instead of 4.8mm makes the flat front image look much better and the sliders then all fit into a space that corresponds to the width of the actual machine when seen from the front. I decided to leave it flat, despite the relative ease of introducing a round look to some parts.
On my machine the crank is the only element made from plastic. There is a triangle on top of its axle centre, it points to the counter digit that is currently incremented or decremented. The paint of this arrow is yellowish, probably because of age (I bought my Curta in 1969). I reproduced this yellowish colour but should perhaps use plain white.
Most of the machine is black. To distinguish parts levels of grey are used as fill colours:
Symmetric paths have their origin in the centre. Rectangles have their origin at top left; Digits (unfortunately?) have their origin at bottom left instead of centre.