It looks like you're new here. If you want to get involved, click one of these buttons!

- All Categories 24.9K
- Announcements & Guidelines 11
- Common Questions 30
- Using Processing 21.5K
- Programming Questions 11.9K
- Questions about Code 6.2K
- How To... 4.1K
- Hello Processing 72
- GLSL / Shaders 278
- Library Questions 3.9K
- Hardware, Integration & Other Languages 2.6K
- Kinect 644
- Arduino 1K
- Raspberry PI 177
- Questions about Modes 1.9K
- Android Mode 1.2K
- JavaScript Mode 407
- Python Mode 185
- Questions about Tools 99
- Espanol 2
- Developing Processing 507
- Create & Announce Libraries 210
- Create & Announce Modes 17
- Create & Announce Tools 28
- Summer of Code 2018 57
- Rails Girls Summer of Code 2017 3
- Summer of Code 2017 49
- Summer of Code 2016 4
- Summer of Code 2015 40
- Summer of Code 2014 22
- p5.js 1.5K
- p5.js Programming Questions 899
- p5.js Library Questions 297
- p5.js Development Questions 30
- General 1.4K
- Events & Opportunities 278
- General Discussion 365

Hi,

I'm trying to add Perlin noise to an icoSphere (icosahedron / geodesic sphere) but for some reason the terrain (noise) generated is too "homogeneous": "peaks" are allocated almost evenly and heights (vertices heights) don't vary much.

Ideally I'd like to be able to adjust the noise so as to get real random values (heterogeneous distribution and heights) like in the following pictures.

The vertices positions are stored in array list (here named "knots") and all I do is adding a variable (named "r") to the x, y, z position of each vertex:

```
for e in knots:
r = noise(random(1))
for i, f in enumerate(e):
particles[e[i]] = Particle(particles[e[i]].x() + particles[e[i]].x() * r , particles[e[i]].y() + particles[e[i]].y() * r, particles[e[i]].z() + particles[e[i]].z() * r)
```

I guess this is not an appropriate way to apply Perlin noise and would love some help to tweak the snippet above.
Any tip, idea, code (**both Java or Python**) is welcomed !

EDIT: This question is a "programming question". Even though the code is in Python, the question is about Perlin noise programmation. Answers or suggestions in Java are totally fine !

full code:

```
add_library('peasycam')
from particle import Particle
def setup():
global ICOSUBDIVISION, vdata, tindices, particles
size(800, 600, OPENGL)
smooth(10)
cam = PeasyCam(this, 450)
particles = []
ICOSUBDIVISION = 0
X, Z = 0.525731112119133606, 0.850650808352039932
vdata = [[-X, 0, Z], [X, 0, Z], [-X, 0, -Z],
[X, 0, -Z], [0, Z, X], [0, Z, -X],
[0, -Z, X], [0, -Z, -X], [Z, X, 0],
[-Z, X, 0], [Z, -X, 0], [-Z, -X, 0]]
tindices = [[0, 4, 1], [0, 9, 4], [9, 5, 4], [4, 5, 8],
[4, 8, 1], [8, 10, 1], [8, 3, 10], [5, 3, 8],
[5, 2, 3], [2, 7, 3], [7, 10, 3], [7, 6, 10],
[7, 11, 6], [11, 0, 6], [ 0, 1, 6], [ 6, 1, 10],
[ 9, 0, 11], [ 9, 11, 2], [ 9, 2, 5], [ 7, 2, 11 ]]
Icosahedron()
def draw():
background(360)
lights()
f1, f2, f3 = PVector(), PVector(), PVector()
for e in range(0, len(particles), 3):
f1.x, f1.y, f1.z = particles[e].x(), particles[e].y(), particles[e].z()
f2.x, f2.y, f2.z = particles[e+1].x(), particles[e+1].y(), particles[e+1].z()
f3.x, f3.y, f3.z = particles[e+2].x(), particles[e+2].y(), particles[e+2].z()
noStroke()
colorMode(HSB, 360, 105, 100)
fill(abs(f1.x), abs(f1.y), abs(f1.z))
beginShape()
vertex( f1.x, f1.y, f1.z )
vertex( f2.x, f2.y, f2.z )
vertex( f3.x, f3.y, f3.z )
endShape( CLOSE )
def keyPressed():
global ICOSUBDIVISION, particles
if keyCode == UP:
if ICOSUBDIVISION == 5:
return
ICOSUBDIVISION += 1
particles = []
Icosahedron()
elif keyCode == DOWN:
if ICOSUBDIVISION == 0:
return
ICOSUBDIVISION -= 1
particles = []
Icosahedron()
def Icosahedron():
global vertexList
vertexList = []
[subdivide(vdata[tindices[e][0]], vdata[tindices[e][1]], vdata[tindices[e][2]], ICOSUBDIVISION) for e in range(20)]
for e in range(0, len(vertexList), 3):
x, y, z = 0, 1, 2
p = Particle(vertexList[e+x]* 200, vertexList[e+y]* 200, vertexList[e+z]* 200)
particles.append(p)
VertPos = set(particles)
knots = [[] for e in VertPos]
for i, v in enumerate(VertPos):
for j, p in enumerate(particles):
if p == v:
knots[i].append(j)
for e in knots:
r = noise(random(1))
for i, f in enumerate(e):
particles[e[i]] = Particle(particles[e[i]].x() + particles[e[i]].x() * r , particles[e[i]].y() + particles[e[i]].y() * r, particles[e[i]].z() + particles[e[i]].z() * r)
def norme(v):
ln = 0
for e in range(3):
ln += (v[e] * v[e])
ln = sqrt(ln)
for e in range(3):
v[e] /= ln
def addi(v):
for e in range(3):
vertexList.append(v[e])
def subdivide(v1, v2, v3, depth):
if depth == 0:
addi(v1)
addi(v2)
addi(v3)
return
v12, v23, v31 = [0,0,0], [0,0,0], [0,0,0]
for e in range(3):
v12[e] = (v1[e] + v2[e]) / 2
v23[e] = (v2[e] + v3[e]) / 2
v31[e] = (v3[e] + v1[e]) / 2
norme(v12)
norme(v23)
norme(v31)
subdivide(v1, v12, v31, depth - 1)
subdivide(v2, v23, v12, depth - 1)
subdivide(v3, v31, v23, depth - 1)
subdivide(v12, v23, v31, depth - 1)
```

Tagged:

## Answers

just came up with this:

The final result is somewhat better but still no perfect.

@GoToLoop: Do you actually think it's a correct way to apply Perlin noise ?

Sorry. Dunno much about perlin or

noise().Most I've got close were these 2 online sketches I've refactored a long time ago:

@solub what is p in the above line? If you draw p without the noise, would you get a perfect sphere?

Related to your first post:

Where are you applying perlin noise? From what I know in 1D, perlin noise variation depends on the sample difference between calls to perlin noise. If you want to see more variation, you just need to sample at larger intervals aka.

perlin_noise_function_generator(t)where t is your sampling interval. However, perlinNoise and noise is not the same function.Kf

@kfrajer: Each p is a vertex, p.x, p.y, p.z are the vertices positions. So if I draw p without the noise I would indeed get a perfect sphere.

In the snippet I normalize each vertex, compute noise and multiply them by the noise value:

And this gives me someting like this:

(I can indeed map the noise between lower than 40 (say 30 or 20) and 100 to get more variations. )I guess it's ok but am still not sure if it's an appropriate way to apply Perlin noise.

Take this picture for instance (found on google images after searching "icosphere" + "perlin noise") How Perlin noise can give you such variation in heights ? There must be somehtin I'm missing.

@solub --

If the example you found on the internet is indeed using perlin noise then the two issues are:

I would demonstrate on your provided sketch, but it fails on

(also, for some reason the forum inserted emoticon HTML into your line 15).

At first glance it looks like you are approaching things in the right way but your base radius is much larger than the reference example, and your output amplitude is way smaller, and you need the highest facet resolution shown in your demo (high resolution is required for sharp peaks). The regularity / irregularity on the surface is extremely sensitive to the scale of input.

To read more about the scale of input coordinates, see past discussions of "perlin" on this forum:

@jeremydouglass My apologies, I forgot to copy/paste the "particle" Class. After a google search I found that the shape in the example was actually created by accident.

(original article here).

I tried to reproduce the same kind of shape following the explanation:

But it didn't work. Dividing "each radius by a noise value" make the sphere shrink so much that it almost disapear.

Anyway, thanks for the links.

Full (working) code:

I‘d use noStroke(); and lights();

EDIT: It actually works if you divide the radii by a very small amount of the noise.

@Chrisir: If I use noStroke() and lights() nothing would be drawn on the screen since I only display strokes.

You only need to do that because you've mapped the noise to a large range in the line above. Because of line 4 you have a range of 10 to 120 which you divide by, giving 1/10 to 1/120, both tiny.

If you didn't do the map you'd have a range of 1/1 (original size) to 1/0 (huge!)

@koogs: indeed !

maybe you can connect the vertices to triangles...?