> For the complete documentation index, see [llms.txt](https://ezedits.gitbook.io/ezedits/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://ezedits.gitbook.io/ezedits/commands/placement/primary+secondary-alignment.md).

# Primary+Secondary Alignment

The two alignment directions define the *orientation* at which the structure is placed.

## Explanation

Every structure has an intrinsic "up" direction and an intrinsic "forward" direction. By default, structures are placed with their up direction facing, well, up (+y), and with their forward direction facing forward (+x).

The most important thing is that now you can control how a structure is placed by defining where its up direction and where its forward direction should face.

We let the user define the alignment using two directions:

{% hint style="info" %}
The `<primary>` direction *defines* the placement's +y direction.

The `<secondary>` direction *implies* the placement's +x direction. From all directions perpendicular to the primary direction, the chosen +x direction is the one that most closely aligns with the given secondary direction.

Note: The primary and secondary may not be the same direction.
{% endhint %}

<details>

<summary><mark style="color:blue;">More in-depth explanation using examples:</mark></summary>

Let's say this is our build that we want to place, by for example having it as our current WorldEdit clipboard.

<img src="/files/ElDjaDFMOa8EMX2LElhU" alt="" data-size="original">

For reference, the red beam is facing towards positive x (east), the blue beam is facing towards positive z (south), and the green beam is facing towards positive y (up).

We now want to place it at various orientations using any of the ezEdits structure commands. For this, we may define a `<primary>` and `<secondary>` direction. Let us go through a few examples for a few such assignments of these parameters and try to understand what is happening:

Let's set the `<primary>` to `up` and the `<secondary>` to `east` (You'd use the [Constant](#constant) mode for that.) (These directions are the default directions):

<img src="/files/ElDjaDFMOa8EMX2LElhU" alt="" data-size="original">

Our shape is pasted exactly in the same orientation as we copied it. Up is still up, right is still right, and so on.

Now, consider the following three examples:

1. The **`<primary>`** is set to **`south`** and the `<secondary>` remains at `east`:

<img src="/files/tQTrwzfKYN7BRRqAqidN" alt="" data-size="original">

Notice how, what was originally *"up"* when we copied it, i.e. the green beam in our case, is pointing into the direction that we set the primary to: *south*. Meanwhile what was originally *east*, is still *east*. The blue beam is going down as a consequence of this 90° rotation.

2. The **`<primary>`** is set to the vector **`(0,1,1)`**, i.e. the direction going "diagonally" up and south, and the `<secondary>` to `east`:

<img src="/files/5wg1oIWM5HD4QaIbKjRM" alt="" data-size="original">

Notice again, how what was originally *"up"* when we copied it, i.e. the green beam in our case, is pointing into the direction that we set the primary to: *diagonally up and south*.

3. The **`<primary>`** is set to the vector **`(1,1,0)`**, i.e. the direction going diagonally up and **east**, while the `<secondary>` is set to `east`:

<img src="/files/40bwo0P8XV5fgBTmK3Rv" alt="" data-size="original">

The green beam is correctly pointing along the primary direction, diagonally up and east. Whatever was pointing *up* when we //copy'd our clipboard is always aligned with whatever direction the primary is set to!

But now, even though the secondary is set to *east*, the red beam is not pointing directly east anymore (but diagonally down and east). This is intended behaviour.

Imagine if it were pointing east: Then the green and red beam would be at a 45° angle instead of the original 90° angle. Our structure would be deformed/bent/sheared.

What we decided to implement instead, is that (while we align the structure's +y direction with the given primary direction) instead of aligning the structure's +x direction with the given secondary direction, we choose the direction that is most similar to the given secondary direction but that is still perpendicular to the primary.

So, if the primary and secondary are not perfectly perpendicular, as in the example above, the secondary is swapped out with the most similar but still perpendicular vector!

Just for reference, here's a small GIF that shows the remaining perpendicular secondary directions for a set primary direction:

<img src="/files/2DiczziUb2jp4Jx4j3Eu" alt="" data-size="original">

To give a final example:

The **`<primary>`** is set to the vector **`(-1,2,-1)`**, i.e. a direction going up and northwest, while the **`<secondary>`** is set to **`west`**:

<img src="/files/0hvsODrTABVwoB0x0mfX" alt="" data-size="original">

As you can see, the green beam, or what was originally up in our build when we copied it, is now pointing into our specified `northwest+2*up` direction, while the red beam, or what was originally east when we copied, is now pointing as `west` as it can while still being perpendicular to the primary.

All of this applies independently of your current clipboard. Here's another structure at its original orientation followed by its placement aligned just like the previous example.

![](/files/3GL6Z4pyQ3uyACqM9kK8) ![](/files/mvRa9nJvY1ajp5hoKq1x)

Can you see why setting the primary to `(-1,2-1)` and the secondary to `west` leads to the leaf being oriented like that?

***

By the way, the command used was

`//ezbrush place Clipboard Constant(Direction:(-1,2,-1)) Constant(Direction:west)`

or, if you fancy abbreviations,

`//ezbr pl Cl C(D:(-1,2,-1)) C(D:west)`

With this primary + secondary system, we hope that you can easily and quickly construct your desired 3D orientation for each structure placement in any scenario.

</details>

***

## Overview

The primary and secondary can be set to either:

<table data-view="cards" data-full-width="false"><thead><tr><th>Name</th><th>Abbreviation</th><th>Description</th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td><a href="#constant"><strong><code>Constant</code></strong></a></td><td><strong><code>C</code></strong></td><td>Explicitly set a constant direction for all placements.</td><td><a href="#constant">#constant</a></td></tr><tr><td><a href="#random"><strong><code>Random</code></strong></a></td><td><strong><code>R</code></strong></td><td>Random direction for each placement.</td><td><a href="#random">#random</a></td></tr><tr><td><a href="#noise"><strong><code>Noise</code></strong></a></td><td><strong><code>N</code></strong></td><td>Direction based on the evaluation of a noise function at the placement's position.</td><td><a href="#noise">#noise</a></td></tr><tr><td><a href="#aim"><strong><code>Aim</code></strong></a></td><td><strong><code>A</code></strong></td><td>Your player aim direction.</td><td><a href="#aim">#aim</a></td></tr><tr><td><a href="#upward"><strong><code>Upward</code></strong></a></td><td><strong><code>U</code></strong></td><td>The most upwards perpendicular direction to your aim.</td><td><a href="#upward">#upward</a></td></tr><tr><td><a href="#playerrelative"><strong><code>PlayerRelative</code></strong></a></td><td><strong><code>P</code></strong></td><td>The direction from the placement's position towards the current player position.</td><td><a href="#playerrelative">#playerrelative</a></td></tr><tr><td><a href="#surfacenormal"><strong><code>SurfaceNormal</code></strong></a></td><td><strong><code>S</code></strong></td><td>The approximate surface-normal in the region of the placement's position.</td><td><a href="#surfacenormal">#surfacenormal</a></td></tr><tr><td><a href="#viewdiff"><strong><code>ViewDiff</code></strong></a></td><td><strong><code>V</code></strong></td><td>Define a direction using two clicks. Exclusively for brushes.</td><td><a href="#viewdiff">#viewdiff</a></td></tr><tr><td><a href="#expression"><strong><code>Expression</code></strong></a></td><td><strong><code>E</code></strong></td><td>Define a direction through an expression over each placement position.</td><td><a href="#expression">#expression</a></td></tr><tr><td><a href="#tangential"><strong><code>Tangential</code></strong></a></td><td><strong><code>T</code></strong></td><td>The direction tangential to the path. Exclusively for arrays.</td><td><a href="#tangential">#tangential</a></td></tr><tr><td><a href="#orthogonal"><strong><code>Orthogonal</code></strong></a></td><td><strong><code>O</code></strong></td><td>The direction orthogonal to the path. Exclusively for arrays.</td><td><a href="#orthogonal">#orthogonal</a></td></tr><tr><td><a href="#mixed"><strong>Mixed</strong></a></td><td>-</td><td>Mix and combine any of the other Alignment modes using a weighted list.</td><td><a href="#mixed">#mixed</a></td></tr></tbody></table>

***

## Settings

***

### Constant

Explicitly set a constant direction for all placements.

Syntax: <mark style="color:orange;">**`Constant`**</mark> or <mark style="color:orange;">**`Constant(Direction:<direction>)`**</mark>

Abbreviation: <mark style="color:orange;">**`C`**</mark> or <mark style="color:orange;">**`C(D:<direction>)`**</mark>

If you do not specify a `<direction>`, then:

* the default direction is **+y** if you're setting the `<primary>`.
* the default direction is **+x** if you're setting the `<secondary>`.

There are various ways to define a direction. From using the axes, cardinal directions, vector notation, or player relative directions like forward, left, right, etc. Pro tip: You can also add directions together using simple arithmetic operators, like `east-z+(0,0.5,0)`. Pro tip²: Put `=` at the end to evaluate your direction expression as you are typing it.

<details>

<summary><mark style="color:blue;">Examples</mark></summary>

`//ezsc Clipboard C(D:(0,2,0)) C(D:east)`

<img src="/files/gMT9lLa4BErJF4eObvu4" alt="" data-size="original">

`//ezsc Clipboard C(D:(-1,2,-1)) C(D:east)`

<img src="/files/D24zc6NKpknl8WDVTPOh" alt="" data-size="original">

`//ezsc Clipboard C(D:(-1,2,-1)) C(D:-aim)`

<img src="/files/BA05GNf3NusZnCBN22Dz" alt="" data-size="original">

</details>

***

### Random

Random direction for each placement.

Syntax: <mark style="color:orange;">**`Random`**</mark>

Abbreviation: <mark style="color:orange;">**`R`**</mark>

<details>

<summary><mark style="color:blue;">Examples</mark></summary>

`//ezsc Clipboard Constant Random`

Only setting the `<secondary>` to Random here, primary remains pointing up. Notice how our structure's up direction (green beam) remains up (primary is set to up), but each placement is randomly rotated around the primary (y-axis in this case) since the secondary is random.

<img src="/files/5aT8hlJhpWVa9Ax76syo" alt="" data-size="original">

`//ezsc Clipboard Random Constant`

Only setting the `<primary>` to Random, secondary remains pointing east. The terrain was replaced with glass so you can see better. Notice how the green beam is now facing all kinds of directions, but the red beam is roughly pointing east for all placements.

<img src="/files/nTzuEFlyyT1Tmdn3P6Ys" alt="" data-size="original">

`//ezsc Clipboard Random Random`

If we set both to Random, then we get true random chaos.

<img src="/files/PBKbIRbPl0WCE9NpODMT" alt="" data-size="original">

</details>

***

### Noise

Direction based on the evaluation of a noise function at the placement's position.

Syntax: <mark style="color:orange;">**`Noise`**</mark> or <mark style="color:orange;">**`Noise(Noise:<noise>)`**</mark>

Abbreviation: <mark style="color:orange;">**`N`**</mark> or <mark style="color:orange;">**`N(N:<noise>)`**</mark>

The default `<noise>` is `Perlin(Freq:0.01)`.

<details>

<summary><mark style="color:blue;">Examples</mark></summary>

`//ezsc Clipboard Constant Noise`

* Top-down screenshot
* `<primary>` is still up and only the `<secondary>` is set to Noise.
* The default Noise is Perlin Noise.

<img src="/files/EXWLe6WFYTB4EunL2XoZ" alt="" data-size="original">

`//ezsc Clipboard Constant Noise(N:Vor(Freq:0.02,DistReturn:cell))`

* Same scenario as above but using [Cellular Noise](https://en.wikipedia.org/wiki/Voronoi_diagram#/media/File:Coloured_Voronoi_3D_slice.svg).
* You can recognize how each cell has its own random direction.

<img src="/files/7WLmx17NGUJ2f8TOXp4k" alt="" data-size="original">

</details>

***

### Aim

Your player's aim direction.

Syntax: <mark style="color:orange;">**`Aim`**</mark>

Abbreviation: <mark style="color:orange;">**`A`**</mark>

Note: For brushes, `Constant(Direction:aim)` will use your player's aim direction at the time of brush binding, while `Aim` will use the player's aim direction during each brush act.

<details>

<summary><mark style="color:blue;">Examples</mark></summary>

`//ezsc Clipboard Aim Constant`

If we set the `<primary>` to `Aim` then the up direction of our structure, the green beam in our example, will align with our current player's aim direction.

My player model is included in the picture for reference. That's where I was looking when I executed the command. *The aim direction is visualized in F3+B with the thin blue line*

![](/files/1miOJc4IPnFm8nNMHo8Q) ![](/files/Efse0W8iTU93xYzZCQfT)

</details>

***

### Upward

The most upward perpendicular direction to your aim.

Syntax: <mark style="color:orange;">**`Upward`**</mark>

Abbreviation: <mark style="color:orange;">**`U`**</mark>

<details>

<summary><mark style="color:blue;">Diagram</mark></summary>

<img src="/files/dOpXHjw8Bo9q6IL3sfRe" alt="" data-size="original">

</details>

***

### PlayerRelative

The direction from the placement's position towards the current player position.

Syntax: <mark style="color:orange;">**`PlayerRelative`**</mark>

Abbreviation: <mark style="color:orange;">**`P`**</mark>

<details>

<summary><mark style="color:blue;">Examples</mark></summary>

`//ezsc Clipboard PlayerRelative Constant`

If you set the `<primary>` to `PlayerRelative`, then each structure is placed such that its up direction is pointing towards your player position.

If you look closely, you can see my player model in the pictures. That's where I executed the command.

![](/files/qQc3itBl4oIVNaRKKrOu) ![](/files/Ip1ldIgDOvS50rpS6hxn)

`//ezbr place Shape(S:Cone,P:diamond_block) PlayerRelative Constant -s 12,36,12`

<img src="/files/kgiIe2KFXmHw7CalVACK" alt="" data-size="original">

</details>

***

### SurfaceNormal

The approximate surface-normal in the region of the placement's position.

Syntax: <mark style="color:orange;">**`SurfaceNormal`**</mark>

Abbreviation: <mark style="color:orange;">**`S`**</mark>

By [normal](https://en.wikipedia.org/wiki/Normal_\(geometry\)) we mean the direction perpendicular to the terrain in question.

<details>

<summary><mark style="color:blue;">Examples</mark></summary>

`//ezbr place Shape(P:57,S:Cone) SurfaceNormal Constant -s 12,36,12`

You can see our ingame alignment visualizer dynamically orient itself depending on which part of the terrain you are looking at when you are holding the brush.

<img src="/files/dZuCjE1Le7HfSRc8VNav" alt="" data-size="original">

</details>

***

### ViewDiff

Define a direction using two clicks. Exclusively for brushes.

Syntax: <mark style="color:orange;">**`ViewDiff`**</mark>

Abbreviation: <mark style="color:orange;">**`V`**</mark>

Each placement requires a right click and a left click. The first right click sets the placement position at the targeted block. Left-clicking somewhere else then defines a direction: From your first (right) click target position to your second (left) click.

<details>

<summary><mark style="color:blue;">Examples</mark></summary>

`//ezbr place Clipboard SurfaceNormal ViewDiff`

Here I set the primary to SurfaceNormal and control the secondary direction with a second click through the ViewDiff mode. Pay attention to my hand. You can see me alternating between right- and left-clicks. A right click sets the placement position, and a left click sets the ViewDiff direction. Our ingame alignment visualizer dynamically updates depending on your movement and your actions.

<img src="/files/q33Gbbchz0fB2TayCHAj" alt="" data-size="original">

`//ezbr place Shape(S:Torus(Thickness:0.4),P:57) PlayerRelative ViewDiff -s 20,20,30 -k x -c 90`

This torus shape required a few more parameters, so this example turned out a bit longer than usual. What's important to notice though is that the primary is set to PlayerRelative, meaning the top of the torus always faces the player, and the secondary is set to ViewDiff, meaning the final orientation is determined with a second click. Here, after each right-click, I alternate between left-clicking above and left/right from the placement position to create a linked chain.

<img src="/files/9iJsCS8E1WDhUDHSrPQX" alt="" data-size="original">

</details>

***

### Expression

Define a direction through an expression over each placement position.

Syntax: <mark style="color:orange;">**`Expression(Expression:=<expression>,Space:<space>)`**</mark>

Abbreviation: <mark style="color:orange;">**`E(E:=<expression>,S:<space>)`**</mark>

Mandatory Arguments:

* <mark style="color:orange;">**`Expression`**</mark> **(**<mark style="color:orange;">**`E`**</mark>**)**: An expression defining a 3D vector for each position in space.
  * Input variables are <mark style="color:blue;">`x`</mark>, <mark style="color:blue;">`y`</mark>, <mark style="color:blue;">`z`</mark>.
  * Output variables are <mark style="color:blue;">`rx`</mark>, <mark style="color:blue;">`ry`</mark>, <mark style="color:blue;">`rz`</mark>.
  * For each placement, the expression will evaluated with the according placement position and the result used for the placement's alignment.

Optional Arguments:

* <mark style="color:blue;">**`Space`**</mark>**&#x20;(**<mark style="color:blue;">**`S`**</mark>**)**: Defines the domain of the input variables.
  * Defaults to <mark style="color:blue;">`WORLD`</mark>.
  * <mark style="color:blue;">`WORLD`</mark>: the placement position. x, y, z, are in world coordinates
  * <mark style="color:blue;">`LOCAL`</mark>: When used in...
    * ezplace: Always 0,0,0.
    * ezscatter: Coordinates shifted such that the center of the region is 0,0,0.
    * ezarray: x=y=0. z=0 at the start of the path, z=L at the end of the path, whereby L is the length of the path.
  * <mark style="color:blue;">`NORMALIZED`</mark>: When used in...
    * ezplace: Always 0,0,0.
    * ezscatter: Coordinates normalized to the region such that x,y,z ∈ \[-1,1].
    * ezarray: x=y=0. z=0 at the start of the path, z=1 at the end of the path.

<details>

<summary><mark style="color:blue;">Examples</mark></summary>

`//ezsc TS(P:##Grayscale,S:Fur,T:=y) C Ex(E:"=rx=z;rz=-x",S:N)`

* <mark style="color:blue;">`TS(P:##Grayscale,S:Fur,T:=y)`</mark> is a fur shape in a grayscale gradient.
* <mark style="color:blue;">`C`</mark>, the primary, using the default up direction.
* <mark style="color:blue;">`Ex(E:"=rx=z;rz=-x",S:N)`</mark> sets the secondary to (z,0,-x), whereby x,z are the normalized placement position coordinates.

<img src="/files/k2dc0rOwB0wWngzGhgSh" alt="" data-size="original">

`//ezar Sh(S:Fur,P:clay) C E(E:"=rx=sin(2*pi*z);rz=cos(2*pi*z)",S:N) -g -12`

This example shows how the z coordinate ranges from 0 to 1 along the path when using normalized mode.

<img src="/files/XDBV3qWtfd8cfQL74y9T" alt="" data-size="original">

</details>

***

### Tangential

The direction tangential to the path. Exclusively for arrays.

Syntax: <mark style="color:orange;">**`Tangential`**</mark>

Abbreviation: <mark style="color:orange;">**`T`**</mark>

<details>

<summary><mark style="color:blue;">Examples</mark></summary>

`//ezarray Clipboard Tangential Constant -g 11 -o 2`

The *Tangential* direction points tangential to the spline path at the position of the placement. If you set the primary to *Tangential*, the top of the shape is pointing along the spline like this.

<img src="/files/PQB5Xgq24Jcey98lyQpL" alt="" data-size="original">

</details>

***

### Orthogonal

The direction orthogonal to the path. Exclusively for arrays.

Syntax: <mark style="color:orange;">**`Orthogonal`**</mark> or <mark style="color:orange;">**`Orthogonal(Angle:<angle>)`**</mark>

Abbreviation: <mark style="color:orange;">**`O`**</mark> or <mark style="color:orange;">**`O(A:<angle>)`**</mark>

The angle, given in degrees, defines the initial direction of the orthogonal direction, whereby 0° and 360°, will face up, 90° and 270° face left and right, and 180° faces down (at the first part of the spline at least. It may twist further along if the normal mode is set to CONSISTENT, which is the default setting).

<details>

<summary><mark style="color:blue;">Examples</mark></summary>

`//ezarray Clipboard Orthogonal Constant`

The *Orthogonal* direction points perpendicular to the spline path at the position of the placement. If you set the primary to *Orthogonal*, the top of the shape will point perpendicular to the spline path like this.

<img src="/files/6LhFTvtOtjcQ1wMCpBBy" alt="" data-size="original">

Here's a GIF going through the `<angle>` parameter:

<img src="/files/PwoPpFpty1ZlirdxjvZX" alt="" data-size="original">

`//ezarray Clipboard Orthogonal Constant -n HORIZONTAL`

The [-n flag](/ezedits/commands/placement/array-parameters.md#spline-orientation-n) has a direct influence on the orthogonal direction.

<img src="/files/r6Bcmn4Iey0yuF6eo1QT" alt="" data-size="original">

</details>

***

### Mixed

You may combine any number of any of the other Alignment modes using a weighted list:

Syntax: <mark style="color:orange;">`<weight1>%<alignment1>,<weight2>%<alignment2>,...`</mark>

Alignment directions are scaled by the given weight and summed up together.

<details>

<summary><mark style="color:blue;">Examples</mark></summary>

` //ezsc Sh(P:clay,S:Cone)`` `` `**`Constant`**` `` ``-s 11,30,11 -n 1 `

(for reference)

<img src="/files/bTqYRkDSYnMRZ4vna6m5" alt="" data-size="original">

` //ezsc Sh(P:clay,S:Cone)`` `` `**`10%C,10%R`**` `` ``-s 11,30,11 -n 1 `

GIF going through

* `10%Constant`
* `10%Constant,1%Random`
* `10%Constant,2%Random`
* ...
* `10%Constant,10%Random`

<img src="/files/kRc06CF4x9Ujqmdde43s" alt="" data-size="original">

</details>

***

## Parameters

The following flags adjust how Alignments are calculated.

***

### Snap to certain directions: <mark style="color:orange;">`[-j <snapDirections>]`</mark> <a href="#snap-to-angles-j" id="snap-to-angles-j"></a>

This parameter allows you to restrict the chosen alignment direction to the specified subset. E.g. snapping to / only allowing cardinal direction, i.e. 90° rotations.

Available options:

* <mark style="color:orange;">**`MULTIPLES_90`**</mark>
  * Only allows multiples of 90°, i.e. all axis-aligned directions.
* <mark style="color:orange;">**`MULTIPLES_45`**</mark>
  * Only allows multiples of 45°, i.e. axis-aligned directions AND all perfect diagonals.
* <mark style="color:orange;">**`MULTIPLES_22_5`**</mark>
  * Only allows multiples of 22.5°.
* <mark style="color:orange;">**`MULTIPLES_15`**</mark>
  * Only allows multiples of 15°.
* <mark style="color:orange;">**`DIAGONALS_1_1`**</mark>
  * Only allows axis-aligned directions, and perfect "1:1" diagonals.
* <mark style="color:orange;">**`DIAGONALS_2_1`**</mark>
  * Only allows the <mark style="color:orange;">`DIAGONALS_1_1`</mark> directions and any "2:1" diagonals.
* <mark style="color:orange;">**`DIAGONALS_3_1`**</mark>
  * Only allows the <mark style="color:orange;">`DIAGONALS_2_1`</mark> directions and any "3:1" diagonals.
* <mark style="color:orange;">**`DIAGONALS_4_1`**</mark>
  * Only allows the <mark style="color:orange;">`DIAGONALS_3_1`</mark> directions and any "4:1" diagonals.
* <mark style="color:orange;">**`DIAGONALS_5_1`**</mark>
  * Only allows the <mark style="color:orange;">`DIAGONALS_4_1`</mark> directions and any "5:1" diagonals.

<details>

<summary><mark style="color:blue;">Examples</mark></summary>

`//ezbrush Cl Constant ViewDiff -j MULTIPLES_45`

<img src="/files/rk8uGOnYHnOIhNxBlb5g" alt="" data-size="original">

</details>

***

### Perturb Secondary: <mark style="color:orange;">\[-x]</mark> <a href="#perturb-secondary-x" id="perturb-secondary-x"></a>

In our primary+secondary system, placement fails if both vectors are collinear (which simply means they are on the same line).

By enabling this flag ezEdits tries to circumvent that case by perturbing the secondary direction by a small amount.

***
