# SeaShell Mesh from point array? extrude along path?

I have and algorithm that generates seashell geometry in Python. I’d like to rewrite it in three.js and generate many different types of shells on the web.

I’ve searched this forum and Stackoverflow and am still not sure. Can Three.js create a complex mesh from a generative point array? I’ve looked at BufferGeometry and it doesn’t look like it can, but I’m not sure.

My algorithm generates points from curves, (“cross sections”, “ellipses”, “ribs”) along a spline. It’s kind of like extruding a shape along a path, except the shapes increase in size and points the further they get along down the path. I’ve looked into the path extruding methods and they don’t seem like they’d work.

I’m three.js newbie and will welcome any advice on what tools, methods or examples I should be looking at and trying. Thanks!

Related:

Another option is to take a look at this topic: Addon. Produces almost infinite many time-varying geometries with functions
And contact @hofk

1 Like

The addon Addon to create special / extended geometries also shows how to create different more complex geometries. If you have the formulas/algorithm, it’s just a little work to get the result.

see GitHub hofk (Klaus Hoffmeister) · GitHub

from THREEp: examples THREEp

2 Likes

Hello! I’ll give Addon a try and post back as soon as I have a question or something to show. Thanks!

Hello,

I am a javascript newbie and I cannot figure out how to start translating my python seashell code into three.js

I looked at these amazing examples, but they all seem to be manipulations/squeezing of sphere geometry:
https://hofk.de/main/threejs/sandboxthreep/examplesTHREEp%20r90.html

My algorithm, written in python, generates shells from points derived from shapes extruded along a spline. For my purposes, it is important that the variables in this algorithm can be changed. Can three.js can do this sort of thing at all? It seems like the most complicated example models I’ve seen are imported from 3D programs.

Here is my python code:

class Shell:

``````def __init__(self, n, m, turns, s, i, D, alpha_, beta, phi, mu, omega, A, a, b, L, P, W1, W2, N ):
self.n = n            # Resolution of spiral
self.m = m            # Resolution of spline
self.turns = turns    # Number of turns of spiral
self.s = s            # Angle from b to a axis in spiral
# changing s to -1 makes spline larger, but -50 or 50 changes nothing. sin effect I think.
self.i = i            # Clipping? of spiral?
# values of less than one show no change, values of 10+ clip spiral into shorter coils. At 50, the spiral disappears. The spline does not change.
# Changing j values shows a similar effect.

self.D = D            # Direction of coiling, 1 dextral, -1 sistral
self.alpha_ = alpha_  # Equiangular angle of spiral
self.beta = beta      # Enlarging angle of spiral, breadth
self.phi = phi        # Spline rotation about spiral point
self.mu = mu          # Spline rotation about spiral point
self.omega = omega    # Spline rotation about spiral point
self.A = A            # Size of spiral aperture
self.a = a            # Minor spline length
self.b = b            # Major spline length
self.L = L            # Height of nodule
self.P = P            # Angle of nodule in regards to spline
self.W1 = W1          # Length of nodule in regards to spline
self.W2 = W2          # Length of nodule along spiral
self.N = N            # Number of nodules along a complete revolution of theta.

def generateShell(self):
"""Generate the curve """
shell_matrix =[]
spiral_matrix =[]
prevSpline =[]
while self.i < self.n:
theta = float(map(self.i, 0, self.n, 0, self.turns))
rad =   float(exp(theta * cos(self.alpha_) / sin(self.alpha_)) )

x = float (self.A  * rad * sin(self.beta) * cos(theta) * self.D)
y = float (self.A  * rad * sin(self.beta) * sin(theta))
z = float (-self.A * rad * cos(self.beta))

spiral_i = PVector(x,y,z)
spiral_matrix.append(spiral_i)

#Initialization values for generateSpline.
self.j = 0
spline_matrix =[]

def generateSpline(x,y,z):
"""Generate spline around each spiral point. Values from generateSpiral are passed to this nested function."""
while self.j < self.m:
s = float(map(self.j, 0, self.m, 0, TWO_PI))
r2 = float(pow( pow(cos(s)/self.a,2) + pow(sin(s)/self.b,2), -0.5 ))

#Add shell surface nodules and manipulations.
if (self.W1==0 or self.W2==0 or self.N==0):
else:
lt = float((TWO_PI / self.N) * ( self.N*theta / TWO_PI - int(self.N*theta / TWO_PI) ))
surfrad = self.L * exp( -( pow(2*(s-self.P)/self.W1, 2) + pow(2*lt/self.W2, 2) ) )

#Generate spline point.
x = cos(s + self.phi) * cos(theta + self.omega) * r2 * rad * self.D  # This line closes the opening of the curve at the origin
y = cos(s + self.phi) * sin(theta + self.omega) * r2 * rad
z = sin(s + self.phi)                           * r2 * rad

#Adjust orientation of the point so spline does not flatten against the spiral curve.
x -= sin(self.mu) * sin(s + self.phi) * sin(theta + self.omega) * r2
y += sin(self.mu) * sin(s + self.phi) * cos(theta + self.omega) * r2
z *= cos(self.mu)

spline_point = PVector(x,y,z)

self.j = self.j+ 1
return spline_matrix

#Call generateSpline from within generateSpiral
spline = generateSpline(*spiral_i)

#Append returned spline_matrix to shell_matrix
shell_matrix.append(spline) # shell_matrix should be of form: ([[xyz],[xyz],[xyz]],[[x,y,z],[x,y,z],[x,y,z]]) etc.
self.i = self.i + 1

return shell_matrix``````

You’re right, the addon THREEp is based on spherical coordinates.
The addon THREEf on cylindrical coordinates.

Any geometry can be created. The addons THREEg and THREEi use very different variants.
Just look at this examples.

An example where I test a simple form.

As a newbie, it is helpful to have a look at the example collection.

There you’ll also find my very simple basic example of how to create an indexed buffer geometry.
https://hofk.de/main/discourse.threejs/2017/Indexed%20BufferGeometry/Indexed%20BufferGeometry.html
Starting with that, you can make it as complicated as you want!

Hi!
Not the exact port of your python code, just a simple concept of what and how you can do in Three.js:

P.S. This is not the ultimate solution, but that was the pure fun to get know about how to build a logarithmic spiral

3 Likes

Oh, this is cool! Thank you for pointing me in the right direction. I did not know about Codepen.io before this. I was looking for a way to debug javascript as I am new to working with it.

You’re welcome