# Flattening a two-dimensional array

Here’s one way to calculate array indices when you’re storing a “2D array” in a flat one-dimensional array.

# You, ICE, and position vectors

In ICE, we often work with point or particle positions, and these positions are 3D Vectors.

Now, in general, a vector is something that has both value and direction (for example, any cyclist knows that the wind has both a magnitude and a direction, and together they really define the wind

When you’re working with point/particle positions, you’re really working with position vectors that specify a unique position in space. You’re not really interested in the magnitude of the vector, just the head and tail of the vector.

For any position vector, the tail is the origin: the point (0, 0, 0).
The head of the vector is the position in space.

When you’re working with position vectors in ICE, it’s important to understand what coordinate system you are working in, because that determines the origin. For example, here’s two different position vectors for the same point:

# Intro to rotating vectors in ICE

In this video I take a quick look at how Rotate Vector works, but more importantly, I dive into some issues related to different coordinate systems. In many scenarios where you use Rotate Vector (eg to rotate polygons), you have to understand what coordinates you’re working with.

Hopefully, this will be the first in a series of vids.

# Deleting overlapping particles

As an exercise, I built this ICE tree that prevents any overlapping particles (for non-rotated particles only). It works by comparing the X, Y, and Z values of the vector between two points with the combined size of the two particle shapes (which are boxes in this example).

The compound node returns an array of booleans, one for each neighbour. The boolean flags indicate whether or not the particles would overlap, so if at least one is True, then I delete the particle. If you must see it, here’s the compound:

# Vector multiplication in ICE versus the Dot Product

In general, there isn’t a unique definition for the multiplication of one vector by another, but there are several common “vector products”, such as the dot product and the cross-product.

The dot product of the two vectors (x, y, z) and (a, b, c) is ax + by + cz.

I kinda assumed that in ICE, the Multiply node would give me the same result, but it turns out that Multiply gives (ax, by, cz):

# Pop quiz: Get X coordinate out of a vector without using a conversion node

Given a 3D vector, can you get the X coordinate without using 3D Vector to Scalar or any other conversion node? (Not that there’s anything wrong with using a conversion node.)

# ICE Trigonometry nodes: degrees or radians?

The docs don’t say whether the Trigonometry nodes like Cos and Sin work with degrees or radians, so you have to figure it out yourself. Fortunately, that’s pretty easy to do. You just check which of these returns -1: cos( 180 ) or cos( π) ?

I went a little overboard, but this shows that Cos and Sin expect angular measurements expressed in degrees.

This is based on some basic trigonometry, which can be pretty handy when working with ICE:

• 2*π radians is equivalent to 360 degrees, so π is 180 degrees.
• cos( θ ) is the X coordinate of a point on the unit circle, so we know that at 180 degrees (or π if using radians), Cos will return -1.

# Aligning particles and making instances look at something

Dealing with particle orientation and rotation can be frustrating, especially when you’re first learning.

Here, I’ve got a bunch of faces instanced onto a disc, and I want all of them to to look the closest point on the grid that’s in the center of the disc. Because the initial local Z axis of some particles faces “away” from the grid, you get can some weird popping and flipping. Here’s an illustration of the problem from an earlier test, when I was aligning the faces to look at a specific point. Notice how only the instances on one side of the null have problems.

So, I use the dot product to determine whether the local Z axis faces “away” from the target grid, and if so, I make an adjustment of 180 degrees, and then the faces align nicely.

A negative dot product tells me that the angle between the local Z axis and the vector to the closest point on the grid is more than 90 and less than 270.

# Making circles on the surface of a mesh

Taking a cluster of points and moving them on to a circle turned it to be easier than I thought… At first it seemed more complicated to get at the points, because sometimes the Show Values on the output of a Filter node is, let’s face it, misleading. Based on what a certain Show Values showed me, I started off using arrays instead of Filters, and that made the graph a little messier.

First, I calculate the point I want to use as the center of the circle. That gives me the first vector I need.

Subtracting the CC (circle center) vector from the PP (Point Position) vectors gives me a set of vectors that take me from the circle center to the points.

I just resize the PP-CC vectors to get point positions that fit on a circle: