This how-to guide handles curve and surface parameters, which are an essential part for algorithmic modeling in Grasshopper. Both are used to define a position on the geometric shape. Curves have one dimension and thus one parameter is needed to specify a point on the curve. Surfaces have two dimensions and thus two coordinates specify a point.
Curve parameters
A curve has one dimension, though it can inhabit a two- or three-dimensional space. To specify a point on a curve, we can describe its position by the distance that one has to travel along, from the curve’s start until reaching the point. Though the curve parameter does not have to equal the actually travelled length (as describe later), it starts at the lower bound of the curve’s domain and ascends until it reaches the upper bound.
Curve Domains
Let’s assume a simple curve: a circle with the radius of 2
. The domain of the
circle can be displayed with a Domain0 To 2.0 * Pi
, despite the radius and length. Every infinitesimal interval of the
curve can be allocated within the curve’s domain. In other words, a number
within the curve’s domain can be remapped to a position on the curve.
However, there is a pitfall with curves and their domains: When the type of a
shape changes, for example from a Circle to a Circular Curve, the domain
might change as well. For example, when we use the component Curve DomainInputs Curve (C) Curve to measure/modify Domain (D) Optional domain, if omitted the curve will not be modified. Outputs Curve (C) Curve with new domain. Domain (D) Domain of original curve. 2 * Pi
is replaced with the curve’s length, here 4 * Pi
.
The domain of a curve
does not have to start at 0, any real number is possible. For example, if we
ShatterInputs Curve (C) Curve to trim Parameters (t) Parameters to split at Outputs Segments (S) Shattered remains Inputs Curve (C) Curve to trim Parameters (t) Parameters to split at Outputs Segments (S) Shattered remains Inputs Curve (C) Curve to trim Parameters (t) Parameters to split at Outputs Segments (S) Shattered remains
Working with curve parameters
From the foregoing, we can recap that every value within a curve’s domain
represents a point on that curve. We can find a point and the curve’s properties
at that position with the component Evaluate CurveInputs Curve (C) Curve to evaluate Parameter (t) Parameter on curve domain to evaluate Outputs Point (P) Point on the curve at {t} Tangent (T) Tangent vector at {t} Angle (A) Angle (in Radians) of incoming vs. outgoing curve at {t} 2 * Pi
to evaluate the
midpoint of the domain (the component converts the circle to a curve and thus
the domain changes to 4 * Pi
).
To solve the above more parametric and to react to changes of the curve’s
domain, we can calculate a representative value in the curve’s domain with Remap NumbersInputs Value (V) Value to remap Source (S) Source domain Target (T) Target domain Outputs Mapped (R) Remapped number Clipped (C) Remapped and clipped number 0 To 1
.
Before we connect our circle, we need to convert it to a Circular Curve with Curve
Grasshopper offers several components to retrieve curve parameters, for example by intersection events or by curve analysis. Other components need a curve parameter as input to perform a certain function at that position of the curve.
Reparameterize curves
In the examples above, dealing with curve domains was cumbersome and needed
special attention. But we can make our lives easier: domains can be
reparameterized. This means, a domain is rewritten, or remapped, to the
normalized domain 0 To 1
. Thus, independent of the curve or type of curve, we
always get the same domain.
To do so, we can set a new domain D, here 0 To 1
, with a Curve DomainInputs Curve (C) Curve to measure/modify Domain (D) Optional domain, if omitted the curve will not be modified. Outputs Curve (C) Curve with new domain. Domain (D) Domain of original curve.
Because the normalization of a curve’s domain is so useful, it can also be achieved with a shortcut: right-click the input grip of a curve and select Reparameterize. That an input is reparameterized is indicated by the little symbol. After reparameterizing a curve, the curve parameters t also relate to the normalized domain.
Picking up the example from above, in which we remapped a value to fit the
curve’s domain, we can, after reparameterizing a curve’s domain, use a default
Number Slider
Curve parameters and lengths
In case of our circle, there was a relation between the curve parameter and the length; the midpoint (length factor 0.5) was at curve parameter Pi. However, this is often not the case. For example, the domain of polylines depends on the number of segments.
Nurbs curves, as another example, set their domain in relation to the number of knots. Even after reparameterizing a curve’s domain, there is no relation between the curve parameter and the length of a curve’s segment. As shown in the image below, the midpoint of this curve is at t = 0.580508.
After dividing this curve into segments according to equal subdomains of the curve’s domain, we see that the actual segments' lengths vary significantly.
To conclude, we have to treat curve parameter and length factor as two different properties, which occasionally have the same value. When dealing with curve parameters, it’s usually better to work with the normalized format.
Surface parameters
A surface has two dimensions and can inhabit a two- or three-dimensional space. To specify a point on the surface, we need two coordinates, which are commonly called u and v. These coordinates have to be within the domains of the surface. Because there are two dimensions, we have two domains. In Grasshopper, there is a special data type to host these domains, which is Domain² and each domain is named according to the coordinate.
To get the domain of a surface, we can use a Domain²Inputs Surface (S) Surface to measure Outputs U dimension (U) Approximate dimension in U direction V dimension (V) Approximate dimension in V direction
To find the uv-coordinates of a point on a surface, we can use Surface Closest PointInputs Point (P) Sample point Surface (S) Base surface Outputs Point (P) Closest point UV Point (uvP) {uv} coordinates of closest point Distance (D) Distance between sample point and surface
Grasshopper offers several components that either output uv-coordinates by some kind of event or rule and components that use uv-coordinates as input to perform certain functions at those positions.
Reparameterize surfaces
The concept of reparameterization, as described above, is also applicable and even more useful for surfaces. If we do not normalize the domains, we need to deconstruct the surface’s domains, find the coordinates of the position within these domains and combine them. Using a reparameterized surfaces shortens this to setting the position in a predefined domain space.
Trimmed and untrimmed surfaces
When dealing with surfaces, there is also a pitfall: trimmed surfaces. A trimmed surface is a combination of an arbitrary shape and closed curves. Internally, Rhino and Grasshopper use the underlying, untrimmed shape and display what is inside the outer border; additional closed curves can be used to cut holes into the remaining surface. If possible, transformations are calculated for the arbitrary, untrimmed shape and the curves separately and then displayed again as the combined, trimmed surface.
The surface’s domains and its uv-coordinates relate to the untrimmed surface,
not the trimmed one. This means that coordinates can actually be outside of the
trimmed surface. To illustrate this, we create a trimmed surface with a hexagon
and evaluate a position on that surface with an MD SliderInputs Point (P) Point for region inclusion test Curve (C) Boundary region (closed curves only) Outputs Relationship (R) Point/Region relationship (0 = outside, 1 = coincident, 2 = inside) Point (P') Point projected on region plane.
To retrieve the untrimmed surface from a trimmed one, we can use UntrimInputs Surface (S) Base surface Outputs Surface (S) Untrimmed surface