Sending the result of geometry.boundaryLength() to an attribute / constant

718
5
12-19-2021 03:49 AM
MattOlsen
New Contributor III

Hi all, 

I'm hoping this is an easy one - I can't seem to find documentation on this on the CGA resource page.

I'm trying to measure the lengths of two edges of a lot.

I can REPORT the lengths of two edges using the geometry.boundaryLength() function like this:

Lot-->

     comp(e) { 0 : Front | 1 : Side}

Front-->

     report("front", geometry.boundaryLength())

Side-->

     report("side", geometry.boundaryLength())

 

However, what if I want to use those two lengths in another rule?

The intention is to create an L shape, but I want to first measure the length of the edge and then subtract another constant (block_width) from that:

LShapedFootprint-->

    shapeL((MEASUREDFRONTLENGTH - block_width), (MEASUREDSIDELENGTH - block_width) {shape : LFootprint | remainder : NIL }

How do I get MEASUREDFRONTLENGTH and MEASUREDSIDELENGTH, to plug into this rule?

--

Any help is much appreciated!

 

 

0 Kudos
5 Replies
DavidWasserman
Occasional Contributor III

It is incredibly difficult to send information up the leaf hierarchy created by CGA rules. One way to approach this is precompute elements based on aspects of the start geometry, but for what you are trying that is not possible. I think an operation that might help is resetGeometry based on some conditional, but it might not function exactly as desired. 

https://doc.arcgis.com/en/cityengine/latest/cga/cga-reset-geometry-operation.htm

David Wasserman, AICP
Kevin_Z
New Contributor II

Is your polygon rectangular or odd shaped polygon?

if rectangular why not use scope.x and scope.y for the length and width.

if not rectangular can try n  use inner rectangle and setbacks to create a rectangle.

 

Also if you are using L as  footprints you could try and use the setback rules to adjust the position of the L tail into T shapes for variety.

 

@Anonymous User  probably have better ideas to achieve your goal on this.

MattOlsen
New Contributor III

Thank you both. 

The lots are likely to be rectangular and non-rectangular. Measuring scope.sx / scope.sz is definitely a good method to have available for the rectangular or near-rectangular (with inner rectangle) lots.

Ideally what I'm trying to do is create a rule for a building with a podium around the base (following the shape of the lot - I've got that), and then with a tower in one or two of the corners, as below:

MattOlsen_0-1639987401996.png

I've achieved this using a split operation - however you can see that this results in a split line on the podium running along the edge of the tower. If it was possible to 'merge' the shapes together in CGA that would solve the problem!

So the idea was to instead create an L for the podium shape and use the remainder of the L for the tower itself.

It's possible I'm going about this problem the wrong way - if you can think of a better approach to tackle it, it would be great to hear it!

 

0 Kudos
Clover4
New Contributor II

You can use the new "with" function to precompute the (scopes-blocks_widths) before using them in the same function L-shape.  I bolded "same function" because I have yet to understand if the "with"-"local variable" can exist outside the function it is created.  I think the text on it is confusing.   

Anyways, I created a function to comp 2 edges that was then called into the with statement (because comps cannot be done within the with statement directly), but the results I had were mixed (for your use case) or I would share how.  

0 Kudos
MattOlsen
New Contributor III

Thanks Brian - this seems like it should be possible based on what you are saying!

Intuitively, it seems I should be able to measure and store the length of an edge by writing something like..

attr FrontEdgeLength = geometry.boundaryLength(Front)

(where 'Front' has already been comp'd out from the original Lot shape)

But that doesn't seem to be how it works!

Below is my attempt at incorporating this idea - however I'm not clear on how the measurement of scope / length of those edges should be fed into the with function?

#getting the first 2 edges of the lot shape

Lot-->
           Shape
           comp(e)  { 0 : Front | 1 : Side }

Shape with ( x := [SCOPE / LENGTH OF FRONT EDGE] y := [SCOPE / LENGTH OF FRONT EDGE]) -->
           shapeL ( x - block_width, y - block_width) {shape : Footprint | remainder : NIL}

Footprint-->
           extrude(20)

 

0 Kudos