“Go in a straight line from the current (X, Y) point to the point (90.6, 13.8), extruding material as the move happens from the current extruded length to a length of 22.4 mm.”
That is what the G-code RepRap wiki says, but how do you implement it? Well, the important thing to notice is that there is movement in four dimensions here, but only two of them are significant to the calculation of feed rate, namely the X and Y dimensions. The G-code looks like this:
G1 X10.2 Y3.5 Z0.4 E1.2 F1000
Where G1 is the code, X, Y and Z is the new coordinates, E is the travel in filament, namely how much filament to extrude and F is the feed rate, or speed if you will.
Lets say these coordinates are absolute and that before the move we are in the origin: 0, 0, 0, 0.
The travel in the Z-direction is almost always zero, meaning that at very few times do we need to travel upwards (Z is upwards in the 3D printer industry, BTW) and when we do, it is only 0.4mm, so the distance is insignificant.
There is also the “extruder” axis, which can be thought of as another dimension, however it does not contribute to the movement since it is not a spacial dimension.
What is important is the X and Y vectors. Ideally we want to calculate a speed for these two so that the extruder arrives at the right point while travelling in a straight line. That can only happen if the speed at which they travel is proportional to their length. Also, the speed in both X and Y dimensions must be so that the combined speed of the two vectors equals the set feed rate.
So, the speed along the hypotenuse must be the speed at which the hot end travels. Once the hypotenuse is known, the ratio can be calculated as feed_rate_ratio = feed_rate/hyp. The hypotenuse is calculated using Pythagoras:
The ratio is then used to set the feed rate for each of the axes, so feed_rate_x = feed_rate_ratio*abs(X), feed_rate_y = feed_rate_ratio*abs(Y) and this also goes for the Z and E dimensions as well.
What happens when acceleration is added to the mix? Well, it should not complicate the calculations much further. The acceleration ratio can be calculated in the same way the feed rate ratio was calculated:
accel_ratio = accel/hyp
So the acceleration in each of the dimensions must be multiplied with the acceleration ratio. That means accel_x = accel_ratio*abs(X), accel_e = accel_ratio*abs(E) and so on. I am assuming here that the acceleration is a constant that has already been set in the firmware or by a G-code.
An important thing to note is that the speed need not become zero in every turn, so when navigating through high angles, the minimum speed could be a function of the reciprocal of the angle, thus a 180 degree turn would cause the speed to become 0, but a 90 degree turn only half that:
The angle must be constrained to 180 degrees.
I have not yet tried this theory out in practice, but it makes sense in my mind right now.
Here is what it looks like now: