Trouble meeting specific constraint conditions with spheres

I am attempting to model two spheres (eventually more) and have some specifications for their relationship.

  • They should always remain a set distance apart from each other.
  • They should always maintain the same orientation with each other. To see what I mean by that, consider placing one sphere at the origin and another sphere above the first some distance along the z-axis. If I rotate either sphere, Condition 1 should continue to hold, while the sphere not being rotated should move (translate) so that it maintains its position relative to the rotating sphere. In other other words, the spheres do not have arbitrary surfaces. The closest points on the spheres need to remain such when either sphere rotates.
  • Lastly, they should be free to rotate about the axis which defines the distance between them, so that Condition 2 only holds for rotation away from the direction axis between the two spheres.

I hope the explanations make sense, especially Condition 2, since I felt I had to reword it a few times. I’m pretty sure I can accomplish Condition 1 several ways. First, I could use the ‘Child Of’ constraint and only lock in location. Second, I could use the ‘Copy Location’ constraint. Third, I could use the ‘Limit Distance’ constraint. This seems like it may be best because it specifically dictates exactly what I’m looking for, particularly with the ‘Clamp Region’ set to ‘On Surface’. There are some problems, however.

The relationship is not two-way. If I attempt to grab and move the sphere with the applied constraint, it will only roll around the surface of the other sphere. This is understandable, although it would be nice if the other one just moved accordingly and kept the appropriate distance. With the same constraint applied to the other sphere I then am stuck with not being able to grab and translate either sphere, although they do certainly keep the same distance by just rolling around on each others’ surfaces. This is actually fine for now, but if anybody has any pointers on getting a bit more flexibility I am listening.

So next comes Condition 2, where I am largely lost. Consider having the two spheres, with the elevated second sphere having the applied ‘Limit Distance’ constraint as described above. The first sphere, at the origin, has no constraints applied. [A weird observation: when removing the test constraint from the first sphere, subsequent grabbing and translating of the first sphere does not make the second sphere move, but when grabbing and translating the second sphere, its motion is still limited to the surface of the first. Deleting and reapplying the constraint to the second sphere restores normal operation. Any explanations?] With Condition 1 met, select the first sphere and rotate it. The second sphere does not move (nor should it at this point). What I would like is for the second sphere to translate around the first sphere as the first sphere rotates. Essentially, I do not want them to be able to roll about each others’ surfaces, but instead be locked at some point as though they were facing each other at all times.

It seems Condition 2 could actually be broken down into two sub-conditions. First, the second sphere should translate according to the rotation of the first. Second, it should also be rotating at the same time in order to stay “facing” the first sphere. Combining these does seem like the tricky part and probably why it’s so difficult to describe. Basically, that’s what I meant by “orientation”.

I am aware of the ‘Track To’ constraint. Whether I am misusing it and therefore not getting my desired result or if there is a more appropriate constraint to use, I am not sure. I am confounded by the ‘To’ and ‘Up’ options. I assume the ‘To’ axes refer to the local axes of the object that I am applying the constraint to, but I cannot fully tell if that is right. For instance, If I apply the ‘Track To’ constraint to the second sphere, then ‘Z’ is the default ‘Up’ value and ‘Y’ is the default ‘To’ value. I am then able to select ‘X’ and I can see the local x-axis of the constrained second sphere point to the first. Returning to ‘Y’ points the local y-axis towards the first sphere. But selecting ‘Z’ keeps the local y-axis pointing to the target but rotates the second sphere 180 degrees about its local y-axis. A similar situation occurs if ‘X’ is ‘Up’ but even more confusing, if ‘Y’ is ‘Up’, then all three local axes point to the target when selected in the ‘To’ field. What in the world is going on? Since I haven’t explicitly asked it yet, what exactly is ‘Up’ anyways? Changing the selection makes the local axes flop around but there is nothing consistent that I can tell which would indicate a common “up” direction. Intuitively, I would expect it to be in the positive global z direction but nothing points that way ever.

The closest I can get to what I am trying to achieve is to apply Condition 1 as described above, then apply ‘Track To’ to the second sphere, target the first, select ‘Target Z’ (although I have no idea what it is doing) and leave ‘Z’ as the ‘Up’ field and ‘Y’ as the ‘To’. Then, if I grab the second sphere and translate it, it rolls around the first sphere (maintaining the correct distance - Condition 1) and always faces it. This is the correct behaviour, except that the first sphere does not continually “face” the second as it moves. I need it to do this as well. Alternatively, at this point, I can grab the first sphere and translate it and the second sphere will move to stay in contact with the surface (maintaining the appropriate distance) and continually face the appropriate direction, but the first sphere stays in its original orientation, rather than rotating as necessary to continue facing the second. This must happen in order to meet Condition 2.

In order to do this I tried applying the ‘Track To’ constraint to the first sphere and targeting the second using the same settings as for the constraint upon the second sphere. This kind of works. If I then grab the first sphere and translate it, the second no longer maintains contact, although the first sphere does continue to face the second like I wanted. Unfortunately, the second sphere does not face the first either, as though both the prior constraints on the second sphere disappeared and only the new constraint upon the first sphere applies when I move it around. I then apply the ‘Limit Distance’ constraint to the first sphere and target the second so that both of the spheres have both the ‘Limit Distance’ and ‘Track To’ constraints targeting the other. I do also note that at this point the ‘Limit Distance’ constraint was applied to the second sphere first and then the ‘Track To’, while the reverse happened for the first. I am not sure how to interpret any order of operations within the constraint panel, so I am not bothering yet with this detail until instructed otherwise. Under these conditions I am very close to achieving Condition 2, yet one problem remains: when I grab the first sphere and translate it, it remains in contact with the second and also faces it appropriately, but the second sphere remains completely still and does not track (face) the first as it moves. Conversely, when I grab the second sphere, it behaves correctly, but the first acts as though it is not bound by its constraints anymore. How to get them both to do the right thing at the same time?

It seems to me that if I were to successfully meet Condition 2, Condition 3 would be met by default because rotation about the axis which both spheres are using to face each other will not cause a change in distance, nor would it cause a change in their orientation towards each other (by definition of rotation about that axis). The only trick I could think of is that perhaps this behaviour would be effected in some unforseen way, but since I’m not there and that hasn’t happened yet, I’m not too worried about it.

If you bothered to read through this entire thing, I thank you. May it not have wasted your time. Assistance with any of the quandaries, confusion, etc. is appreciated so that I can actually learn about Blender. However, the main question of the post is highlighted for clarity.

I should also point out that I am totally open to completely alternative ways of achieving what I am trying to do. For instance, I can imagine placing some invisible object (maybe a line with vertices at the center or surface point of each sphere) to which I can define relationships/constraints rather than being stuck with just the spheres, if doing something like that would make it all more flexible or easier in the long run. Involved or tedious is ok, if it works better.

Blender 2.58.0
Linux Mint 12, 64b

Blender 2.63.0
Windows 7, 32 & 64b

It is generally not possible to have two objects whose constraints transform each other in the same channel. Trying to use two “limit distance” constraints makes Blender see that A’s location depends on B’s location, which depends on A’s location, which depends on B’s location… It’s a circular dependency. Similarly, it is not possible to have a set of gears that can be controlled by grabbing and rotating any random gear; there is one and only one place to control the one-dimensional rotation of all the gears on the system (the “root” gear, or whatever all gears’ rotations are driven by.)

As I understand your description, I think the attached file might show one way to meet all three conditions. The price is that the whole system cannot be manipulated in any particular way; rather, the location of sphere A, the orientation of the axis running between spheres A and B, and the rotation around that axis of A, are all set by the location, x- and y- rotation, and z-rotation of sphere A, and the rotation around the axis of sphere B relative to sphere A is set by the z-rotation of sphere B. Simply, sphere A is the parent of sphere B, and sphere B is only free to rotate around its z-axis, and not translate locally at all.

Thus the two spheres always remain a set distance apart from each other, always maintain the same orientation with each other (the north pole of A and the south pole of B are always pointing towards each other,) and both spheres are free to rotate around the axis between their centers, (though you have to subtract A’s local z-rotation from B’s if you want A to spin on its axis but not B.)

But you can’t move A by moving B.

On Layer 2 are two more spheres (C and D) with a setup more like what you described, though using “damped track” instead of “track to” (only use “track to” when you need an axis to always point up, like a camera) The two spheres are distance-limited to each other, and satisfy all three conditions.
But try moving them around. Look at the short animation of C and D I included. Try translating them relative to each other. Look how erratically they move, how the same frame can look different depending on whether you approached it from the front or back, and how many refreshes can be needed for them to reach equilibrium! This is due to that circular dependency.

On Layer 3 is another attempt that I thought may have a better chance, but it suffers the same problems as Layer 2. The circular dependencies cause a lot of problems.

I hope this is of use to you.

Attachments

Two Spheres.blend (700 KB)

Thank you! Layer 1 is pretty much exactly what I was looking for. Also, thank you for pointing out the circular dependencies. That makes much more sense. And the use of layers to illustrate the different cases was very helpful in seeing the various what’s and why’s. To that effect, I do have some observations I would like some clarification on.

I notice in Layer 1 that there aren’t any constraints at all and that appears to be the key difference between Layer 1 and Layers 2 & 3. I see in the Object tab of the Properties panel that there is an area for ‘Transform Locks’. Is there any fundamental difference between locking Location, Rotation or Scale here vs. applying a Limit Location|Rotation|Scale constraint or is this one of Blender’s many feature redundancies (it seems like you can do everything in about five different places)? The other key thing you did, as far as I can tell, is that in the “Relations” area, you specified A as the parent. What is interesting to me is that this seems so much more general than using a Child Of constraint and it seems a better way to start.

I also appreciate you tilting A in an arbitrary direction because the other thing I noticed, which I think clears up a LOT of confusion I’ve been having with relationships/dependencies, is that once A is defined as the parent of B, the Location|Rotation|Scale fields of the Transform property appear to be completely relative to the local origin/axes/size of A. So Condition 1 is simply met by setting the appropriate values in Location. But part of Condition 2 is also met by this same act because if A ever rotates, B will rotate with it because its location is defined in terms of A’s local axes (which are rotating).

The second part of Condition 2 and also Condition 3 are addressed in the Rotation fields of the Transform Locks properties where you dictate that X and Y are not free to rotate, but rotation about the Z axis is allowed. I see one caveat at this point - even though the L|R|S fields of the Transform properties are defined relative to the local coordinates/attributes of the parent, the Rotation fields for the Transform Lock properties are defined according to the local axes of the child while the Location fields of the Transform Lock properties still define the allowable translation in terms of the local axes of the parent. Almost seems like an inconsistency, but like I said, your example has been exemplary in elucidating some of these finer points.

I have no qualms working down a chain of dependencies (to avoid the circular problem) but I do have one final question before I can really get started. It involves the free rotation of the child about an axis not coincident with one of the local axes. For example, Layer 1 works perfectly because the child is placed so that it is locked in position directly along the z-axis of the parent. The orientation is determined by locking X- and Y-axis rotation. Since the z-axis of the child is coincident with the z-axis of the parent, free rotation about the z-axis still maintains the correct orientation while meeting Condition 3. But say I were to place the child with a Location of z=1.5 and y=1.5. Since Rotation within the Transform Locks property is defined according to the child (even if it were the parent the same issue would still be present) but the axis of orientation (which can be seen by the dotted relationship line) is no longer a local or global coordinate axis for either object, how can I properly define Condition 3 and keep the correct orientation as per Condition 2?

…[the following is edited cuz I spoke too soon]

So I can get alignment along an arbitrary relationship axis but the free rotation (Condition 3) seems elusive.

Set the location of the child to z=y=1.5. Now look from the parent (A) down the relationship axis to the child (B). You’ll notice that it appears to bisect the positive local y- and z-axes of the child. Also notice that the child is in the same orientation as the parent because the Rotation fields in the Transform properties are all set to zero (meaning the child is not rotated at all from the relative rotation of the parent). So change the Rotation of the X field to 45 degrees. I may have been remiss in a previous statement about what the Rotation field does. It actually appears that it rotates the child about the local axis of the parent, except that it is more like a parallel axis passing through the child because the child does not swing about the parent but rotates in place. However, the child is not rotating about its own local axis - an important distinction. To see what I mean, now try setting the Y Rotation to 90 degrees.

With that said (and restoring the child’s rotation to only x=45), rotation about the relationship axis appears to be freed by unlocking the Y Rotation in the Transform Locks properties. When this is done, the green band around the child’s local y-axis appears, implying that it is free to rotate in that way. But it’s not. Any Y rotation of the child occurs about an axis parallel to the local y-axis of the parent, so this is extremely misleading (and why I came back and marked this as unsolved). Is there a way to perform rotation about the local axis of a child if the child’s local axes are not necessarily parallel to the parent’s local axes? Without having to compute those transform matrices by hand, of course. If not, I am capable of doing so, in which case maybe I’ll be writing my own constraints, but I was hoping Blender had this functionality in place.

I think this would be great material for a tutorial on how the child-parent relationship works, particularly for delineating the complex “whose location, rotation, etc. are we talking about?” issue. For example, that last bit on how child rotation occurs about an axis passing through the child but parallel to the parent’s local axis is quite the subtlety. If I ever get around to writing such a thing, may I use elements of your file (probably starting with your setup in Layer 1)? Due credit will of course be given.

Again, thank you for your invaluable help.

Yeah, sure you can. But the problem you ran into isn’t related to the parent’s axes; rather it is related to the order in which the rotations are performed. Notice the box below the Rotation panel: it says, right now, “XYZ Euler.” Hover your mouse over it and the tooltip will note that it is “prone to gimbal lock.” That’s not exactly the problem here, but you can see that trying to use these orientations carries problems.

In this case, your problem would be fixed by changing “XYZ Euler” to “YXZ” or “YZX”. The order of those letters means the rotations are applied as such (for XYZ): Rotate 45 degrees around the x-axis. Rotate n degrees around the ORIGINAL (before the x-rotation happened!) y-axis (so now the y-axis is no longer on or parallel to the axis through the centers), then p degrees around the original z-axis. This is done on Layer 1. Note that there is no longer a simple 1-axis rotation to spin A around the axis through the centers. If you want that, you should keep B on an axis of A.

If you want something to spin freely around an axis whose orientation is set with the other two rotation axes, the axis you want to be free had better have its letter come first (or before whichever other is used to define the axis, if you’re only using one. “ZYX” would have worked in the case you described."

Also, I would like to note that the parented object doesn’t know how its parent has transformed it; it still thinks it’s in the world space wherever and at whatever orientation and scale it was when you selected it, its parent, and hit ctrl+P. So suppose you’ve parented a cube to a sphere and turned the sphere upside-down. Increase the cube’s z-location by 1, and it actually goes down by 1! Spin the sphere in any which way and you will find that the axes spin with it. From the cube’s perspective, it’s as if the whole world has been spun about the sphere’s location.

This means that it’s also possible to do the rotation-around-the-y-axis-at-[0,1.5,1.5] relative to the parent without changing the order of rotation. Look at layer 2. C is the parent of D. Clear the rotation and location of C, and you will find that D is located at [0, 1.5, 1.5] in the world space, and rotated 45 degrees around the x-axis. But D says its location is still [0,0,0]! It still says it has no rotation! Even though the order of rotations is still XYZ, it can be spun around the y-axis and keep that axis parallel to the axis through the centers, because, as the file is, C has not been moved from where it was when I made it the parent of D. This can be used to interesting effect, but it can also be hard to keep track of, so take care.

And just to show that it is indeed possible to rotate around a child’s local axis that is not parallel to a parent’s axis, look at layer 3. There are two jacks with a similar parent-child relation as the cubes have been using, but Jack B is rotating around an axis in no way parallel to any axis of Jack A. Look at the order in which the rotations are applied; this explains how that is possible.

And something else that might be of interest to you is on layer 4. Here are two objects (jacks, not spheres, because it’s easier to see them spinning) rotating in a way that fits your conditions, except neither one is the parent of the other, but rather both are children of the empty (the little axes) between them. An empty is an object that has no size and cannot be rendered; it is mainly useful for defining coordinates, like position or rotation. Here both jacks’ z-rotations are entirely independent of each others, (no more having to subtract A’s z-rotation from B’s to keep B still!) and the location and rotation of the whole system is set by moving and turning the empty. If you play the animation, you’ll see how intricate stacked rotations can look, and you can achieve many more effects by choosing where to place the parents.

I hope that this can also be of use to you.

Attachments

Two Spheres 2.blend (971 KB)

My Blender on this comp seems to misbehave when I open the second file, so I’ll take a look at it on another. I know I want to see what you did with the empty because I might end up using that kind of object but I think I have figured out a pretty efficient way of programming the kind of constraints I need for building my structure just by seeing how you did layer one in the first file. I know the numpy module provides optimized matrix operations but I’ve had trouble getting this Blender to load it so I think I’m going to look for C functions I could offload the work to in the meantime. I’m going to look around for threads related to that issue though, since I know that’s a different topic. Thank you so much for you help. It’s exactly what I was looking for.