[027] Understanding Absolute Ratio Split (') in Esri CityEngine CGA

Learn to utilize the absolute ratio symbol (') in CGA split operations to divide shapes based on a normalized total length of 1.

This tutorial explains how the absolute ratio (') symbol works in Esri CityEngine CGA. Unlike relative split (~), it normalizes the split direction to a total value of 1, enabling consistent proportional subdivision regardless of actual geometry size. We explore its technical application in high-rise building facades and analyze how reference points shift in nested split operations.

What Is the Absolute Ratio Symbol (') in CityEngine CGA?

The importance of the split operation in CGA cannot be overstated.

It is important to learn various ways of using split while analyzing rules written by others.

Until yesterday, we covered the relative split symbol '~', which divides internal regions relatively.

Today, we'll explore how to split shapes using absolute ratios, where the length of the shape in the direction of the split is set to 1, rather than using relative proportions.

The symbol for splitting with an absolute ratio is '.

This method works by normalizing the entire split length to a value of 1.

Difference Between Relative Split (~) and Absolute Ratio Split (')

Let's look at the difference between ~ and ' while splitting the following figure.

Comparison of ~ and ' split symbols
img 1 : Initial comparison between relative split (Lot1) and absolute ratio split (Lot2)

The code is as follows.

Relative Split Example


Lot1 -->
    split(x){~1: A | ~2: B}

Lot2 -->
    split(x){'0.1: A | '0.2: B | ~1: E}

A --> color(1,0,0) #Red
B --> color(0,1,0) #Green
E --> color(1,0,1) #Purple

Line 2: Lot1 divides the total length of the split direction in a ratio of 1:2.

Line 5: Lot2 divides only 10% and 20% of the total length of the split direction.

How Absolute Ratio Splits Calculate Space

Looking at the results,

Split result comparison
img 2 : Visible differences in geometry subdivision

The difference is clearly visible. Lot1 divides the entire length of the split direction in a 1:2 ratio without any leftover space, while Lot2 divides only 0.1 (10%) and 0.2 (20%) of the total length and discards the rest.

Since this functionality exists, it is worth considering where absolute ratio splits become useful in practical modeling scenarios.

Practical Use of Absolute Ratio Splits in Building Facades

Let's assume a real-world application scenario. There is a high-rise building of unknown height. We want to separate the facade patterns according to the floor heights as follows: Set the 1st floor to 10m and color it red; from the 2nd floor, color the length corresponding to 50% of the building height in green, and the rest in blue.

Let's look at the code.


Building -->
    split(y) { 10: Floor1 | '0.5: MidSection | ~1: TopSection }

Floor1 --> color(1,0,0)
MidSection --> color(0,1,0)
TopSection --> color(0,0,1)

Line 2: After splitting with a fixed value of 10 and coloring it red, color 0.5 (50%) of the total length in the split direction in green, and the remaining area in blue.

Looking at the results...

High-rise building facade split
img 3 : Verifying the 50% proportional split on a building facade

Yes, we can confirm that the green section accurately occupies 50% of the total split length.

A point to remember is that while ~ changes its value based on the size of the remaining split area when used inside {...}*, ' is applied as a fixed value even when used inside {...}*.

Let's verify this behavior.

Facade Floor Distribution Example


Lot -->
    split(x) { '0.1: A | '0.2: B | '0.3: C | ~1: D }

Line 2: Split into 10%, 20%, and 30% of the total length and color them red, green, and blue, then color the remaining area in yellow.

Let's look at the results.

Proportional split result confirmation
img 4 : Confirming split subdivisions close to the expected absolute ratios

You can confirm that it was split close to the expected ratios. ' is not very difficult to use as it changes very little when used with other symbols. Since ' is a ratio relative to the total length in the split direction, it can be considered a fixed value.

How Absolute Ratios Behave Inside Nested Split Operations

Now, let's look at what determines the reference for '.

Look at the code below. This is a slightly modified version of the basic form.

Comparing Local and Global Split References


Lot1 -->
    split(x) { 10: A | ~1: split(x) ('0.2: B | '0.4: C) | 30: D }

Lot2 -->
    split(x) { 10: A | '0.2: B | '0.4: C | 30: D }

A --> color(1,0,0) #Red
B --> color(0,1,0) #Green
C --> color(0,0,1) #Blue
D --> color(1,1,0) #Yellow

For Lot1 : splits 10m on the left and 30m on the right, and splits the middle area into 20% and 40%.

For Lot2 : splits the first part as 10m, the second as 20%, the third as 40%, and the last as 30m.

Comparing the two codes, they seem identical in content. Try to predict the result. What kind of difference will there be?

Reference point comparison result
img 5 : Different results despite seemingly identical logic

In terms of the code, it should output identically since it's putting 20% and 40% into the middle area after excluding 10 and 30 from the left and right, but they show different results.

As you might have noticed, ' calculates the ratio based on the area of the {...} block it is contained in. In the case of Lot1, since it identifies the middle area as ~1 and creates a new {...} to function within it, it recognizes the 60m (excluding the left and right fixed values) as the total length, splits 20% and 40% of that 60m, and discards the rest. The gray area indicates the state where no rule is applied.

In the case of Lot2, since it functions within the global {...}, it is assigned 20% and 40% based on the total length of 100m.

When mixing these three symbols (*, ~, '), there are many cases where it gets confusing, and sometimes split results occur that were completely unexpected. Even looking at the CGA reference, the behavior is not explained very clearly, which can be frustrating, but as you use it often, you will realize which coding methods to avoid.

Key Takeaways About Absolute Ratio Splits in CGA

So far, we have covered *, ~, and ' used in split. We have finished all the basics of splitting methods.

Then, we must apply additional rules to each of these divided areas. While the same rule can be applied to all split areas, in most cases, different rules are used for each split surface. Next time, we will look at how to select specific split surfaces.

FAQ About Absolute Ratio Splits in CityEngine

What is the difference between ~ and ' in CityEngine?

The ~ symbol creates relative splits based on the remaining available space, while the ' symbol creates proportional splits based on the total length of the split direction normalized to 1. Relative splits dynamically adjust to leftover space, whereas absolute ratio splits always reference the full split length within the current split scope.

Does the absolute ratio symbol use the remaining space?

No. The ' symbol does not automatically use the remaining space. It only allocates the exact proportion specified. Any unused area remains unassigned unless another rule such as ~1 is added to consume the leftover space.

Can absolute ratios be nested inside split operations?

Yes. Absolute ratio splits can be nested inside other split operations. However, the ratio is calculated relative to the current split scope defined by the surrounding {...} block. This means nested splits may produce different results from globally defined splits even when the ratio values appear identical.

"Proportion is a correspondence among the measures of the members of an entire work, and of the whole to a certain part selected as standard."
— Marcus Vitruvius Pollio, De Architectura
Continue Learning
Explore complete tutorial collections for CityEngine and Global Mapper.

Comments

Popular posts from this blog

029] How to Split Polygon Areas with Intersecting Lines in Global Mapper

[008] How to Understand CGA Rule Structure in CityEngine (Beginner Guide)

046] How to Create Parallel Offset Lines in Global Mapper