Welcome to the Onshape forum! Ask questions and join in the discussions about everything Onshape.

First time visiting? Here are some places to start:
  1. Looking for a certain topic? Check out the categories filter or use Search (upper right).
  2. Need support? Ask a question to our Community Support category.
  3. Please submit support tickets for bugs but you can request improvements in the Product Feedback category.
  4. 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.

Options

Efficient way to "re-align" a vector?

eric_pestyeric_pesty Member Posts: 1,530 PRO
This one is not critical as I figured out ow to get what I wanted... However the method I am using seems very rube goldberg-ish and I am just curious about the "proper" way to do this!

My scenario is that I have an vector defined as "global" x,y,z that I want to use to transform some bodies, however the bodies may be in a different orientation as they are aligned with a reference mate connector.

All I want to do is re-align that vector so that its xAxis is coincident with my mate connector xAxis (I don't actually care about the other axes as they are always zero). I already extracted a coordinate system from my MC. This is what I am doing currently:

translatevector = normalize(project(cSys.xAxis, translatevector)) * norm(translatevector); //extra convoluted way of re-aligning vector

So what's the "correct" way of doing this? I did try
translatevector*cSys
hoping it would know what to do but that didn't work so I worked around it.
Tagged:

Best Answers

  • Options
    eric_pestyeric_pesty Member Posts: 1,530 PRO
    Answer ✓
    Update!

    Yes, the toWorld(cSys)*translatevector is what I needed to do all along!

    In my defense, this is what the documentation says about "toWorld":
    When used in operations which place or move parts (like opTransformopPattern, or addInstance), this transform will (somewhat counterintuitively) move parts from the world origin and orientation to the cSys origin and orientation.
    I really don't have any "feel" for how the "*" works with transforms (it seems to work in reverse order to what I would expect as well as apparently being altogether backwards!)
  • Options
    Evan_ReeseEvan_Reese Member Posts: 2,066 PRO
    Answer ✓
    I spoke too soon...
    My convoluted method breaks past 90 (offset flips).

    And the toWorld way messes things up when I offset the MC, I basically only want the rotation part of the "toWorld" (I think...), to be continued...
    I'm a spatial thinker, so an image of your goal would help a ton. You might be running into the unpredictability of coordinate system orientations too. Because of math reasons, I don't think there's a way to make coordinate systems always show up in a way that's always intuitive and predictable to a user, so you may need to find another heuristic to determine the direction.

    Based on this description of your goal...
    Basically all I want to do is translate my bodies along cSys.xAxis by a distance equal to translatevector.x (which is really the same as the norm of translate vector x and y are both zero).
    It does seem like you have it right with your original thinking of:
    [a normalized vector for the direction] * [a length for the distance]

    Which might look something like:
    const translationVector = cSys.xAxis * norm(whateverVectorHasTheLength);

    Evan Reese / Principal and Industrial Designer with Ovyl
    Website: ovyl.io

Answers

  • Options
    Evan_ReeseEvan_Reese Member Posts: 2,066 PRO
    edited May 2023
    I may not understand exactly what you're after, but does this do anything for you?
    cSys.xAxis = translatevector;
    Maybe you need to normalize translatevector.

    You could also create a single transform that handles all of the translation and rotation with 
    const myTransform = transform(XY_PLANE, targetPlane);
    
    //or maybe even just
    
    const myTransform = toWorld(myTargetCoordinateSystem);
    Evan Reese / Principal and Industrial Designer with Ovyl
    Website: ovyl.io
  • Options
    Evan_ReeseEvan_Reese Member Posts: 2,066 PRO
    Also, sometimes doing things with vectors does just feel crazy convoluted (in my experience). If you're doing this kind of thing a lot, you could write a function that does it, and put that in a library.
    Evan Reese / Principal and Industrial Designer with Ovyl
    Website: ovyl.io
  • Options
    eric_pestyeric_pesty Member Posts: 1,530 PRO
    I may not understand exactly what you're after, but does this do anything for you?
    cSys.xAxis = translatevector;
    Maybe you need to normalize translatevector.

    You could also create a single transform that handles all of the translation and rotation with 
    const myTransform = transform(XY_PLANE, targetPlane);
    
    //or maybe even just
    
    const myTransform = toWorld(myTargetCoordinateSystem);
    Hmm, I don't think that first one would what I am trying to do as I wan to change translatevector's direction (not the cSys) and I would except this to re-algin cSys...

    Wouldn't the bottom options also modify the entire part studios reference planes?
  • Options
    eric_pestyeric_pesty Member Posts: 1,530 PRO
    edited May 2023
    @Evan_Reese
    I'm really not "fluent" in vector math so I'm basically using trial and error (emphasis on error) to get what I need!

    Basically all I want to do is translate my bodies along cSys.xAxis by a distance equal to translatevector.x (which is really the same as the norm of translate vector x and y are both zero).

    Looking at it now, I think I know where I went wrong!

    I actually started with just "translatedistance", then I realized I needed a vector for my opTransform, so I created "translatevector".

    It was only much later that I realized I had to realign my vector (when I noticed it didn't work if I rotated my reference mate connector) and I improvised from there until I ended up with this (which seems to work fine):

                var translatedist = -translate;
                var translatevector = vector(translatedist, 0 * inch, 0 * inch);
                translatevector = normalize(project(cSys.xAxis, translatevector)) * norm(translatevector); //extra convoluted way of re-aligning vector
    
                opTransform(context, id + "transform1", {
                            "bodies" : instanciatedBodies,
                            "transform" : transform(translatevector)
                        });

    I think this might actually be the way to do it (based on something I am doing earlier...): 

                var translatedist = -translate;
                var translatevector = vector(translatedist, 0 * inch, 0 * inch);
    
                opTransform(context, id + "transform1", {
                            "bodies" : instanciatedBodies,
                            "transform" : toWorld(cSys) * transform(translatevector)
                        });

    Or can I use it like this:
    translatevector = toWorld(cSys)* translatevector;
    ?

  • Options
    eric_pestyeric_pesty Member Posts: 1,530 PRO
    Answer ✓
    Update!

    Yes, the toWorld(cSys)*translatevector is what I needed to do all along!

    In my defense, this is what the documentation says about "toWorld":
    When used in operations which place or move parts (like opTransformopPattern, or addInstance), this transform will (somewhat counterintuitively) move parts from the world origin and orientation to the cSys origin and orientation.
    I really don't have any "feel" for how the "*" works with transforms (it seems to work in reverse order to what I would expect as well as apparently being altogether backwards!)
  • Options
    eric_pestyeric_pesty Member Posts: 1,530 PRO
    I spoke too soon...
    My convoluted method breaks past 90 (offset flips).

    And the toWorld way messes things up when I offset the MC, I basically only want the rotation part of the "toWorld" (I think...), to be continued...
  • Options
    Evan_ReeseEvan_Reese Member Posts: 2,066 PRO
    @Evan_Reese
    I'm really not "fluent" in vector math so I'm basically using trial and error (emphasis on error) to get what I need!
    I'm honestly not either. I was pretty much at zero knowledge of them going into Featurescript, and have since needed to dig into them for a number of the features I've made. It's starting to make some intuitive sense now, but I'm sure I still do things in a roundabout way a lot and I also do a lot of trial and error. This video series is a fantastic resource for it though.
    Evan Reese / Principal and Industrial Designer with Ovyl
    Website: ovyl.io
  • Options
    Evan_ReeseEvan_Reese Member Posts: 2,066 PRO
    Answer ✓
    I spoke too soon...
    My convoluted method breaks past 90 (offset flips).

    And the toWorld way messes things up when I offset the MC, I basically only want the rotation part of the "toWorld" (I think...), to be continued...
    I'm a spatial thinker, so an image of your goal would help a ton. You might be running into the unpredictability of coordinate system orientations too. Because of math reasons, I don't think there's a way to make coordinate systems always show up in a way that's always intuitive and predictable to a user, so you may need to find another heuristic to determine the direction.

    Based on this description of your goal...
    Basically all I want to do is translate my bodies along cSys.xAxis by a distance equal to translatevector.x (which is really the same as the norm of translate vector x and y are both zero).
    It does seem like you have it right with your original thinking of:
    [a normalized vector for the direction] * [a length for the distance]

    Which might look something like:
    const translationVector = cSys.xAxis * norm(whateverVectorHasTheLength);

    Evan Reese / Principal and Industrial Designer with Ovyl
    Website: ovyl.io
  • Options
    eric_pestyeric_pesty Member Posts: 1,530 PRO
    @Evan_Reese
    Yep, that's it! Thank you!

    It makes perfect sense (now that I know the answer...): I know that cSys.xAxis is the direction I want so I just need to make it the length I need!

    I think I briefly tried this but gave up when I saw that cSys.xAxis was just (1,0,0) and I thought well that's not helpful... But I think I just hadn't rotated my mate connector at that point (duh)!

    It's actually even simpler as the information I have to start with is actually just the distance! So all I need to do is:
    const translatevector = cSys.xAxis * translatedist;
    and it seems to work as expected at any rotation angle for any offset.

    All my ramblings from the last few days was me deciding we can't wait for custom fonts to happen and attempting to crate a feature specifically for the weird font we need to use regularly...

    Basically I use a MC for the bottom left corner reference and instantiate a bunch of surfaces (imported from an outside program) corresponding to each character in the string and keeping a running total of how far to move each one to the right (based on the character width and spaces before and after).

    The transform is the last step needed to change the justification and I already know the total length from my running total above.
    A bit late for images but here's what the baseline case looks like and a center-justified, offset MC, rotated>90deg showing up as intended!





Sign In or Register to comment.