There are two main special steps to the technique used by most open-source 3d printer controllers:
- Divide each linear gcode segment into lots of very small subsegments ("Segmentation")
- Use some basic trigonometry or the pythagorean theorem to tie extruder position to carriage height for each of the three towers ("Inverse Kinematics")
to find the target position for each small segment
The inverse kinematics are surprisingly simple. A virtual 90 degree triangle is constructed from two known lengths to solve for the unknown third length:
- The fixed delta arm length is the hypotenuse of the triangle
- The horizontal distance between the column joints and end-effector joints is calculated from the XY coordinates of the nozzle and the fixed position of the column, to determine the length of the lower side of the triangle
- The length of the upper side of the triangle is calculated from the previous two via the pythagorean theorem
- The length of the upper side is added to the nozzle Z height to get the necessary carriage height
I think the best open-source reference here is Steve Grave's Rostock Kinematics document, rev3 available for download here: https://groups.google.com/d/msg/deltabot/V6ATBdT43eU/jEORG_l3dTEJ
Some relevant pictures:
These inverse kinematics calculations are performed for each carriage to get a "carriage space" target position, and this is performed for every path sub-segment.
The results from these steps can then be reinserted back into the standard linear path interpolation techniques for the printer, in which it fires steps in the necessary ratios and at the necessary rates to produce the desired straight-line motion and acceleration/velocity profile. (How THAT is done is a different question.)
The net effect is that the printer will move through a series of small "linear" carriage movements (linear meaning constant* speed with respect to time) that collectively approximate the necessary curved (quadratic position with respect to time) carriage motions required to produce a straight-line end-effector move.
*(Constant speed before acceleration slowdowns are applied in order to obey dynamics constraints, anyway. Again, that's the subject of a different question.)
Segmentation is very similar to the process of using a polygon to approximate a circle. If the facets are small enough, the polygon is a good approximation. Higher Segmentation rates produce less path-following error. The primary conceptual difference between drawing circle arcs and Delta motion paths is that the so-called "faceted arc" with Delta Segmentation is constructed in height-vs-time coordinates instead of the X-vs-Y coordinates you'd use to draw a circle on a computer screen.
This system is used in large part because support for Delta style printers was originally bolted onto GRBL-based motion planners which were written exclusively for straight-line motion paths in Cartesian printers. It was a relatively minimal modification to the existing codebase compared to implementing full quadratic path interpolation.
Techniques have evolved over the years. And alternate approaches are often used: for example, the dc42 fork of RepRapFirmware performs exact path-following without segmentation, by recalculating the proper time for the next step after every step. This is functionally equivalent to approximating a circle with a polygon facet count so high that every pixel on the screen gets its own facet. So it is exactly as accurate as the positioning resolution of the motors allows. The downside is that this segmentation-free technique is fairly processor-intensive, so it only works on relatively fast controllers, not the older 8bit Atmega AVR that powers most existing consumer/hobbyist printers today.
Other techniques are possible. The academic parallel robotics control literature is a whole other world of mathematical techniques and complexity in order to produce generalized control algorithms that work for a wide range of robot mechanisms. The version we use in open-source 3d printers is quite simple and application-specific in comparison.