## The Shape

I was working on a project where I needed to arrange chairs around a pillar in a hotel or condo lobby. While I was contemplating the procedural layout, I thought it would be interesting to arrange objects based on various geometric shapes. I initially began with a circle and eventually developed concentric rings around a radius to create what could potentially be stadium seating.

## Blueprint Node

Determined to streamline the process when it came to working in the blueprint graph, I created blueprint function library functions for different types of potential shapes, each with the appropriate structs for parameters that correspond to those shapes. I plan to encapsulate this functionality into a component where you can simply select the specific shape via an enumerator, and the relevant settings will be displayed accordingly. I intend to revisit this concept in the near future. The idea is to enable artists to add objects or actors to the world in the form of a 2D or 3D layout. Furthermore, artists will have the capability to add objects around specific vector points, but I’ll discuss that in more detail in a separate post.

For now this is the result that we’re shooting for.

- What are the uses
- Usage

## Struct

USTRUCT(BlueprintType) struct FCageVectorSphereParams { GENERATED_BODY() UPROPERTY(BlueprintReadWrite, EditAnywhere) int32 LatitudeSegments; UPROPERTY(BlueprintReadWrite, EditAnywhere) int32 LongitudeSegments; UPROPERTY(BlueprintReadWrite, EditAnywhere) float Radius; UPROPERTY(BlueprintReadWrite, EditAnywhere) bool bTop; UPROPERTY(BlueprintReadWrite, EditAnywhere) bool bBottom; };

## Header

/** Create Vector Sphere */ UFUNCTION(BlueprintCallable, BlueprintPure, meta=(DisplayName = "Create Vector Sphere"), Category="CageTools|Object Placement") static TArrayCreateVectorSphere(int32 LatitudeSegments, int32 LongitudeSegments, float Radius, bool bTop, bool bBottom); }

## C++

TArrayUCageUtilities::CreateVectorSphere(int32 LatitudeSegments, int32 LongitudeSegments, float Radius, bool bTop, bool bBottom) { TArray SphereTransforms; for (int32 lat = 0; lat <= LatitudeSegments; ++lat) { for (int32 lon = 0; lon <= LongitudeSegments; ++lon) { // Calculate the spherical coordinates float Theta = 2 * PI * float(lon) / float(LongitudeSegments); float Phi = PI * float(lat) / float(LatitudeSegments); // Convert to Cartesian coordinates float X = Radius * sin(Phi) * cos(Theta); float Y = Radius * sin(Phi) * sin(Theta); float Z = Radius * cos(Phi); FVector Vertex(X, Y, Z); if ((bTop && Vertex.Z >= 0.0f) || (bBottom && Vertex.Z <= 0.0f) || (!bTop && !bBottom)) { // Create a transform with the forward vector pointing outward on the Z-axis FTransform Transform(FRotator(0.0f, 0.0f, 0.0f), Vertex); SphereTransforms.Add(Transform); } } } return SphereTransforms; } }