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.

Center of Gravity Calculated with Featurescript

philipp_wehrphilipp_wehr Member Posts: 8 EDU
Hi Guys, 

I am trying to calculate the Center of Gravity (COG) of a 2D man (Picture). 
I worked with Solidworks Api and could figure everything out with the Macro Recorder. Sadly this feautre doesnt exist in Onshape and there are not a lot of Tutorials for Onshape. 
What i want to do in Feature Script is to calculate for all 3 Konfigurations the overall COG. Therefore I need the X and Y Coordinates of the COG  (Yellow Points) of each body segement.
Then I want to calculate with FeatureScript the overall COG. I have all the masses of the different Body Segments in the different Konfiguration Sizes. 
My question would be now: 

-How can I get all the X and Y Dimensions for the different Body Segments( Points) and how can I use this values further on to use them in a formula. 
-How Can I create different Points for the different Configurations. 
-Whats the best way to implement the different Mass Values for the different Configurations into Featurescript

I am thankful for every help, 
Greetings from Germany Philipp   



  • _anton_anton Member, Onshape Employees Posts: 34
    If I understand correctly, you need to select edges of a sketch, give them individual masses, and compute the overall centroid? You could do something like the following, if you don't mind entering masses manually.

    annotation { "Feature Type Name" : "My Feature" }
    export const myFeature = defineFeature(function(context is Context, id is Id, definition is map)
            annotation { "Name" : "Edges", "Item name" : "Edge" }
            definition.edges is array;
            for (var widget in definition.edges)
                annotation { "Name" : "Edge", "Filter" : EntityType.EDGE && SketchObject.YES, "MaxNumberOfPicks" : 1 }
                widget.edge is Query;
                annotation { "Name" : "Mass (kg)" }
                isReal(widget.mass, POSITIVE_REAL_BOUNDS);
            var acc = vector(0, 0, 0) * meter * kilogram;
            var totalMass = 0 * kilogram;
            for (var i = 0; i < size(definition.edges); i += 1)
                const centroid = evApproximateCentroid(context, {
                        "entities" : definition.edges[i].edge
                const mass = definition.edges[i].mass * kilogram;
                const weightedCentroid = centroid * mass;
                acc += weightedCentroid;
                totalMass += mass;
            const centroid = acc / totalMass;
            println("Total center of mass:");
            debug(context, centroid);

    Here, I'm setting up an array parameter, in which each entry is an edge and a mass (for simplicity given as a real number, multiplied by kilograms in the code). For each edge I'm getting a centroid, multiplying by its mass, and dividing by the total mass in the end for the total center of mass.
  • philipp_wehrphilipp_wehr Member Posts: 8 EDU
    Thanks for the reply. 
    That was not 100% what i was searching for. I want to select all Points ( not Edges) and then calculate for each Point X and Y Disatance to origin. That would help me out a lot. 

  • Jake_RosenfeldJake_Rosenfeld Moderator, Onshape Employees, Developers Posts: 1,640

    Edge midpoint selection can only be "woken up" if both edges and vertices are available selections for your feature.

    It is kind of hacky, but if you want this behavior what you could make the following changes:
    1. Change the "Filter" of widget.edge from "EnttiyType.EDGE && SketchObject.YES" to "EntityType.EDGE || EntityType.VERTEX".  
    2. Change the call to "evApproximateCentroid" to a call to "evVertexPoint" ( https://cad.onshape.com/FsDoc/library.html#evVertexPoint-Context-map )

    Unfortunately, though, the user will be able to select both edges and vertices, and if they select an edge it will fail.  This is because those points you want to select are edge midpoints, not real vertices that are always available in the system.  They way they are currently implemented, they are only available when both edges and vertices are selectable.

    Is there a reason that you prefer making your user select the edge midpoints manually, instead of having the user select the edges, and having the program figure out their midpoints?
    Jake Rosenfeld - Modeling Team
  • philipp_wehrphilipp_wehr Member Posts: 8 EDU
    Hi @Jake_Rosenfeld

     I don't want to select any edges. :smiley:
    I have a single sketch only with points. These Points have a specific position on the Lines, which i already configured (Picture).
    What i need now is to X Distance and Y Distance of each Point as a variable to further calculate my overall center of mass. 
    Thanks for all the help, 

  • philipp_wehrphilipp_wehr Member Posts: 8 EDU
    The X-Distance and the Y-Distance is Meauserd to the Origin. 
  • Jake_RosenfeldJake_Rosenfeld Moderator, Onshape Employees, Developers Posts: 1,640

    In that case it should be easy!

    First, alter the original script to have `"Filter" : EntityType.VERTEX && SketchObject.YES` to allow selection of those vertices. 

    Next, you will probably want to change definition.edges to definition.vertices (this does not have any geometric effect, it is just a variable name), and also widget.edge to widget.vertex.

    Finally get rid of the call to evApproximateCentroid in favor of something like:
    const pointPosition = evVertexPoint(context, { "vertex" : definition.vertices[i].vertex });
    // pointPosition is a world space vector representing the position of the vertex.  [0] = X, [1] = Y, [2] = Z
    const xDistanceToOrigin = pointPosition[0];
    const yDistanceToOrigin = pointPosition[1];

    Jake Rosenfeld - Modeling Team
Sign In or Register to comment.