4
$\begingroup$

I am currently trying my hand at rigging a virtual delta 3D printer in Blender.

schematic 3D printer

In it, the position of the central sphere (the printer's "nozzle") should be determined by the z-position of the three surrounding cubes so that, whenever one of them moved, the nozzle would position itself accordingly, as if there actually were rigid rods (represented above by bones) connecting them.

To that end, I have tried using three limit distance constraints on the nozzle, each tied to one of the cubes.

This setup doesn't seem to behave properly, however, as

  1. The constraints do not do that good a job at keeping the nozzle at a fixed lenght from all the cubes, even when only one of them is translated along z.

  2. More alarmingly, if I select all the cubes and translate them upwards, the nozzle actually changes its position relative to them (see the nozzle's skewed motion path in the gif below). One would think that only the relative distances between the objects would matter, but it doesn't seem to be the case after transforms.

translation variance

  1. Only when, after a translation, I try to move the misplaced nozzle "by hand" (that is, by pressing G myself), the nozzle snaps back to the position in which it was actually supposed to be. This seems to indicate Blender actually is capable of calculating its correct position but fails to update it properly.

I understand that the stacked nature of Blender's constraint system, coupled with numerical error, might be responsible for some of this, but is there a workaround? Am I doing something fundamentally wrong? Is there a better way to rig such a system (without resorting to scripting, preferably)?

Cheers, I.

$\endgroup$
1
$\begingroup$

If I understand correctly, you need to move the nozzle and update the cube's Z position accordingly. I have tried to do it by the way you describe (Distance limit constraint and Z restrain for each cube) but it looks like it only updates the position of 2 cubes while ignoring the third one. This is probably because the solution equation for the 3 of them (the intersection point of the 3 spheres) is an exact number, and Blender can't calculate it at that precision, as you described.

I've managed to make the Z position of the cube driven by the coordinates of the nozzle, and calculate the relative height with Pythagoras' theorem.

Driver configuration

It's basically a 2-part Pythagoras, one for the projected distance on the XY plane with the difference of the nozzle's and cube's X and Y positions, and one for calculating the cube's Z value, considering the previous calculated distance and the arm length (which I assumed as 5 here, hence the 25 value (5^2)). If you need a better explanation, I'll gladly help.

Here is the .blend file.

$\endgroup$
2
  • $\begingroup$ I forgot to mention, if you move the nozzle too far from one cube, it may lock to 0. To undo this just do Control + Z on any operation, and make sure that the solution is possible, I don't know how to update the driver calculation. This could be prevented by limiting the cube's Z height, but the methods I tried didn't work. $\endgroup$ Apr 7 '20 at 2:51
  • $\begingroup$ Thank you kindly for the detailed answer. My problem, however, is precisely the opposite: I'd like the cubes' positions to drive the nozzle's ("so that, whenever one of them moved, the nozzle would position itself accordingly"). It is certainly possible to script it as a driver nonetheless, but I've found that, at times, drivers are a bit unresponsive, do not automatically update their dependecies, etc. Considering that the constraints approach is leading me nowhere, however, I think I'll give drivers a go. Thank you for your time! $\endgroup$
    – impresso
    Apr 7 '20 at 14:14
0
$\begingroup$

Edit: I believe I got things precisely backwards. Which is a shame, because I actually already deleted the right answer, because I thought I got it backwards, even though I got it right... I'll leave the backwards answer first, then provide the reverse version afterwards.

You want the "cubes" to maintain a fixed distance from the nozzle, and to maintain a specific, fixed, world XY position. And your later comments indicate you want to drive this from the position of the nozzle, rather than driving the position of the nozzle from the "cubes". Is that correct?

What you are saying here is that you want each cube to lie at the intersection of the surface of a sphere centered on nozzle, and a line running in the world Z. You can find this value (actually, sometimes, a pair of values, sometimes no value) with drivers. If you look for the equation of the intersection of a sphere with a line, you'll get what you want. For cases with multiple solutions, you'll probably want to use the solution with the greatest Z. For cases with no solution, well, like the doctor says, don't move your arm like that.

But you can also approximate it, to any level desired, by using live boolean modifiers and shrinkwrap constraints.

You can't make the literal surface of a sphere (or if you can, you can't boolean it), but you can give a sphere a very thin solidify modifier. Again, you can't boolean a line, but you can boolean a very thin cylinder. The cylinders should be unparented (or possibly parented to an armature root bone) while the sphere should be parented to your nozzle. Each cylinder can have a boolean modifier targeting the sphere, on intersect mode. (I used "exact" here but "fast" should be perfectly fine.) Then, you can simply shrinkwrap the "cube" bones to these meshes to acquire the intersection of a line and the surface of a sphere:

enter image description here

Obviously, these meshes should have visibility disabled for renders. They exist only for rigging purposes. The quality improves as you use more vertices for your sphere, thinner cylinders, and a smaller thickness for your sphere's solidify modifier. Again, notice, there are two solutions for each cylinder; my bones prefer the top solution, which I think is what you'd want, just by virtue of having a rest pose relatively high in the world Z.

Edit/postscript: I now believe you are looking for a solution where the cubes drive the nozzle. That can be done using the same techniques, it's just, in this case, you're looking for the intersection of three spheres, each centered on one of the cubes. However, there are still multiple solutions to this problem-- ranging from zero solutions, to one solution, to infinite solutions.

In this case, you parent a sphere to each cube's bone, and then boolean intersect it, serially, with each of the other two. Every sphere should get a solidify modifier so that you acquire the intersection of their surfaces. When you shrinkwrap the nozzle to this surface, you will acquire a valid solution. In order to prefer the lowest solution, you can shove the nozzle off to Z = -1E29 or so before shrinkwrapping if you'd like....

enter image description here

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.