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.
Why is the coordinate system of a cylindrical face centered at a random position ?
dave_cowden
Member, Developers Posts: 444 ✭✭✭
When i select a cylindrical face, and then get its surface definition, I expect the resulting coordinate system to have its origin at one end of the selected face.
In this example, you can see this is not the case: the coordinate system origin is an an apparently random point along the axis:
https://cad.onshape.com/documents/fb2492dd151e6c82527a8b38/w/b099ffb6d8c3abcecc7942fa/e/da38c8a92c77ed9eec932465
When you build a cylinder by extruding a circle, the origin of the cylinder coordinate system is in the sketch plane. In this case, the cylinder was created by a revolve, and the coordinate system is not aligned with anything I can find it appears to be completely random. More importantly, it is not at either end of the cylindrical face, as I expect.
I am aware that the underlying surface definition ( a cylinder ) is infinite, and that its origin would not _necessarily_ need to align with the face. But this way of working makes it very difficult to find a coordinate system that lies at the end of the face, as I'd like.
As an example, I normally expect the origin of the underlying line associated with an Edge to be located at one of the ends of the edge. If it is not, I always know that parameter = 0 and parameter = 1 will correspond to the end of the lines. But neither of these are true with the result of evSurfaceDefintion for a cylindrical face. The resulting cys does not appear to be located at the end of the cylindrical face.
There are of course ways to compute the right location, but they both represent more work than it seems like it should be:
Approach A:
(1) get the face and get the coordinate system using evSurfaceDefintion
(2) compute evBoundingBox, with respect to the axis of the cylinder
(3) the center of the cylindrical surface is actually at the results of the bounding box Z boundaries.
Approach B:
(1) get the face and get the coordinate system using evSurfaceDefintion
(2) use evTangentPlanes with u,v=0,0 to compute a tangent plane at one end of the surface
(3) the center is the intersection of the normal of this plane and the axis of the cylinder coordinate ssytem
Both of these will work, but why can't the csys that's returned be at one end or the other of the cylinder?
In this example, you can see this is not the case: the coordinate system origin is an an apparently random point along the axis:
https://cad.onshape.com/documents/fb2492dd151e6c82527a8b38/w/b099ffb6d8c3abcecc7942fa/e/da38c8a92c77ed9eec932465
When you build a cylinder by extruding a circle, the origin of the cylinder coordinate system is in the sketch plane. In this case, the cylinder was created by a revolve, and the coordinate system is not aligned with anything I can find it appears to be completely random. More importantly, it is not at either end of the cylindrical face, as I expect.
I am aware that the underlying surface definition ( a cylinder ) is infinite, and that its origin would not _necessarily_ need to align with the face. But this way of working makes it very difficult to find a coordinate system that lies at the end of the face, as I'd like.
As an example, I normally expect the origin of the underlying line associated with an Edge to be located at one of the ends of the edge. If it is not, I always know that parameter = 0 and parameter = 1 will correspond to the end of the lines. But neither of these are true with the result of evSurfaceDefintion for a cylindrical face. The resulting cys does not appear to be located at the end of the cylindrical face.
There are of course ways to compute the right location, but they both represent more work than it seems like it should be:
Approach A:
(1) get the face and get the coordinate system using evSurfaceDefintion
(2) compute evBoundingBox, with respect to the axis of the cylinder
(3) the center of the cylindrical surface is actually at the results of the bounding box Z boundaries.
Approach B:
(1) get the face and get the coordinate system using evSurfaceDefintion
(2) use evTangentPlanes with u,v=0,0 to compute a tangent plane at one end of the surface
(3) the center is the intersection of the normal of this plane and the axis of the cylinder coordinate ssytem
Both of these will work, but why can't the csys that's returned be at one end or the other of the cylinder?
0
Best Answer

kevin_o_toole_1 Posts: 427You're right that the "Cylinder" type doesn't give any information about boundaries of the cylinder. The actual surface passed into evSurfaceDefinition may have had slanted or arbitrarily shaped ends, and it may not have even covered all 2pi radians of the circle (e.g. the surface of a fillet between two planes). The surface definition is internally stored as an infinite cylinder, and when the surface's boundaries change without changing the surface (after, say, you boolean subtract half of the cylinder), that internal representation is not updated.
One could argue that the "Cylinder" type should therefore not store a "CoordSystem" to represent its central axis, but rather should store some representation of an infinite axis without an origin. However, our view is that with Cylinders, Planes, Lines, etc. we are okay specifying more degrees of freedom than necessary if they provide a more consistent interface with familiar data structures (3D vectors and CoordSystems).
We realize this allows someone to shoot themselves in the foot by depending on something they can't really depend on, and its not obvious that one needs to do extra work (e.g. your approach A or B ) to guarantee certain invariants like a cSys guaranteed positioned on the edge of a cylinder.
Because of everything mentioned above, a solution for this would necessarily need to do extra computation calculating properties of the boundaries to give the right result with these invariants maintained. Moreover, people might have different expectations of where that cSys should be placed, and some people will just not care and not want us to do the extra computation.
If we were to solve this problem, I suspect we would want to break out evCylinder, evCone, evTaurus, etc. into their own functions like evPlane, and then have those functions take an optional extra argument to specify alignment, which could be one of CylinderAlignment.MINIMUM_END, CylinderAlignment.MAXIMUM_END, CylinderAlignment.CENTER_OF_BOUNDS, or CylinderAlignment.ARBITRARY. This way its not extra code to get a nonarbitrary position, and its more obvious from the interface what properties of the cSys are guaranteed, and what is arbitrary. To be frank, evPlane is in need of such options even more than evCylinder, with how much code needs to be written to find just a corner of a rectangle.
What do you think? Does this sound like a reasonable route to take if we were to tackle this issue?
In the mean time, I wouldn't say this change is coming soon, and your Approach A is roughly equivalent to what would be done for CylinderAlignment.MINIMUM_END anyway. In your position I would continue using that approach.5
Answers
One could argue that the "Cylinder" type should therefore not store a "CoordSystem" to represent its central axis, but rather should store some representation of an infinite axis without an origin. However, our view is that with Cylinders, Planes, Lines, etc. we are okay specifying more degrees of freedom than necessary if they provide a more consistent interface with familiar data structures (3D vectors and CoordSystems).
We realize this allows someone to shoot themselves in the foot by depending on something they can't really depend on, and its not obvious that one needs to do extra work (e.g. your approach A or B ) to guarantee certain invariants like a cSys guaranteed positioned on the edge of a cylinder.
Because of everything mentioned above, a solution for this would necessarily need to do extra computation calculating properties of the boundaries to give the right result with these invariants maintained. Moreover, people might have different expectations of where that cSys should be placed, and some people will just not care and not want us to do the extra computation.
If we were to solve this problem, I suspect we would want to break out evCylinder, evCone, evTaurus, etc. into their own functions like evPlane, and then have those functions take an optional extra argument to specify alignment, which could be one of CylinderAlignment.MINIMUM_END, CylinderAlignment.MAXIMUM_END, CylinderAlignment.CENTER_OF_BOUNDS, or CylinderAlignment.ARBITRARY. This way its not extra code to get a nonarbitrary position, and its more obvious from the interface what properties of the cSys are guaranteed, and what is arbitrary. To be frank, evPlane is in need of such options even more than evCylinder, with how much code needs to be written to find just a corner of a rectangle.
What do you think? Does this sound like a reasonable route to take if we were to tackle this issue?
In the mean time, I wouldn't say this change is coming soon, and your Approach A is roughly equivalent to what would be done for CylinderAlignment.MINIMUM_END anyway. In your position I would continue using that approach.
Thanks for the very complete answer. Indeed, I ended up doing option A.
In terms of how to handle it, I think you have represented the pros and cons well. I like your suggested strategy, except that I would not have the CylinderAlignment parameter be optional. Requiring the caller to make a decision is essential to avoid the confusion that exists now, where you get a random/meaningless csys that appears to be stable in many cases ( it tricked me very well ! )