-
Notifications
You must be signed in to change notification settings - Fork 128
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[BUG] path_sweep() weird anchors #1383
Comments
The anchor creating for path_sweep treats it as a generic polyhedron. Creating intelligent anchors for an arbitrary shape that we know nothing about is hard to do and yes, the anchors are often not great, especially if the shape isn't convex. If you have an algorithm in mind that you think will be better than the existing algorithms, you can propose it, but otherwise, we don't know how to improve this. You can probably get at least some of the anchors where you want them by fiddling with the centerpoint. Now for path_sweep we do have some additional information, so I could probably put a named anchor at the centroid of the two end faces in the case that Note that with current anchors, normals are always correct, defined as the normal of the face of the anchor point, or if on a corner or edge, the average normal of the faces that meet at the anchor point. Also not sure what you mean about "a bunch of extra anchor arrows drawn". There should always be 27, not counting any named anchors. |
It occurs to me that it's not even obvious how to define the size of a roundover for this situation given that the length of the path traced out by the profile can be enormously different for different points on the profile. |
I assume this comment was meant for my other issue #1384 ?
I certainly don't have an algorithm in mind, and I'm not even sure how the algorithm for generic polyhedrons work. But it would be great to be able to position and rotate children along any point of
Having anchors at the end faces would be great! For example, how to position a copy of the 2d polygon profile so it fits exactly at the end faces?
Ok. I'm confused why there was no anchor at the end face, and the top left edge has double anchors for "hull"? And that in "intersect" there was no anchor near the right end, but I understand now that those anchors are just drawn out from the center point until it intersects the outer surface? |
You have reinvented Because the hole is in a cylindrical ring it can actually be rounded and probably chamfered using Have you read the "VNF Attachables" section of the "Attachments Tutorial"? |
Interesting complication with end face anchors: if they point out then you can't just attach the 2d profile polygon at the "start" anchor because it will get flipped around. lerp_index() seems very close to lookup() so not sure about that. |
Oh, will give that a try!
However it's bent on both axis so it's rather a spheric surface. Would it be possible to project a path onto the surface of a VNF and get the resulting 3D path?
I'm not sure what this means, or why.
It's not the same, |
Ah, yeah, I forgot about the gentle curve the other way. You can probably get an OK result with bent_cutout_mask if you make the thickness of the mask thick enough so it doesn't cut a groove on the inside. Yes, that projection operation is possible in principle. There can be failures like a path that isn't connected if the VNF is concave. Above is the result of making anchors point out and then using attach to place the polygon on each end. Note that on the start end, the polygon is flipped. The triangular protrusion is on the wrong side. It would work if I had the "start" anchor pointing toward the interior of the object---backwards. Yes, lookup isn't exactly the same thing. |
Is there a function for this already? I think it could be useful. Something like
Ah, I see. Wouldn't an |
No, there is no projection function written. It's possible in principle, but difficult in practice. I would think you would take the vnf, path, and projection direction. Not sure if you return all connected components or just the closest one? Probably have to return all because closest feels like it might not always be well defined. Feel free to write it. :) The closest existing code to that kind of projection is in join_prism(), but it's limited to a prism, not an arbitrary VNF. I think the answer is basically I'm not sure about adding other anchors that are along the path. There's not an obvious, clean way to do that. Anchor names all need to be text strings computed when the object is made, not when the anchor is used. |
Another question is whether there should be two anchors at each end, one at the origin of the profile and one at the centroid of the profile. |
I see. Unfortunately that's a bit beyond my skills I'm afraid. :)
The idea was that |
So the idea is that
|
Yes, pos_along() would take the position as a factor between 0.0 and 1.0, or optionally an actual position (using closest_point or something), to get the corresponding index into $transform and apply it with multmatrix(), which would make the child objects positioned and rotated to the slice origin. From there the user can do position() etc to use the anchors of that slice, if pos_along() also forwards the attachable() stuff like $parent_geom and $parent_size. So one could do something like |
"start" and "end" anchors are now available in path_sweep, as well as $transforms and $scales. |
Problem is that the 2d anchors mean things anchor in 2d. That's why orientations are wrong.
The above works. Problem is you can't set h=0 to create 3d anchors to a zero height extrusion, so the code needs to be examined to fix that to make this work properly. Another thing: it's invalid math to lerp between transform matrices. The error is probably small if there's not much rotation between them, but generally not a valid practice. More seriously, there's a nasty complication having to do with scaling. If scaling is used, the surface isn't parallel to the path, and all the anchor orientations will be wrong. I'm not sure of an easy way to fix that one. It may be easiest to write an entire new pair of attachable methods in order to address this whole situation. |
A simple example of catastrophic failure of lerping a transformation is to lerp between identity and xrot(180). Right answer is xrot(90). But lerp will give you something rather different. Maybe you have the base shape rotated differently. I have it like this: in which case the LEFT and RIGHT anchors are going to be aligned with the path_sweep normal. The BACK and FWD anchors will be the other normals. The TOP and BOT anchors will point along the shape inside of it. What remapping of anchors are you suggesting? There is no natural "top" for a path_swept object. Consider the case of something with twist=1200. One could imagine trying to remap TOP and BOT to be the same as FWD and BACK, like happens in 2d. The reason I pass Note that in the case of scaled sweeps, the anchors are correctly positioned but their direction is incorrect. It will be normal to the path instead of normal to the swept surface. This complication is basically the blocker at this point for implementing this. I'm not sure what's gained by going to extra effort to discard the diagonal anchors. Maybe they are sometimes useful? If not....don't use them. Remapping TOP and BOT does mean you can't use them at the end slices. |
Oh, yes my base shape is: So from the POV of the base shape, BACK makes sense of course. But when looking at the sweep it's a bit confusing. I pass Regarding interpolating between transforms. It sounds like it should be possible by decomposing it first: https://stackoverflow.com/questions/3093455/3d-geometry-how-to-interpolate-a-matrix |
See rot_decode and rot_resample. The problem with saying "this direction was weird" for your case is that if you reorganize things to "make sense" for your case then they won't make sense in some other case and also won't be understandable because an arbitrary modification was applied to rationalize everything for your case. Could be quite common that normals point outwards, for example. In any case, as I have said, the scale thing is the killer problem for doing this, not the transform interpolation or any other matter. Probably needs an entirely new anchor type written that takes some kind of scale information and the pair of slices at each end, or maybe the transforms for each end. Maybe it's possible to adapt what's there already? But it's decidedly nontrivial. |
Great! So it should be possible to make a generic
Understood.
Would it be an alternative to have an intermediate implementation that works for all the cases where one does not use scaling? |
No, the transform interpolation only works for rotations. I struggled to find a more generic way to interpolate between transformations and was not successful. I wrote code to do eigenvalues in OpenSCAD, thinking that matrix powers would then enable this capability, but it turns out a bunch of common transforms aren't diagonalizable, so it doesn't work for those cases. The existing method doesn't even work for scaling. It also happens that the "natural" interpolation for scaling may not be what people want---it is exponential rather than linear. You're suggesting that it gives an error if scale is not 1? Intermediate implementations have a tendency to become the permanent implementations. |
Perhaps https://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToQuaternion or http://callumhay.blogspot.com/2010/10/decomposing-affine-transforms.html could help? however in this particular case there’s no reason to decompose it, since path_sweep is producing the transforms and could as well save them in separate arrays $sweep_translations, $sweep_rotations, $sweep_scales that can easily be interpolated. Scales should not be applied to the children, only to the region used to produce the anchors. |
It's trivial to separate translation from other parts of the transform, and since the current code supplies the scales you can back out the unscaled transforms. Note that a rotation and translation combined is actually just a rotation about a point other than the origin. The linked code only handles rotations. |
Code To Reproduce Bug
Expected behavior
I would wish to get usable anchors with correct normals, so that children could be positioned for example flush to the ends or sides.
Screenshots
For example with "intersect" the RIGHT anchor is nowhere near the actual end of the shape, and none of the anchors are centered on their sides. And there's a bunch of extra anchor arrows drawn:
Here's how "hull" looks, also a bit weird and not very usable.
The text was updated successfully, but these errors were encountered: