[053] How to Use rotateScope() for Angled Splits in CityEngine CGA

Rotate the procedural bounding box to control the angle of facade divisions.

This tutorial explores how the coordinate system (scope) affects splitting operations in Esri CityEngine. By combining alignScopeToAxes and rotateScope, you will learn how to achieve complex diagonal divisions on 3D geometry and understand the relationship between world axes and local procedural space.

Recommended Audience: Beginners in CGA coding and GIS professionals looking to master coordinate transformations for urban modeling.

How Scope Direction Affects split() Operations

As I mentioned previously, the reason for changing the scope is to perform operations like splitting, moving, and scaling in the desired direction.

Today, we will use rotateScope() to rotate the scope and see how the results of split() change accordingly.

@Group("Select_Axes", 0)
@Enum("world.xyz", "x", "y", "z")
@Description("Select which axis to align the scope to.")
attr AlignScopeToAxes = "world.xyz"

Lot -->
    primitiveCone(5, 5, 20)
    # Generate a cone
    alignScopeToAxes(AlignScopeToAxes)
    A

A -->
    split(y) { '0.25 : B }*
    # Split into 4 equal parts along the Y-axis

B -->
    case split.index == 0 :
        color(1, 0, 0) X.
        # Paint the first split segment red
    else :
        X.

On line 15, there is a split(y). Since split(y) operates along the local Y-axis of the current scope determined by alignScopeToAxes on line 11, you should pay close attention to how the splitting angle changes.

Video demonstrating the interaction between alignScopeToAxes and split

However, scope alignment alone has its limitations.

Using rotateScope() for Diagonal Splits

Let's use rotateScope to change the split() angles in various ways.

As the name suggests, rotateScope() allows you to rotate the local scope around the X, Y, and Z axes.

How rotateScope Changes Local Scope Axes

// Advanced Rotation Example
@Group("Select_Axes", 0)
@Enum("world.xyz", "x", "y", "z")
attr AlignScopeToAxes = "world.xyz"

@Angle
attr rot_X = 0
@Angle
attr rot_Y = 0
@Angle
attr rot_Z = 0

Lot -->
    primitiveCone(5, 5, 20)
    # Generate a cone
    alignScopeToAxes(AlignScopeToAxes)
    rotateScope(rot_X, rot_Y, rot_Z)
    # Rotate the scope based on attribute values
    A

A -->
    split(y) { '0.25 : B }*
    # Split along the Y-axis of the rotated scope

B -->
    case split.index == 0 :
        color(1, 0, 0) X.
    else :
        X.

Step-by-step video of scope rotation and alignment

In the video, we only performed a simple test.

Understanding World Axes and Local Scope

After typing the code above yourself, you should refer to the world axes in the bottom left, change the axis and scope values, and carefully observe and understand the relationship between them.

For those who have studied coding a bit, it would be even better to check how position movement works according to axis and scope changes using the t() command.

alignScopeToAxes is the easiest and most straightforward method among scope alignment techniques.

Limitations of alignScopeToAxes()

This is because it uses only a single element, the 'axis,' as the reference for setting the scope.

However, as you build things, there are times when you need to attach the scope to elements other than the axes.

For example, setting a scope based on the sloped surface of a roof,

or in the case of the pentagonal pyramid in the video above, setting the scope based on the third face is difficult with alignScopeToAxes(). (It's not impossible; you could set the angle using rotateScope, but you would have to readjust it if the size of the pentagon changes.)

That is exactly why we need alignScopeToGeometry(), which we will cover in the next lesson.

“People who use imagination are dreaming while awake.

They are not servants who surrender to appearances.
They are masters who can direct the focus of their attention.

When imagination is used consistently, our perception of events unfolding in time and space begins to change.”
— Neville Goddard
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