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.
How to calculate distance across a surface?
chris_houser
Member Posts: 6 EDU
My goal is to write a script to add a hexagonal pattern of hexagonal tiles across a series of adjacent surfaces. However, I'm new to Featurescript so at an early stage.
Where I'm stuck at the moment is trying to convert from real-world distances to the "2d unitless parameter-space" used as parameters to evFaceTangentPlanes. I'd like the user to be able to specify something like 5mm, and for the script to calculate how much to add to the x or y of the 2d vector to move 5mm across the surface.
I figured out how to get the length along the curve of each perimeter edge, which is close:
You can see my attempts so far here. My document is a bit messy, both the geometry and the code. Let me know if cleaning it up would help answer my question. I started with the Surface Pattern script, and most of it's still there. I'm successfully creating an almost-hexagonal pattern of spheres, but still depending on Surface Pattern's parameters of number of repeats in the u and v directions, rather than being able to specify the distance between them.
Where I'm stuck at the moment is trying to convert from real-world distances to the "2d unitless parameter-space" used as parameters to evFaceTangentPlanes. I'd like the user to be able to specify something like 5mm, and for the script to calculate how much to add to the x or y of the 2d vector to move 5mm across the surface.
I figured out how to get the length along the curve of each perimeter edge, which is close:
<div>for (var q in evaluateQuery(context, qEdgeAdjacent(definition.Face, EntityType.EDGE))) { </div><div> println("len: " ~ evLength(context, {"entities": q}));<br></div><div>}</div><div></div>
In particular, evLength's distance along a curve is like what I want but not along the edges, rather along the curve of the surface in whatever direction evFaceTangentPlanes's coordinates run.
I tried to figure out how to get a coordinate system from the surface, figuring I could then use coordSystem conversion functions like toWorld and fromWorld, but I don't know if that would work, and could figure out how to get a coordinate system anyway.
Anyone have any ideas?
I tried to figure out how to get a coordinate system from the surface, figuring I could then use coordSystem conversion functions like toWorld and fromWorld, but I don't know if that would work, and could figure out how to get a coordinate system anyway.
Anyone have any ideas?
You can see my attempts so far here. My document is a bit messy, both the geometry and the code. Let me know if cleaning it up would help answer my question. I started with the Surface Pattern script, and most of it's still there. I'm successfully creating an almost-hexagonal pattern of spheres, but still depending on Surface Pattern's parameters of number of repeats in the u and v directions, rather than being able to specify the distance between them.
Tagged:
0
Best Answer
-
chris_houser Member Posts: 6 EDUThe ratio of surface-parameter distance to 3d world distance is not constant across the surface. Moreover, I don't think it's geometrically possible to get exactly what I want.
However, I may be able to get close enough. I don't plan to actually apply hexagonal tiles to any spheres. This is what I have so far:/** * Estimate the 3d location of a point across a surface in a given vector direction. * @param face {Query} : Surface across which distances will be estimated * @param start3d {Vector} : 3d world coordinate of the starting point from which to step (should be a point on the surface) * @param start2d {Vector} : 2d unitless vector corresponding to the start3d point * @param step2d {Vector} : 2d unitless vector, a direction and an initial guess for the final return step * @param target_distance : desired length from starting point to the point this function will return. */ function surfaceStep(context is Context, face is Query, start3d is Vector, start2d is Vector, step2d is Vector, target_distance) { var next_tan_plane; for (var i = 0; i < 3; i += 1) { next_tan_plane = evFaceTangentPlane(context, { "face" : face, "parameter" : step2d + start2d }); debug(context, start3d, next_tan_plane.origin); var step_norm = norm( start3d - next_tan_plane.origin ); println("dist: " ~ step_norm ~ " target: " ~ target_distance); step2d = target_distance * step2d / step_norm; } return {"step2d": step2d, "target": next_tan_plane}; }
That could be cleaned up quite a bit: maybe more convenient parameters and using a target epsilon (distance error) rather than hardcoding 3 loop iterations. Anyway, I'm using that to compute step sizes near the origin on the surface, and using those step sizes to lay out a pattern of spheres along the surface. Here's that script applied to a few surfaces:
2
Answers
Is this only meant to be for planar surfaces?
IR for AS/NZS 1100
IR for AS/NZS 1100
- Some surfaces don't intersect a plane going through their origin.
- When they do intersect, it may not cover the full range from 0 to 1 of the surface parameter space.
So I think my next attempt will be to use evFaceTangentPlane to get real-world 3d coords of two points: the origin, and a point very close in the 'u' direction, like vector(0.1, 0). Finding the distance between those points should let me calibrate the surface parameter dimension to real-world distance. Do that again for the 'v' direction, and maybe that'll be enough info to space things properly. ...assuming the correlation is constant across the surface. :-PHowever, I may be able to get close enough. I don't plan to actually apply hexagonal tiles to any spheres. This is what I have so far:
That could be cleaned up quite a bit: maybe more convenient parameters and using a target epsilon (distance error) rather than hardcoding 3 loop iterations. Anyway, I'm using that to compute step sizes near the origin on the surface, and using those step sizes to lay out a pattern of spheres along the surface. Here's that script applied to a few surfaces:
IR for AS/NZS 1100