VB - Extracting Area from a Closed PolyLine

Hi All,
I have a grasshopper VB script which creates a closed polyline and I was hoping for some advise on how to extract the area.

I noted this link: Area of closed polyline which suggests the AreaMassProperties don’t work on a polyline - but i’m not sure what would? (or how to get my shape without a polyline…)

In a nut shell workflow is as follows:

  1. I run an iterative calculation, exporting a series of planar points representing a force area.
  2. I create a closed, planar polyline with those points.
  3. I want to extract the area and centroid of the closed polyline.

Important section of code is as follows:

' Generates the closed polyline.

Dim PolyPts as New List (of Point3D)

PolyPts.add(USBsPt)
PolyPts.add(PtB)
'PolyPts.add(PtX)
PolyPts.add(PtD67)
PolyPts.add(PtD)
PolyPts.add(DSBsPt)
PolyPts.add(USBsPt)

Dim Poly as new polyline (PolyPts) - WORKING UPTO HERE

' Calculates Area, centroid and Moments

UpArea = Rhino.Geometry.areamassproperties.compute(Poly,.001) - Not Working.

Could anyone advise on a workaround for this? Potentially convert to a brep, mesh or use some other Rhino Function?

Any help would be much appreciated :slight_smile:

You can triangulate it and compute the triangle areas. Here’s a Python script demonstrating how:

Thanks Anders, i will have a look at that tomorrow. I did start with calculating sub areas/centroids so I may be better to fall back on that.

Are there any other methods to extract a polyline area - or potentially mesh or generate a patch surface that the areamassproperties would operate on?

Cheers

A simple method would be to convert it to a curve using Polyline.ToNurbsCurve and then using AreaMassProperties.Compute to compute the area. I think the method in the script I linked to is plenty simple though, but it of course depends :slight_smile:

Thanks Anders - that’s very helpful :slight_smile:

Your method is straight forward, I agree. My - complication - is that my polyline is an amalgamation of upto 10 points, and these can change.

The project is using grasshopper to iterate an ‘uplift’ profile on a concrete dam.

I can independently set upstream load, downstream load, drain locations and effectiveness - then you have ‘cracking’ if the loads are to high.

As a result to triangulate I either need a whole series of If statements subject to which points are ‘true’ for a given run… or I can be lazy and build a polyline then convert to nurbs :slight_smile:

I’ll give it a go now, and confirm if it all works :slight_smile:

I do have another question, as some of my control points are identical in some circumstances - is there an easy way in VB to cull duplicates - like Rhino.geometry.Point3D.CullDuplicates?

I tried the above, and i’ve had some success (embedded in polyline component for example) - however I cant seem to create a new list, being the culled list?

Any advice would be appreciated.

Thanks again Anders, that worked a treat.

I declared a new Curve - then assigned that to Poly.ToNurbsCurve.

For any who come later final code (or at least the important bits):

' Declare Variables

Dim PolyPts as New List (of Point3D)
Dim Poly as polyline
Dim NrbCrv as NurbsCurve

' Adds points into the 3D Points array

PolyPts.add(USBsPt)
PolyPts.add(PtB)
' PolyPts.add(PtX)
PolyPts.add(PtD67)
PolyPts.add(PtD)
PolyPts.add(DSBsPt)
PolyPts.add(USBsPt)

' Creates PolyLine

Poly = new Polyline(PolyPts)

' Convert Polyline to Nurbs

NrbCrv=Poly.ToNurbsCurve

'Compute area and assign to output LDiag

LDiag = Rhino.Geometry.areamassproperties.compute(NrbCrv,.001).Area
1 Like

That would be one way, but the polyline class itself actually has several methods that sounds like they might be relevant to your modelling goals. Notably:

Glad it worked :slight_smile:

Thanks again Anders. With the way I am running my iterations, turned my version using point transforms, polylines and the mass commands is running to slow (1 second per solution - but this is part of what I intend to be a ‘live’ design package (for concept design upgrades on concrete dams) so i’ve had to re-write.

To speed things up i’ve dropped back to calculating areas. Managed to cut it back to two distinct geometry types and effectively breaking into rectangular or triangular sections - then calculating areas and centroids to take a moment and calculate a resultant.

For anyone else doing something similar in future - options I’m trying to calculate area centroids for i’ve simplified back to:

With Variables linking back to zones:
ZxA (Zone X Area)
ZxO (Zone X Centroid)
ZxM (Area moment of Zone X about PtA)

Code is as follows:

   if  Xx < Gx then ' Code for cracking US of the line of the drains. Output ResX verified for all possible Xx (At Heel, halfway to drain, at drain).

        ' Calculates drain function positions

        D0y = By + (Gx-Xx)*math.tan(math.atan((Dy-Xy)/(Dx-Xx)))

        if D0y > D100y then D100y = D0y ' Adjusts the drains 100% functional position if water level is less than drain head.

        D67y = D100y - (1-DrnEff/100)*(D100y - D0y)

        ' Calculates areas for each sub-area

        Z1A = (Ay-By)*(Xx-Ax)
        Z2A = (Ay-D67y)*(Gx-Xx)
        Z3A = (Cx-Gx)*(Cy-Dy)
        Z4A = (Dx-Gx)*(Dy-D67y)/2
        Z5A = (D67x-Xx)*(D67y-By)/2

        ' Calculates Offsets for each sub-area

        Z1O = B -(xx-Ax)/2
        Z2O = B - (Xx-Ax) - (Gx-Xx)/2
        Z3O = (Cx-Gx)/2
        Z4O = (Dx-Gx)*2/3
        Z5O = (Cx-Gx)+2*(Gx-Xx)/3


    else ' Code for cracking DS of the line of the drains.

        ' For this case, the crack extends past the drains and it is assumed the drains do not function.

        ' Calculates area of each sub-area

        Z1A = (Ay-By)*(Xx-Bx)
        Z2A = (Cy-Dy)*(Cx-Xx)
        Z3A = (Dx-Xx)*(Dy-Xy)/2
        Z4A = 0
        Z5A = 0

        ' Calculates offsets for each sub-area

        Z1O = B-(xx-Ax)/2
        Z2O = (Cx-Xx)/2
        Z3O = 2/3* (Dx-Xx)
        Z4O = 0
        Z5O = 0

    end if

' Calculates Moments about toe for uplift

Z1M = -Z1A*Z1O
Z2M = -Z2A*Z2O
Z3M = -Z3A*Z3O
Z4M = -Z4A*Z4O
Z5M = -Z5A*Z5O

’ Calculates resultant area and area moment for uplift.

    ' Calculates Sum of Vertical Forces for Uplift

    SumFU = -(Z1A + Z2A + Z3A + Z4A + Z5A)

    ' Calculates sum of area moments for Uplift

    SumMU = (Z1M + Z2M + Z3M + Z4M + z5M)

    ' Determines Resulting Location for Uplift

    ResXU = SumMU/SumFU