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.

Perpendicular Vector

graham_lockgraham_lock Member Posts: 142 PRO

Hi

I'm drawing a sketch line on a plane which has its own coordinate system:

const lineEndPoints is map = skLineSegment(sketch1, "line1", {
"start" : vector(0, 0) * meter,
"end" : worldToPlane(sketchPlane, vector(dist.sides[0].point[0] / meter, 0, dist.sides[0].point[2] / meter) * meter) // point[0] is x, point[2] is y
});

I then need to draw a rectangle of a given size which has 2 edges perpendicular to that line, positioned at one endpoint, similar to:

I've been experimenting with perpendicularVector but haven't found how to make it work.

If this is the correct approach a quick example of its use in this use case would be greatly appreciated.

If this is not the correct approach how should I go about it?

Thank you.

Best Answers

  • NeilCookeNeilCooke Moderator, Onshape Employees Posts: 5,680
    edited October 8 Answer ✓

    perpendicularVector is for 3D vectors and there's no guarantee that it will be on your sketch plane.

    Best to do all the vector math outside of the sketch, draw the rectangle at the origin then transform it.

    FeatureScript 2473;
    import(path : "onshape/std/common.fs", version : "2473.0");
    
    annotation { "Feature Type Name" : "My Feature", "Feature Type Description" : "" }
    export const myFeature = defineFeature(function(context is Context, id is Id, definition is map)
        precondition
        {
            annotation { "Name" : "X" }
            isLength(definition.dx, LENGTH_BOUNDS);
    
            annotation { "Name" : "Y" }
            isLength(definition.dy, LENGTH_BOUNDS);
        }
        {
            const lineStart = vector(0, 0) * millimeter;
            const lineEnd = vector(definition.dx, definition.dy);
            const lineLength = norm(lineEnd - lineStart);
            const lineAngle = (definition.dy < 0 ? -1 : 1) * acos((lineEnd[0] - lineStart[0]) / lineLength);
            const angleTransform = matrix([[cos(lineAngle), -sin(lineAngle)], [sin(lineAngle), cos(lineAngle)]]);
    
            const boxWidth = 2 * millimeter;
            const boxHeight = 1 * millimeter;
    
            var rectangle = [vector(boxHeight, boxWidth), vector(-boxHeight, boxWidth), vector(-boxHeight, -boxWidth), vector(boxHeight, -boxWidth), vector(boxHeight, boxWidth)];
    
            for (var i = 0; i < size(rectangle); i += 1)
            {
                rectangle[i][0] += lineLength;
                rectangle[i] = angleTransform * rectangle[i];
            }
    
            const sketch1 = newSketchOnPlane(context, id + "sketch1", {
                        "sketchPlane" : XY_PLANE
                    });
    
            skLineSegment(sketch1, "line1", {
                        "start" : lineStart,
                        "end" : lineEnd
                    });
    
            skPolyline(sketch1, "polyline1", {
                        "points" : rectangle
                    });
    
            skSolve(sketch1);
        });
    

    Senior Director, Technical Services, EMEAI
  • NeilCookeNeilCooke Moderator, Onshape Employees Posts: 5,680
    Answer ✓

    You're over complicating it 😊 just do it in 2 sketches:

    https://cad.onshape.com/documents/6232edc86fa5b3933c9cc699/w/8a4b0f15bb93348c33e3d313/e/993f98802348cecb6d0640f2

    Senior Director, Technical Services, EMEAI

Answers

  • NeilCookeNeilCooke Moderator, Onshape Employees Posts: 5,680
    edited October 8 Answer ✓

    perpendicularVector is for 3D vectors and there's no guarantee that it will be on your sketch plane.

    Best to do all the vector math outside of the sketch, draw the rectangle at the origin then transform it.

    FeatureScript 2473;
    import(path : "onshape/std/common.fs", version : "2473.0");
    
    annotation { "Feature Type Name" : "My Feature", "Feature Type Description" : "" }
    export const myFeature = defineFeature(function(context is Context, id is Id, definition is map)
        precondition
        {
            annotation { "Name" : "X" }
            isLength(definition.dx, LENGTH_BOUNDS);
    
            annotation { "Name" : "Y" }
            isLength(definition.dy, LENGTH_BOUNDS);
        }
        {
            const lineStart = vector(0, 0) * millimeter;
            const lineEnd = vector(definition.dx, definition.dy);
            const lineLength = norm(lineEnd - lineStart);
            const lineAngle = (definition.dy < 0 ? -1 : 1) * acos((lineEnd[0] - lineStart[0]) / lineLength);
            const angleTransform = matrix([[cos(lineAngle), -sin(lineAngle)], [sin(lineAngle), cos(lineAngle)]]);
    
            const boxWidth = 2 * millimeter;
            const boxHeight = 1 * millimeter;
    
            var rectangle = [vector(boxHeight, boxWidth), vector(-boxHeight, boxWidth), vector(-boxHeight, -boxWidth), vector(boxHeight, -boxWidth), vector(boxHeight, boxWidth)];
    
            for (var i = 0; i < size(rectangle); i += 1)
            {
                rectangle[i][0] += lineLength;
                rectangle[i] = angleTransform * rectangle[i];
            }
    
            const sketch1 = newSketchOnPlane(context, id + "sketch1", {
                        "sketchPlane" : XY_PLANE
                    });
    
            skLineSegment(sketch1, "line1", {
                        "start" : lineStart,
                        "end" : lineEnd
                    });
    
            skPolyline(sketch1, "polyline1", {
                        "points" : rectangle
                    });
    
            skSolve(sketch1);
        });
    

    Senior Director, Technical Services, EMEAI
  • graham_lockgraham_lock Member Posts: 142 PRO

    Thank you so much for the example - exactly what I was looking for.

  • graham_lockgraham_lock Member Posts: 142 PRO

    @NeilCooke

    Hi @NeilCooke,

    I've integrated your example into a test document and it does exactly what I asked for, the box profile follows the edge of the curved face and is perpendicular to the line.

    Could you suggest the best way to make the profile follow the line as currently but be oriented such that it is tangent to the curved edge please?

    https://cad.onshape.com/documents/5ae9b4531272e0d2f135073c/w/bc3f6ab2b17a961efef1b4fd/e/14315dad3efc51b9f4fe8227

    Thank you.

  • NeilCookeNeilCooke Moderator, Onshape Employees Posts: 5,680
    Answer ✓

    You're over complicating it 😊 just do it in 2 sketches:

    https://cad.onshape.com/documents/6232edc86fa5b3933c9cc699/w/8a4b0f15bb93348c33e3d313/e/993f98802348cecb6d0640f2

    Senior Director, Technical Services, EMEAI
  • graham_lockgraham_lock Member Posts: 142 PRO
    edited October 12

    Thank you - that's very clean.

  • graham_lockgraham_lock Member Posts: 142 PRO
    edited October 13

    Hi,

    I inadvertently marked the original question as answered and couldn't see how to unmark it - is there a way?

    To continue with the help provided by @NeilCooke …

    I've created a test document which allows switching between tangential and perpendicular tracking.

    This has generated another question:

    1. Tangential tracking works fine if the curved edge is generated via a spline but if generated via an arc the profile is drawn outboard of the edge. This can be corrected by changing

    line 126:

    boxPlane = plane(edgeTangentLine.origin, -Y_DIRECTION, edgeTangentLine.direction);

    to

    boxPlane = plane(edgeTangentLine.origin, Y_DIRECTION, edgeTangentLine.direction);

    but then spline generated curves are incorrectly calculated?

    https://cad.onshape.com/documents/a210980f37f6eb8934643f1d/w/c438d98168a82355ea5d0764/e/f4d243419a7ec6ec132347ac

    Any further help appreciated.

    Thank you.

Sign In or Register to comment.