12
$\begingroup$

Summary: How to graph a 2D parametric equation using Geometry Nodes?

Details:

This question asks about plotting 2D functions of the form $y = F(x)$ using Geometry Nodes, and of course the simplest way to do that would be with a node group like this:

Node group for graphing a 2D function

where the Power math node is replaced by a selection of math nodes to calculate the function of interest.

But that won't work for a parametric equation, one where both $x$ and $y$ are calculated as functions of another variable, $x = f(u)$; $y = g(u)$; $a \le u \le b$; because the above group relies on x having the same value as the X coordinates of the Mesh Line.

I know this can be done by other means. For instance, the Math Function -> XYZ surface can take a parametric form and produce a 2D graph by setting V step to 1, as in this example of the parametric form of a circle:

parametric form of a circle

But I want to know if this can be done using Geometry Nodes. I'll accept either an answer that describes a general method or an answer that conclusively demonstrates that it can't be done.

$\endgroup$
6
  • $\begingroup$ I'm not experienced with Geo-nodes, but I am with bpy. Is there a reason you are not using bpy to achieve this? You can still apply shaders, animate etc in bpy. $\endgroup$ Apr 12, 2022 at 20:04
  • $\begingroup$ I want to animate some raycasting behavior in the vicinity of a parametric surface. If parametric functions are doable in GN then it'll be easier to do there than to write raycasting code for bmesh $\endgroup$ Apr 12, 2022 at 20:07
  • $\begingroup$ @WhisperingShiba I wish bpy was as fast as geometry nodes, unfortunately the Python API is slow, moreover, it's dangerous, which makes sharing projects harder (this can be especially felt here, on BSE, where Python solutions are somewhat niche). $\endgroup$ Apr 12, 2022 at 20:29
  • $\begingroup$ @MarkusvonBroady I feel you on the speed problems. Can you expand on the dangers? Just in-so-far as scripts can deeply break projects by deleting data other data was contingent upon? I've been developing a system that works for me. I create mathematically defined geometries in a separate file with script and then append that data to the main 'assembly' file. $\endgroup$ Apr 12, 2022 at 20:34
  • 1
    $\begingroup$ @WhisperingShiba I simply mean the trust issues, where if you take a script from someone, you probably should read what it does, and if you share a script with someone, it may be hard to convince the receiver your intentions are honest. Also a script based project requires everyone using it to manually run the script, or to enable script auto-execution, which creates a possibly attack vector through sharing a .blend file with a nasty script, so now you need to couch project participants on protecting themselves from that. :) $\endgroup$ Apr 12, 2022 at 20:41

3 Answers 3

12
$\begingroup$

Parametric functions fall absolutely naturally into the lap of GN, by setting X,Y and Z of a curve's points as some function of its Spline Parameter

  • Create a Curve Primitive > Line
  • Resample it to the desired resolution
  • Set Position each of the curve's points, as some function of its 0-1 ('Factor') Spline Parameter

Here's a parametric Trefoil Knot:

enter image description here

enter image description here

$\endgroup$
10
$\begingroup$

You may use an Accumulate Field node for u, calculate x and y, combine them to a vector and set the position on the points of a Mesh Line:

node net

result

You should be aware, that the last point is not exactly the end of one cycle. Instead, it is placed at 0.1*64 = 6,4 which corresponds to about 366,69°.

This allows you, to animate the step size of the Accumulate Field node as well:

Animation

It should be mentioned, that changing the step size in this way, does not produce the original parametric equation. It is like sampling over this equation and connecting the sampling points.

Upper and lower bound for u

If you would like to have exactly one circle of 360° or 2pi, then you need to limit u to a range of 2pi. Generalized, as asked by Marti Fouts, you may limit u by two parameters a and b like this:

Mapped to 2pi

Place a Map Range behind u and use the Result as input for both, x and y. Set From Min to 0, From Max to (Resolution – 1)*Increment Size and connect To Min and To Max to the parameters a and b.

You need to subtract 1 from the resolution, because u will be 0*Increment Size for the first point and (Resolution-1)*Increment Size for the Resolution-th point.

Even simpler

If you want to stick to the original parametric equation and map the range of u, it would be simpler to skip the Accumulate Field node and use the index instead, as proposed by Markus von Broady:

enter image description here

$\endgroup$
2
  • $\begingroup$ I've never yet used the Accumulate Field node, but how does it differ from dividing index by 64 (a constant also controlling the mesh line Count), or domain size, and passing that to both sine and cosine? $\endgroup$ Apr 12, 2022 at 20:26
  • 1
    $\begingroup$ If you consider this static example, the result will be the same. But this way, you could animate the count of the meshline and the step size separately, which by the way generates some really cool patterns ;-) ... and it just matched better to the way, I was thinking. $\endgroup$ Apr 12, 2022 at 21:40
6
$\begingroup$

Update: André Zmuda has kindly taken the time to improve his original answer, and describe the improvements in comments. I've changed this summary to reflect that.

Introduction

André Zmuda and Robin Betts have each provided good answers using different approaches.

I would like to accept both answers but I can only accept one. So I am upvoting both and accepting Betts' (for a reason that has since been corrected.)

Here I present each method, massaged slightly to be closer to the formulation of the $x = F(y)$ node group in the question. See the individual answers for more details.

Zmuda's method

Zmuda's method node group

I have made a slight change, introducing a Map Range math node so that the conditions $a \le u \le $b can be made apparent.

Zmuda's method uses an Accumulate Field Node to generate values in the range of 0 to (Value * the maximum index in the geometry). In this Node group the maximum index is controlled by the Count input of the Mesh Line node.

My small modification maps that range to the U range for the equation by using a Map Range node, as mentioned above.

Betts' example is actually a 3D curve, but Zmuda's method could generate a 3D curve by adding a Curve to Mesh node after the Set Position node.

Betts' method

Betts' method node group

As with Zmuda's method I have introduced a Map Range for the same reason. Betts' method uses a Curve Line rather than a Mesh Line. I have also added a Curve to Mesh Node after the Set Position node to give a closer similarity to the original node group. I also reduced his elegant 3D trefoil equation to a simple 2D circle to match the other examples.

Betts' method uses a Spline Parameter node to generate the $u$ values. The manual says this about the Factor output:

When the node is used on the point domain, the value is the portion of the spline’s total length at each control point. On the spline domain it is the portion of the curve’s total length at the start of the spline.

Similarities and differences

Both methods rely on some form of generator to create the u values. After that the math would be the same for a given function in either method. Zmuda's method works strictly with meshes; while Betts' opted for curves. Either would serve my purpose, since there are Mesh to Curve and Curve to Mesh nodes.

Bonus for reading this far:

Here is a blend file containing both methods; as modified by me to match the original example in the question. Update: I have edited the node group for Zmuda's method to incorporate the fix he gave in comments.

$\endgroup$
7
  • $\begingroup$ Thanks for the summary and for sharing the file! $\endgroup$
    – quellenform
    Apr 13, 2022 at 0:26
  • 1
    $\begingroup$ Thank you, @MartyFouts for this comparison. Only, "Accumlate Field" is not the "bad guy". The error results from combining the MapRange with the values 64 and 0.1. If you change the step size to 0.098, the circle looks good (64*0.098 is much closer to 2*pi). This effect does not appear in my original solution, because I don't map to 2*pi. Thus my circle simply covers 6.4 = 2,03718...*pi, which is 366.69°. Mapping this to 2pi results in a distorted circle. $\endgroup$ Apr 13, 2022 at 20:57
  • 1
    $\begingroup$ Sorry @MartyFouts, I was wrong in my last comment. You may ignore it. The reason for the inaccuracy is different: You need to subtract 1 from the smoothness before multiplying it with the increment and using it as "From Max" in the "Map Range". And you need to feed the Sine with the Result of the Map Range as well. Then the error disappears completely. $\endgroup$ Apr 14, 2022 at 5:58
  • 1
    $\begingroup$ @AndréZmuda Thank yo for the extra effort. I have updated my summary to reflect your comments. $\endgroup$ Apr 14, 2022 at 13:34
  • 1
    $\begingroup$ Thank you @MartyFouts for this update. I supplemented my solution with a description for limitting the range and added a little animation. $\endgroup$ Apr 14, 2022 at 22:26

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .