1
$\begingroup$

Following this answer curve intersection with volume in animation nodes, I've managed to create a spline which i use to distribute objects inside a volume.

Here is how:

enter image description here

But I still need to avoid having distributed objects along the spline when this one gets outside the volume along the gap :enter image description here

How can it be done? I've tried substracting those points (outside volume) from the ones that are generating the spline that is used to distribute the objects but as it now look obvious the spline will still be generated. So my second option is to do it inside the distribution objects loop but don't know how, any ideas? enter image description here

EDIT

AS @Omar Ahmad proposes finding inside points is straight forward using BVHTREE but this way we cant control the distance between the volume faces and the points.enter image description here

EDIT 2

@Omar Ahmad solution does the job but putting the tool to some tricky situations give inconsistent results like this ones:

enter image description here enter image description here

I'll be trying the other solution proposed, far more complex, which I'm already struggling to replicate.

$\endgroup$
2
  • 1
    $\begingroup$ Do you plan to animate either curve or volume, and if yes, how should the points behave then? E.g. If the gap increases, would the drawn points move closer together or would some of them suddenly disappear? And would the number of intersections stay constant or is it variable? $\endgroup$
    – binweg
    Commented Oct 4, 2018 at 9:26
  • $\begingroup$ Neither curve o volume are going to be animated but as I'm building this a tool for "parametric object placing" everything should be updated anytime something changes. The tool should work like this: from a list of objects I need to distribute them along an spline EVENLY only through the segments which are inside a given volume. All objects in this list (which can vary in length) have to be distributed and cannot be just hidden. Please ask if I'm not being clear. $\endgroup$ Commented Oct 4, 2018 at 11:30

2 Answers 2

2
$\begingroup$

This answer will be using the technique described in my answer here. After getting the parameters of the intersections, we prepend it with zero and append it with 1 representing the start and end of the spline respectively. The prepended list represents the starting parameters of the sub-splines between intersection points while the appended list represents the ending parameters. We can generate those sub-splines by trimming as follows:

Sub-Spline

We can then loop over the sub-splines, evaluate a point in the middle and see if it is inside the object or not, if yes, we append the spline:

Interior Splines

And that is it, you now have the interior splines which you can evaluate to get what you want. For instance:

Example

$\endgroup$
13
  • $\begingroup$ the problem with this method is that I don't have control over the distances between the intersection of the spline with the volume and the points. $\endgroup$ Commented Oct 4, 2018 at 8:12
  • $\begingroup$ @JuanManuelLynch Edited the answer, is this what you are looking for? $\endgroup$
    – Omar Emara
    Commented Oct 4, 2018 at 15:41
  • $\begingroup$ Sorry for the delay, I've been busy. Your solution does the job but after putting it into some stress situations I get inconsistent results. Check my edit. I'm going to try @binweg approach. $\endgroup$ Commented Oct 6, 2018 at 10:18
  • $\begingroup$ @JuanManuelLynch There might be a better simpler approach to all this, but it may not be as straightforward as the method we have been using. Will write an answer soon. $\endgroup$
    – Omar Emara
    Commented Oct 6, 2018 at 14:55
  • $\begingroup$ Oh that would be great, this solutions may not be perfect but just taking the time to reproduce and understand them is giving me so much knowledge, thanks. I´ll try my own approach also $\endgroup$ Commented Oct 7, 2018 at 11:18
1
$\begingroup$

My attempt at this problem is quite similar to Omar Ahmad's answer in that I calculate the spline parameter of the intersections – i.e. their positions along the spline's length in the range of zero to one – and use this value for the placement.

result
(Visible hollow copy only for demonstration purposes. Origial filled box used for calculations is hidden)

As a first step, I modify the Raycast loop of the node tree for the intersections to return the parameter and a boolean that gives information about the angle of normal and segment, and through that, whether the intersection is an entry into or an exit from the volume. In my setup, False means entry and True means exit.
The additional parameter spline length comes from a Get Spline Length node of the spline.

modified raycast

With an expression node list(zip(x, y)) I convert the two lists into one list of pairs, one for each intersection. For example

[(False, 0.2),
 (True,  0.5),
 (False, 0.6),
 (True,  0.9)]

To handle the spline's ends, I check for the first and the last point on the spline whether they are in the volume (BVH Tree > Is Inside Volume) and add a expression that will later interpret these points as additional entries or exits.
If there is always at least one intersection, one could invert the first and last boolean of the list, but checking Is Inside Volume also works when there is no intersection.

add start and end

This will end up as something like this:

[(True,  0),
 (False, 0.2),
 (True,  0.5),
 (False, 0.6),
 (True,  0.9)
 (False, 1)]

Similarly to the two slices vectors[:-1] and vectors[1:] in the tree to find the intersections, I create two slices tuples[:-1] and tuples[1:] and feed them into another loop.

tuple slices

The Create Splines loop checks whether each segment is inside of the volume based on the supplied boolean values, adjust the parameters of start and end by a given value to “prevent” (in some cases) the objects to appear directly at the wall or even clip into it, and check whether the adjusted segment is even long enough to hold any object.

create spline loop

While Omar Ahmad at this point continues to work with the parameters, I return a trimmed copy of the original spline (iff the spline is inside the volume and the segment is long enough).

The list of splines is fed into a final loop sample splines, along with a float number to set the average number of items to place per unit. From the loop's Evaluate Spline node we can extract location, tangents for the rotation etc.

sample splines loop place some objects

Using the segments' length and the ceiling function gives a rather regular distribution of objects, but it complicates things if you want a fixed number of objects. Maybe algorithms commonly used to assign seats to politicians after elections like the Sainte-Laguë method can be used, considering the lengths of the segments. Or you simply tweak the average until you're happy with the total. :P

The number of placed objects depends on the length of the segments:
offset gap

The distance of the first objects from each wall, or the average number of objects per unit can be adjusted, though the distance from a wall is calculated along the spline and might be misleading (a.k.a. wrong) for shallow angles:
more items and more space from wall
shallow angles

As mentioned above, the node tree should work for no intersections as well. For splines completely enclosed in the volume (with objects) or splines completely outside (no objects):
no intersection

Unfortunately, it won't work for cyclic splines.

N.B.: By default, the resolution of the Evaluate Spline nodes, which can be set in the advanced node settings in the properties panel of the node, is quite low. This resulted in an uneven distribution for me. Increasing the resolution solved this problem.

My .blend file for Animation Nodes v2.1:

$\endgroup$
5
  • $\begingroup$ this is huge! Ok I'm trying to replicate your solution, I even updated to v2.1, but as some of the nodes are collapsed is taking me a wile. For instance the "create pairs node" is self explicatory but somehow I cant find any vector list operation with two outputs. $\endgroup$ Commented Oct 6, 2018 at 10:52
  • $\begingroup$ My fault, sorry. Create Pairs is a group of the two list slices [:-1] and [1:] that also appeared in the find intersections node tree. I initially grouped them as I intended to reuse the group on the right. But that didn't look as good as originally thought as there was a type mismatch (Vector List vs Generic List) that would have required additional Convert Type nodes. I forgot to get rid of the node group. $\endgroup$
    – binweg
    Commented Oct 6, 2018 at 11:15
  • $\begingroup$ I noticed your two additional test cases and might add, that this answer also doesn't work for zero-width gaps, or more than one intersection per original segment. For the second test case, this might also have to to with the resolution of the Evaluate Spline nodes that I mentioned. Failing the first test case might be avoidable by not using Ray Cast but instead checking whether start and/or end of the segment are inside the volume (which could be done for both Omar Ahmad's solution as well as mine). $\endgroup$
    – binweg
    Commented Oct 6, 2018 at 11:29
  • $\begingroup$ even if this one was not the perfect solution it did what it was asked and also shares a big amount of knowledge, Im will also accept it as an answer. $\endgroup$ Commented Oct 7, 2018 at 12:51
  • $\begingroup$ Thanks, but apart from the variable number of objects in my answer, which is also implementable in the other answer, I too think that Omar Ahmad's answer is the superior one and I wouldn't mind if you accepted that answer. Props when it's due :) $\endgroup$
    – binweg
    Commented Oct 7, 2018 at 13:00

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .