# How to draw 3d spiral in p5.js in 2d without webgl or any 3D engine

I intend to draw spirals in the shape of a 3d spring, as in the doodle below. How can I do that through trigonometry without 3d engines like webgl? Thanks!

2 Likes

Take a look at Khan Academy’s post.

1 Like

1 Like

There’s a couple things I would look into:

1. You could create a 3d model in blender and load it into p5. This is one simple way to create more complex geometry but it makes it harder to animate the shape. Dan Shiffman made a video about this and there’s a bunch of blender tutorials out there.
2. As @Chrisir suggest look at using trigonometry. There’s an example of this on the p5 website. I would try drawing a bunch of cylinders to create curves.
3. This reminded me of an example from three.js using extrude. (Use the drop down in the top right of the screen to select HelixCurve.) I don’t know how well this would translate to p5 but you could look at the code and see if there’s something there.
2 Likes

It’s always nice to break the problem down into smaller parts: let’s look at how we can draw the spiral one-dimension at a time.

Notice the x-axis motion is simply going back and forth with the width decreasing as we go down. Notice the y-axis motion is also going back and forth, but with an added motion going down.

These motion can be represented by two sinusoidal functions with 90 degrees out of phase. Or conveniently, use a sine function for one of the axis, and cosine function for the other function. Note that these two functions alone creates a circle.

Now we just need to multiple the x-axis function with some decaying value, and add the y-axis function with some increasing function to get the spiral you wanted.

Here is a proof of concept:

``````void setup() {
size(400, 400, P2D);
background(255);
}

void draw() {
float n = 500;
for (float t = 0; t < n; t++) {
// adding width/2 to center the spiral
float x = cos(t * 0.05) * 100 * map(t, 0, n, 1, 0.5) + width / 2;
float y = sin(t * 0.05) * 20 + map(t, 0, n, 100, 300);
fill(0);
ellipse(x, y, 5, 5);
}
}
``````

Result: 3 Likes

thank you! such intelligent solutions!

That’s not 3D yet

In 3D you want the circle between x and z plane : cos and sin

The going down part is y : y++;

You can now use point (with 3 parameters) or line (with 6 parameters) or sphere with translate (with 3 parameters)

You can use peasyCam

Use lights(); at start of draw()

Chrisir

1 Like

so @FSXAC give a very good answer!

1 Like

You might also be interested in applying your spiral math to the Tube from the Shapes3D library.

http://lagers.org.uk/s3d4p/index.html

Edit: that is for Processing (Java), not p5.js

example in 3D as I described above

Chrisir

``````
ArrayList<PVector> listPV = new ArrayList();
float angleForRotation;

void setup() {
size(800, 800, P3D);
noStroke();

float x, y, z;      // pos
float r = 88;

fill(255, 2, 2);

for (int i=0; i<8*360; i+=4) {
// x and z are the circle part
// y is the height (which makes the circle to a spiral)
y = map(i,
0, 8*360,
-230, 230);
// store result
}
background(0);
//
} // func

void draw() {
background(0);
lights();

translate(width/2, height/2);
rotateX(angleForRotation);

for (PVector pv : listPV) {
pushMatrix();
translate (pv.x, pv.y, pv.z);
sphere(8);
popMatrix();
}

angleForRotation+=.07;
//
} // func
//
``````