Welcome to the Onshape forum! Ask questions and join in the discussions about everything Onshape.
First time visiting? Here are some places to start:- Looking for a certain topic? Check out the categories filter or use Search (upper right).
- Need support? Ask a question to our Community Support category.
- Please submit support tickets for bugs but you can request improvements in the Product Feedback category.
- Be respectful, on topic and if you see a problem, Flag it.
If you would like to contact our Community Manager personally, feel free to send a private message or an email.
evDistance can't resolve entities
joshtargo
Member Posts: 269 EDU
trying to find the smallest bounding cylinder that can enclose bodies. user gives direction.
attempting to "close in" on shadow curves with evDistance, but it's failing.
0
Answers
So, your println(shadowCurves) shows a result, but shadowCurves is a query…you need evaluateQuery to see if the query is empty (or just use isQueryEmpty). Because that is most likely what your issue is, shadowCurves is empty, because you aren't generating new curves with the split.
If your method is going to be using a shadow, and then fitting a circle to that, you would be better off trying opCreateOutline. Its not a documented function, so proceed with caution. I write about its use in my blog.
But if the user is helping to define direction, you could also just use an axis and evDistance → maximum.
If you do an axis as side 0, the body as side 1, the maximum distance is the minimum radius for a cylinder.
You could either have the user give the center line of the cylinder, or if the part is somewhat symmetric, use an approximate centroid and a provided direction as your axis.
Custom FeatureScript and Onshape Integrated Applications
@Caden_Armstrong evDistance with maximum doesn't work with lines or an axis, also, figuring out where to put that line would be tricky.
ah you are right, forgot about that.
Do the inverse. Make a cylinder sheet body larger than your input, and the find the minimum distance between the cylinder and your body. Then find the distance between the axis and the found point to find the radius.
…that should be equivalent. And just center it on the body's centroid.
Custom FeatureScript and Onshape Integrated Applications
the centroid, even if it was the 2-dimensional projected centroid, is not the center of the smallest circle that can enclose an arbitrary shape. I don't know if it's even deterministic, or if i need to creep up on it iteratively.
@Caden_Armstrong I gave up for now on having it shrink to fit, it's non-trivial to figure out for an arbitrary group of objects, but it works for several simpler modes, and will likely be used just for cylindrical objects anyway.
link: Bounding Cylinder FS
This as the work for some 2d extremum search procedure. In my example you can find a few other examples of the optimizing features based on linear solver or optimizer:
https://cad.onshape.com/documents/ae329b71917362861fcd1689/w/03830fe502efd40ceb6c2ef5/e/bf4022337386226aa9f1305a
here is a sample of the approach of smallest bounding box feature which uses search in 3d angle space to find the optimal coord system:
I assume in your case the function that we search the minimum for should like like something like this:
you create the initial axis through the centroid of your body in the given direction, and define perpendicular X and Y offset values in the orthogonal plane. Then you should somehow construct the numerical function which depends on X,Y and has an extremum when the bounding cylinder through the given axis has the smallest radius. And this is the trickest part, because evDistance() will return you zero distance always when your cylinder is small enough to intersect any of the scope parts, and thus simple estimation function based on shrinking cylinder is helpless for extremum search.
If we assume that each of the selected parts might have a single touching point to the bounding cylinder, then we can say that the bounding cylinder axis position is found when the distances to each of the parts in the scope to the bounding cyl surface are equal and non zero values. The cylinder should be large enough to not intersect any of the parts.
So your problem can be redefined as the search of the minimum of the functions which takes X, Y numeric values and returns some some synthetic value, my guess is that the good enough estimation value might be constructed as the summ of squared differences between each distance to the body and the smallest distance. If 'di' is distance to the body 'i' and the 'dmin' is the min value of all 'di' then
estimation = summ_for_all_i((di - dmin)^2);
Try to play with it and maybe you will be able to derive something useful from these ideas
@Konst_Sh I think it's trickier than this. I can't assume that each selected part will only touch the cylinder once, or even at all, and there doesn't seem to be a good way to even project the outline of the parts on to 2D to make it simpler that way, or to do it using sketch constraints. it's a hard problem. i reverted to just having a few simple modes, rather than working on auto-shrink.
There was this really thorough Calculate Bounds feature a while back. I suspect it'll either already do what you're after or be a great code reference.
I think, I was able to find some neat approach to this problem. We can create the projection profile, of the bodies to plane, perpendicular to the selected direction, and if we find the two most distant points on this profile then for the most cases the center of bounding cylinder will be located right between those points. Then the trickest part will be to find the first of those points, because the second can be found just by evDistance between the first one and the profile edges by setting "maximum": true. So the first point is found with optimizer function which looking for a point from which the max distance to the profile is on the extremum.
https://cad.onshape.com/documents/ae329b71917362861fcd1689/w/03830fe502efd40ceb6c2ef5/e/bf4022337386226aa9f1305a
Having a situation where the two furthest projected points make the smallest enclosing circle is possible, and relatively easy, to implement, but it is very possible that three points would be needed, and then it gets difficult to do fast (brute force is easy, but even 16 points can take 2.5 seconds, which is unacceptable as part of a part studio regen).